From 6c2c883fc1f331e7594f01550b6ae72e0902633b Mon Sep 17 00:00:00 2001 From: wubin01 Date: Thu, 25 Oct 2018 16:54:15 +0800 Subject: [PATCH 01/41] add tron proxy --- src/main/java/org/tron/common/overlay/server/Channel.java | 2 +- src/main/java/org/tron/core/net/BlockSyncService.java | 5 +++++ src/main/java/org/tron/core/net/{peer => }/TronHandler.java | 4 +++- src/main/java/org/tron/core/net/TronProxy.java | 5 +++++ 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/tron/core/net/BlockSyncService.java rename src/main/java/org/tron/core/net/{peer => }/TronHandler.java (89%) create mode 100644 src/main/java/org/tron/core/net/TronProxy.java diff --git a/src/main/java/org/tron/common/overlay/server/Channel.java b/src/main/java/org/tron/common/overlay/server/Channel.java index 7c483bb2fcd..b02c51731ca 100644 --- a/src/main/java/org/tron/common/overlay/server/Channel.java +++ b/src/main/java/org/tron/common/overlay/server/Channel.java @@ -41,7 +41,7 @@ import org.tron.core.db.ByteArrayWrapper; import org.tron.core.exception.P2pException; import org.tron.core.net.peer.PeerConnectionDelegate; -import org.tron.core.net.peer.TronHandler; +import org.tron.core.net.TronHandler; import org.tron.protos.Protocol.ReasonCode; @Component diff --git a/src/main/java/org/tron/core/net/BlockSyncService.java b/src/main/java/org/tron/core/net/BlockSyncService.java new file mode 100644 index 00000000000..d7649c3e574 --- /dev/null +++ b/src/main/java/org/tron/core/net/BlockSyncService.java @@ -0,0 +1,5 @@ +package org.tron.core.net; + +public class BlockSyncService { + +} diff --git a/src/main/java/org/tron/core/net/peer/TronHandler.java b/src/main/java/org/tron/core/net/TronHandler.java similarity index 89% rename from src/main/java/org/tron/core/net/peer/TronHandler.java rename to src/main/java/org/tron/core/net/TronHandler.java index 555fd8c8cb2..4320522ab7d 100644 --- a/src/main/java/org/tron/core/net/peer/TronHandler.java +++ b/src/main/java/org/tron/core/net/TronHandler.java @@ -1,4 +1,4 @@ -package org.tron.core.net.peer; +package org.tron.core.net; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; @@ -7,6 +7,8 @@ import org.tron.common.overlay.server.Channel; import org.tron.common.overlay.server.MessageQueue; import org.tron.core.net.message.TronMessage; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerConnectionDelegate; @Component @Scope("prototype") diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronProxy.java new file mode 100644 index 00000000000..e7c40e36acc --- /dev/null +++ b/src/main/java/org/tron/core/net/TronProxy.java @@ -0,0 +1,5 @@ +package org.tron.core.net; + +public class TronProxy { + +} From 510db9b52778c022c30e14fcaf4f302040a35d41 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Fri, 26 Oct 2018 15:50:32 +0800 Subject: [PATCH 02/41] add message handler --- .../org/tron/core/exception/P2pException.java | 2 + .../java/org/tron/core/net/TronProxy.java | 96 ++++++++++++ .../SyncBlockChainMsgHadler.java | 143 ++++++++++++++++++ .../net/messagehandler/TronMsgHandler.java | 10 ++ 4 files changed, 251 insertions(+) create mode 100644 src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java create mode 100644 src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java diff --git a/src/main/java/org/tron/core/exception/P2pException.java b/src/main/java/org/tron/core/exception/P2pException.java index bd014d5d617..7a4153c7dd6 100644 --- a/src/main/java/org/tron/core/exception/P2pException.java +++ b/src/main/java/org/tron/core/exception/P2pException.java @@ -17,6 +17,8 @@ public enum TypeEnum { NO_SUCH_MESSAGE (1, "No such message"), PARSE_MESSAGE_FAILED (2, "Parse message failed"), MESSAGE_WITH_WRONG_LENGTH (3, "Message with wrong length"), + BAD_MESSAGE (4, "Bad message"), + HARD_FORK (5, "Hard fork"), DEFAULT (100, "default exception"); private Integer value; diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronProxy.java index e7c40e36acc..3ab150d82b4 100644 --- a/src/main/java/org/tron/core/net/TronProxy.java +++ b/src/main/java/org/tron/core/net/TronProxy.java @@ -1,5 +1,101 @@ package org.tron.core.net; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.common.overlay.message.Message; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.db.Manager; +import org.tron.core.exception.BadItemException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.exception.StoreException; +import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.message.MessageTypes; +import org.tron.core.net.message.TransactionMessage; + +@Slf4j +@Component public class TronProxy { + @Autowired + private Manager dbManager; + + public Message getData(Sha256Hash hash, MessageTypes type) throws StoreException { + switch (type) { + case BLOCK: + return new BlockMessage(dbManager.getBlockById(hash)); + case TRX: + TransactionCapsule tx = dbManager.getTransactionStore().get(hash.getBytes()); + if (tx != null) { + return new TransactionMessage(tx.getData()); + } + throw new ItemNotFoundException("transaction is not found"); + default: + throw new BadItemException("message type not block or trx."); + } + } + + public void syncToCli(long unSyncNum) { + logger.info("There are " + unSyncNum + " blocks we need to sync."); + dbManager.setSyncMode(unSyncNum == 0); + } + + public long getBlockTime(BlockId id) { + try { + return dbManager.getBlockById(id).getTimeStamp(); + } catch (BadItemException e) { + return dbManager.getGenesisBlock().getTimeStamp(); + } catch (ItemNotFoundException e) { + return dbManager.getGenesisBlock().getTimeStamp(); + } + } + + public BlockId getHeadBlockId() { + return dbManager.getHeadBlockId(); + } + + public BlockId getSolidBlockId() { + return dbManager.getSolidBlockId(); + } + + public BlockId getGenesisBlockId() { + return dbManager.getGenesisBlockId(); + } + + public BlockId getBlockIdByNum(long num) throws Exception {return dbManager.getBlockIdByNum(num);} + + + + public long getHeadBlockTimeStamp() { + return dbManager.getHeadBlockTimeStamp(); + } + + public boolean containBlock(BlockId id) { + return dbManager.containBlock(id); + } + + public boolean containBlockInMainChain(BlockId id) { + return dbManager.containBlockInMainChain(id); + } + + public boolean contain(Sha256Hash hash, MessageTypes type) { + if (type.equals(MessageTypes.BLOCK)) { + return dbManager.containBlock(hash); + } else if (type.equals(MessageTypes.TRX)) { + return dbManager.getTransactionStore().has(hash.getBytes()); + } + return false; + } + + public BlockCapsule getGenesisBlock() { + return dbManager.getGenesisBlock(); + } + + public boolean canChainRevoke(long num) { + return num >= dbManager.getSyncBeginNumber(); + } + } diff --git a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java new file mode 100644 index 00000000000..d02814afbc9 --- /dev/null +++ b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java @@ -0,0 +1,143 @@ +package org.tron.core.net.messagehandler; + +import com.google.common.collect.Iterables; +import com.google.common.primitives.Longs; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.common.overlay.discover.node.statistics.MessageCount; +import org.tron.common.overlay.server.Channel.TronState; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.config.Parameter.ChainConstant; +import org.tron.core.config.Parameter.NodeConstant; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; +import org.tron.core.exception.StoreException; +import org.tron.core.net.TronProxy; +import org.tron.core.net.message.ChainInventoryMessage; +import org.tron.core.net.message.FetchInvDataMessage; +import org.tron.core.net.message.MessageTypes; +import org.tron.core.net.message.SyncBlockChainMessage; +import org.tron.core.net.message.TronMessage; +import org.tron.core.net.peer.PeerConnection; +import org.tron.protos.Protocol.ReasonCode; + +@Slf4j +@Component +public class SyncBlockChainMsgHadler implements TronMsgHandler { + + @Autowired + TronProxy TronProxy; + + private LinkedList getLostBlockIds(List blockIds) throws Exception{ + + if (TronProxy.getHeadBlockId().getNum() == 0) { + return new LinkedList<>(); + } + + BlockId unForkedBlockId; + + if (blockIds.isEmpty() || (blockIds.size() == 1 && blockIds.get(0).equals(TronProxy.getGenesisBlockId()))) { + unForkedBlockId = TronProxy.getGenesisBlockId(); + } else if (blockIds.size() == 1 && blockIds.get(0).getNum() == 0) { + return new LinkedList(Arrays.asList(TronProxy.getGenesisBlockId())); + } else { + Collections.reverse(blockIds); + unForkedBlockId = blockIds.stream() + .filter(blockId -> TronProxy.containBlockInMainChain(blockId)) + .findFirst().orElse(null); + if (unForkedBlockId == null) { + return new LinkedList<>(); + } + } + + long unForkedBlockIdNum = unForkedBlockId.getNum(); + long len = Longs.min(TronProxy.getHeadBlockId().getNum(), unForkedBlockIdNum + NodeConstant.SYNC_FETCH_BATCH_NUM); + + LinkedList ids = new LinkedList<>(); + for (long i = unForkedBlockIdNum; i <= len; i++) { + BlockId id = TronProxy.getBlockIdByNum(i); + ids.add(id); + } + return ids; + } + + private void checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage msg) throws Exception{ + List blockIds = msg.getBlockIds(); + if (CollectionUtils.isEmpty(blockIds)){ + throw new P2pException(TypeEnum.BAD_MESSAGE, ); + } + long lastBlockNum = blockIds.get(blockIds.size() - 1).getNum(); + BlockId lastSyncBlockId = peer.getLastSyncBlockId(); + if (lastSyncBlockId != null && lastBlockNum < lastSyncBlockId.getNum()) { + logger.warn("Peer {} receive bad SyncBlockChain message, firstNum {} lastSyncNum {}.", + peer.getInetAddress(), lastBlockNum, lastSyncBlockId.getNum()); + throw new P2pException(TypeEnum.BAD_MESSAGE); + } + return true; + } + + public boolean processMessage(PeerConnection peer, TronMessage msg){ + + SyncBlockChainMessage syncBlockChainMessage = (SyncBlockChainMessage) msg; + + peer.setTronState(TronState.SYNCING); + BlockId headBlockId = TronProxy.getHeadBlockId(); + long remainNum = 0; + LinkedList blockIds = new LinkedList<>(); + List summaryChainIds = syncMsg.getBlockIds(); + if (!checkSyncBlockChainMessage(peer, syncMsg)) { + disconnectPeer(peer, ReasonCode.BAD_PROTOCOL); + return; + } + try { + blockIds = del.getLostBlockIds(summaryChainIds); + } catch (StoreException e) { + logger.error(e.getMessage()); + } + + if (blockIds.isEmpty()) { + if (CollectionUtils.isNotEmpty(summaryChainIds) && !del + .canChainRevoke(summaryChainIds.get(0).getNum())) { + logger.info("Node sync block fail, disconnect peer {}, no block {}", peer, + summaryChainIds.get(0).getString()); + peer.disconnect(ReasonCode.SYNC_FAIL); + return; + } else { + peer.setNeedSyncFromUs(false); + } + } else if (blockIds.size() == 1 + && !summaryChainIds.isEmpty() + && (summaryChainIds.contains(blockIds.peekFirst()) + || blockIds.peek().getNum() == 0)) { + peer.setNeedSyncFromUs(false); + } else { + peer.setNeedSyncFromUs(true); + remainNum = del.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); + } + + if (!peer.isNeedSyncFromPeer() + && CollectionUtils.isNotEmpty(summaryChainIds) + && !del.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) + && del.canChainRevoke(summaryChainIds.get(0).getNum())) { + startSyncWithPeer(peer); + } + + if (blockIds.peekLast() == null) { + peer.setLastSyncBlockId(headBlockId); + } else { + peer.setLastSyncBlockId(blockIds.peekLast()); + } + peer.setRemainNum(remainNum); + peer.sendMessage(new ChainInventoryMessage(blockIds, remainNum)); + } + + + +} diff --git a/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java new file mode 100644 index 00000000000..5f41cfc50a4 --- /dev/null +++ b/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java @@ -0,0 +1,10 @@ +package org.tron.core.net.messagehandler; + +import org.tron.core.net.message.TronMessage; +import org.tron.core.net.peer.PeerConnection; + +public interface TronMsgHandler { + + boolean processMessage(PeerConnection peer, TronMessage msg); + +} From e3f900f3bcd56778520d8984244b089bca3aa329 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 29 Oct 2018 12:39:16 +0800 Subject: [PATCH 03/41] add SyncBlockChainMsgHadler log --- .../core/net/messagehandler/SyncBlockChainMsgHadler.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java index d02814afbc9..2db82ba33d8 100644 --- a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java +++ b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java @@ -65,22 +65,19 @@ private LinkedList getLostBlockIds(List blockIds) throws Excep BlockId id = TronProxy.getBlockIdByNum(i); ids.add(id); } - return ids; + return ids;Integer.MAX_VALUE } private void checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage msg) throws Exception{ List blockIds = msg.getBlockIds(); if (CollectionUtils.isEmpty(blockIds)){ - throw new P2pException(TypeEnum.BAD_MESSAGE, ); + throw new P2pException(TypeEnum.BAD_MESSAGE, "SyncBlockChain blockIds is empty"); } long lastBlockNum = blockIds.get(blockIds.size() - 1).getNum(); BlockId lastSyncBlockId = peer.getLastSyncBlockId(); if (lastSyncBlockId != null && lastBlockNum < lastSyncBlockId.getNum()) { - logger.warn("Peer {} receive bad SyncBlockChain message, firstNum {} lastSyncNum {}.", - peer.getInetAddress(), lastBlockNum, lastSyncBlockId.getNum()); - throw new P2pException(TypeEnum.BAD_MESSAGE); + throw new P2pException(TypeEnum.BAD_MESSAGE, "SyncBlockChain firstNum:" + lastBlockNum + ", lastSyncNum:" + lastBlockNum); } - return true; } public boolean processMessage(PeerConnection peer, TronMessage msg){ From fa2f142cd500004ea4bdbdddd62b51b5813ecb15 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 30 Oct 2018 18:57:21 +0800 Subject: [PATCH 04/41] add TransactionsMsgHandler --- .../org/tron/core/exception/P2pException.java | 3 +- .../java/org/tron/core/net/TronProxy.java | 2 +- .../SyncBlockChainMsgHadler.java | 107 +++++++----------- .../TransactionsMsgHandler.java} | 6 +- .../net/messagehandler/TronMsgHandler.java | 2 +- .../java/org/tron/core/net/node/NodeImpl.java | 9 +- 6 files changed, 52 insertions(+), 77 deletions(-) rename src/main/java/org/tron/core/net/{node/TrxHandler.java => messagehandler/TransactionsMsgHandler.java} (96%) diff --git a/src/main/java/org/tron/core/exception/P2pException.java b/src/main/java/org/tron/core/exception/P2pException.java index 7a4153c7dd6..975820d5e95 100644 --- a/src/main/java/org/tron/core/exception/P2pException.java +++ b/src/main/java/org/tron/core/exception/P2pException.java @@ -18,7 +18,8 @@ public enum TypeEnum { PARSE_MESSAGE_FAILED (2, "Parse message failed"), MESSAGE_WITH_WRONG_LENGTH (3, "Message with wrong length"), BAD_MESSAGE (4, "Bad message"), - HARD_FORK (5, "Hard fork"), + DIFF_GENESIS_BLOCK (5, "Different genesis block"), + HARD_FORKED (6, "Hard forked"), DEFAULT (100, "default exception"); private Integer value; diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronProxy.java index 3ab150d82b4..e459252e265 100644 --- a/src/main/java/org/tron/core/net/TronProxy.java +++ b/src/main/java/org/tron/core/net/TronProxy.java @@ -39,7 +39,7 @@ public Message getData(Sha256Hash hash, MessageTypes type) throws StoreException } public void syncToCli(long unSyncNum) { - logger.info("There are " + unSyncNum + " blocks we need to sync."); + logger.info("There are {} blocks we need to sync.", unSyncNum); dbManager.setSyncMode(unSyncNum == 0); } diff --git a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java index 2db82ba33d8..d16f6a484f5 100644 --- a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java +++ b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java @@ -8,6 +8,7 @@ import java.util.List; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.spongycastle.util.encoders.Hex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.overlay.discover.node.statistics.MessageCount; @@ -33,39 +34,26 @@ public class SyncBlockChainMsgHadler implements TronMsgHandler { @Autowired - TronProxy TronProxy; + TronProxy tronProxy; private LinkedList getLostBlockIds(List blockIds) throws Exception{ - if (TronProxy.getHeadBlockId().getNum() == 0) { - return new LinkedList<>(); - } - - BlockId unForkedBlockId; - - if (blockIds.isEmpty() || (blockIds.size() == 1 && blockIds.get(0).equals(TronProxy.getGenesisBlockId()))) { - unForkedBlockId = TronProxy.getGenesisBlockId(); - } else if (blockIds.size() == 1 && blockIds.get(0).getNum() == 0) { - return new LinkedList(Arrays.asList(TronProxy.getGenesisBlockId())); - } else { - Collections.reverse(blockIds); - unForkedBlockId = blockIds.stream() - .filter(blockId -> TronProxy.containBlockInMainChain(blockId)) - .findFirst().orElse(null); - if (unForkedBlockId == null) { - return new LinkedList<>(); + BlockId unForkId = null; + for (int i = blockIds.size() - 1; i >= 0; i--){ + if (tronProxy.containBlockInMainChain(blockIds.get(i))){ + unForkId = blockIds.get(i); + break; } } - long unForkedBlockIdNum = unForkedBlockId.getNum(); - long len = Longs.min(TronProxy.getHeadBlockId().getNum(), unForkedBlockIdNum + NodeConstant.SYNC_FETCH_BATCH_NUM); + long len = Math.min(tronProxy.getHeadBlockId().getNum(), unForkId.getNum() + NodeConstant.SYNC_FETCH_BATCH_NUM); LinkedList ids = new LinkedList<>(); - for (long i = unForkedBlockIdNum; i <= len; i++) { - BlockId id = TronProxy.getBlockIdByNum(i); + for (long i = unForkId.getNum(); i <= len; i++) { + BlockId id = tronProxy.getBlockIdByNum(i); ids.add(id); } - return ids;Integer.MAX_VALUE + return ids; } private void checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage msg) throws Exception{ @@ -73,68 +61,51 @@ private void checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessa if (CollectionUtils.isEmpty(blockIds)){ throw new P2pException(TypeEnum.BAD_MESSAGE, "SyncBlockChain blockIds is empty"); } - long lastBlockNum = blockIds.get(blockIds.size() - 1).getNum(); + + BlockId firstId = blockIds.get(0); + if (!tronProxy.containBlockInMainChain(firstId)){ + throw new P2pException(TypeEnum.BAD_MESSAGE, "No first block:" + firstId.getString()); + } + + long headNum = tronProxy.getHeadBlockId().getNum(); + if (firstId.getNum() > headNum){ + throw new P2pException(TypeEnum.BAD_MESSAGE, "First blockNum:" + firstId.getNum() +" gt my head BlockNum:" + headNum); + } + BlockId lastSyncBlockId = peer.getLastSyncBlockId(); - if (lastSyncBlockId != null && lastBlockNum < lastSyncBlockId.getNum()) { - throw new P2pException(TypeEnum.BAD_MESSAGE, "SyncBlockChain firstNum:" + lastBlockNum + ", lastSyncNum:" + lastBlockNum); + long lastNum = blockIds.get(blockIds.size() - 1).getNum(); + if (lastSyncBlockId != null && lastSyncBlockId.getNum() > lastNum) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "lastSyncNum:" + lastSyncBlockId.getNum() + " gt lastNum:" + lastNum); } } - public boolean processMessage(PeerConnection peer, TronMessage msg){ + public void processMessage(PeerConnection peer, TronMessage msg) throws Exception { SyncBlockChainMessage syncBlockChainMessage = (SyncBlockChainMessage) msg; - peer.setTronState(TronState.SYNCING); - BlockId headBlockId = TronProxy.getHeadBlockId(); + checkSyncBlockChainMessage(peer, syncBlockChainMessage); + long remainNum = 0; - LinkedList blockIds = new LinkedList<>(); - List summaryChainIds = syncMsg.getBlockIds(); - if (!checkSyncBlockChainMessage(peer, syncMsg)) { - disconnectPeer(peer, ReasonCode.BAD_PROTOCOL); - return; - } - try { - blockIds = del.getLostBlockIds(summaryChainIds); - } catch (StoreException e) { - logger.error(e.getMessage()); - } - if (blockIds.isEmpty()) { - if (CollectionUtils.isNotEmpty(summaryChainIds) && !del - .canChainRevoke(summaryChainIds.get(0).getNum())) { - logger.info("Node sync block fail, disconnect peer {}, no block {}", peer, - summaryChainIds.get(0).getString()); - peer.disconnect(ReasonCode.SYNC_FAIL); - return; - } else { - peer.setNeedSyncFromUs(false); - } - } else if (blockIds.size() == 1 - && !summaryChainIds.isEmpty() - && (summaryChainIds.contains(blockIds.peekFirst()) - || blockIds.peek().getNum() == 0)) { + List summaryChainIds = syncBlockChainMessage.getBlockIds(); + + LinkedList blockIds = getLostBlockIds(summaryChainIds); + + if (blockIds.size() == 1 && summaryChainIds.contains(blockIds.get(0))){ peer.setNeedSyncFromUs(false); - } else { + }else { peer.setNeedSyncFromUs(true); - remainNum = del.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); + remainNum = tronProxy.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); } if (!peer.isNeedSyncFromPeer() - && CollectionUtils.isNotEmpty(summaryChainIds) - && !del.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) - && del.canChainRevoke(summaryChainIds.get(0).getNum())) { - startSyncWithPeer(peer); + && !tronProxy.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) + && tronProxy.canChainRevoke(summaryChainIds.get(0).getNum())) { + //startSyncWithPeer(peer); } - if (blockIds.peekLast() == null) { - peer.setLastSyncBlockId(headBlockId); - } else { - peer.setLastSyncBlockId(blockIds.peekLast()); - } + peer.setLastSyncBlockId(blockIds.peekLast()); peer.setRemainNum(remainNum); peer.sendMessage(new ChainInventoryMessage(blockIds, remainNum)); } - - - } diff --git a/src/main/java/org/tron/core/net/node/TrxHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java similarity index 96% rename from src/main/java/org/tron/core/net/node/TrxHandler.java rename to src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index a1140cd4c43..16b3a6f1228 100644 --- a/src/main/java/org/tron/core/net/node/TrxHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -1,4 +1,4 @@ -package org.tron.core.net.node; +package org.tron.core.net.messagehandler; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; @@ -14,6 +14,8 @@ import org.tron.core.exception.TraitorPeerException; import org.tron.core.net.message.TransactionMessage; import org.tron.core.net.message.TransactionsMessage; +import org.tron.core.net.node.Item; +import org.tron.core.net.node.NodeImpl; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Inventory.InventoryType; import org.tron.protos.Protocol.ReasonCode; @@ -22,7 +24,7 @@ @Slf4j @Component -public class TrxHandler { +public class TransactionsMsgHandler { private NodeImpl nodeImpl; diff --git a/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java index 5f41cfc50a4..0508ccdd19a 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java @@ -5,6 +5,6 @@ public interface TronMsgHandler { - boolean processMessage(PeerConnection peer, TronMessage msg); + void processMessage(PeerConnection peer, TronMessage msg) throws Exception; } diff --git a/src/main/java/org/tron/core/net/node/NodeImpl.java b/src/main/java/org/tron/core/net/node/NodeImpl.java index e90e766417a..e8e45f4ce7f 100644 --- a/src/main/java/org/tron/core/net/node/NodeImpl.java +++ b/src/main/java/org/tron/core/net/node/NodeImpl.java @@ -67,6 +67,7 @@ import org.tron.core.net.message.TransactionMessage; import org.tron.core.net.message.TransactionsMessage; import org.tron.core.net.message.TronMessage; +import org.tron.core.net.messagehandler.TransactionsMsgHandler; import org.tron.core.net.peer.PeerConnection; import org.tron.core.net.peer.PeerConnectionDelegate; import org.tron.core.services.WitnessProductBlockService; @@ -79,7 +80,7 @@ public class NodeImpl extends PeerConnectionDelegate implements Node { @Autowired - private TrxHandler trxHandler; + private TransactionsMsgHandler transactionsMsgHandler; @Autowired private SyncPool pool; @@ -288,7 +289,7 @@ public void onMessage(PeerConnection peer, TronMessage msg) { onHandleBlockMessage(peer, (BlockMessage) msg); break; case TRXS: - trxHandler.handleTransactionsMessage(peer, (TransactionsMessage) msg); + transactionsMsgHandler.handleTransactionsMessage(peer, (TransactionsMessage) msg); break; case SYNC_BLOCK_CHAIN: onHandleSyncBlockChainMessage(peer, (SyncBlockChainMessage) msg); @@ -344,7 +345,7 @@ public void broadcast(Message msg) { @Override public void listen() { pool.init(this); - trxHandler.init(this); + transactionsMsgHandler.init(this); isAdvertiseActive = true; isFetchActive = true; activeTronPump(); @@ -630,7 +631,7 @@ public synchronized void disconnectInactive() { private void onHandleInventoryMessage(PeerConnection peer, InventoryMessage msg) { - if (trxHandler.isBusy() && msg.getInventoryType().equals(InventoryType.TRX)) { + if (transactionsMsgHandler.isBusy() && msg.getInventoryType().equals(InventoryType.TRX)) { logger.warn("Too many trx msg to handle, drop inventory msg from peer {}, size {}", peer.getInetAddress(), msg.getHashList().size()); return; From 00336582dd212dd7abca5aa519e4d03742e9c3bd Mon Sep 17 00:00:00 2001 From: wubin01 Date: Fri, 2 Nov 2018 11:44:32 +0800 Subject: [PATCH 05/41] add ChainInventory Msg Handler --- .../tron/common/overlay/server/Channel.java | 2 +- .../tron/common/overlay/server/SyncPool.java | 2 +- .../org/tron/core/exception/P2pException.java | 2 + .../org/tron/core/net/BlockSyncService.java | 5 - .../java/org/tron/core/net/TronHandler.java | 6 +- .../java/org/tron/core/net/TronManager.java | 23 ++ .../java/org/tron/core/net/TronProxy.java | 53 ++--- .../net/messagehandler/BlockMsgHandler.java | 187 +++++++++++++++++ .../ChainInventoryMsgHandler.java | 136 ++++++++++++ .../SyncBlockChainMsgHadler.java | 82 ++++---- .../TransactionsMsgHandler.java | 98 +++++---- .../java/org/tron/core/net/node/NodeImpl.java | 7 +- .../PeerConnectionDelegate.java | 3 +- .../tron/core/net/{node => peer}/Item.java | 2 +- .../tron/core/net/peer/PeerConnection.java | 197 ++++-------------- .../java/org/tron/core/net/peer/PeerSync.java | 96 +++++++++ .../org/tron/core/net/node/BroadTest.java | 2 +- .../core/net/node/HandleBlockMessageTest.java | 2 +- .../core/net/node/HandleTransactionTest.java | 1 + .../org/tron/core/net/node/NodeImplTest.java | 1 + 20 files changed, 617 insertions(+), 290 deletions(-) delete mode 100644 src/main/java/org/tron/core/net/BlockSyncService.java create mode 100644 src/main/java/org/tron/core/net/TronManager.java create mode 100644 src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java create mode 100644 src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java rename src/main/java/org/tron/core/net/{peer => node}/PeerConnectionDelegate.java (84%) rename src/main/java/org/tron/core/net/{node => peer}/Item.java (95%) create mode 100644 src/main/java/org/tron/core/net/peer/PeerSync.java diff --git a/src/main/java/org/tron/common/overlay/server/Channel.java b/src/main/java/org/tron/common/overlay/server/Channel.java index b02c51731ca..7ae943595bf 100644 --- a/src/main/java/org/tron/common/overlay/server/Channel.java +++ b/src/main/java/org/tron/common/overlay/server/Channel.java @@ -40,7 +40,7 @@ import org.tron.common.overlay.message.StaticMessages; import org.tron.core.db.ByteArrayWrapper; import org.tron.core.exception.P2pException; -import org.tron.core.net.peer.PeerConnectionDelegate; +import org.tron.core.net.node.PeerConnectionDelegate; import org.tron.core.net.TronHandler; import org.tron.protos.Protocol.ReasonCode; diff --git a/src/main/java/org/tron/common/overlay/server/SyncPool.java b/src/main/java/org/tron/common/overlay/server/SyncPool.java index b6c5b7bc2c4..5671db9d88a 100644 --- a/src/main/java/org/tron/common/overlay/server/SyncPool.java +++ b/src/main/java/org/tron/common/overlay/server/SyncPool.java @@ -44,7 +44,7 @@ import org.tron.common.overlay.discover.node.statistics.NodeStatistics; import org.tron.core.config.args.Args; import org.tron.core.net.peer.PeerConnection; -import org.tron.core.net.peer.PeerConnectionDelegate; +import org.tron.core.net.node.PeerConnectionDelegate; @Component public class SyncPool { diff --git a/src/main/java/org/tron/core/exception/P2pException.java b/src/main/java/org/tron/core/exception/P2pException.java index 975820d5e95..9975512f813 100644 --- a/src/main/java/org/tron/core/exception/P2pException.java +++ b/src/main/java/org/tron/core/exception/P2pException.java @@ -20,6 +20,8 @@ public enum TypeEnum { BAD_MESSAGE (4, "Bad message"), DIFF_GENESIS_BLOCK (5, "Different genesis block"), HARD_FORKED (6, "Hard forked"), + SYNC_FAILED (7, "Sync failed"), + CHECK_FAILED (8, "Check failed"), DEFAULT (100, "default exception"); private Integer value; diff --git a/src/main/java/org/tron/core/net/BlockSyncService.java b/src/main/java/org/tron/core/net/BlockSyncService.java deleted file mode 100644 index d7649c3e574..00000000000 --- a/src/main/java/org/tron/core/net/BlockSyncService.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.tron.core.net; - -public class BlockSyncService { - -} diff --git a/src/main/java/org/tron/core/net/TronHandler.java b/src/main/java/org/tron/core/net/TronHandler.java index 4320522ab7d..09986d5a3f4 100644 --- a/src/main/java/org/tron/core/net/TronHandler.java +++ b/src/main/java/org/tron/core/net/TronHandler.java @@ -8,7 +8,7 @@ import org.tron.common.overlay.server.MessageQueue; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.PeerConnection; -import org.tron.core.net.peer.PeerConnectionDelegate; +import org.tron.core.net.node.PeerConnectionDelegate; @Component @Scope("prototype") @@ -26,6 +26,10 @@ public void setPeerDel(PeerConnectionDelegate peerDel) { @Override public void channelRead0(final ChannelHandlerContext ctx, TronMessage msg) { + if (!peer.isDisconnect()) { + logger.warn("Received a block {} from disconnect peer {}", blockId.getNum(), peer.getNode().getHost()); + return; + } msgQueue.receivedMessage(msg); peerDel.onMessage(peer, msg); } diff --git a/src/main/java/org/tron/core/net/TronManager.java b/src/main/java/org/tron/core/net/TronManager.java new file mode 100644 index 00000000000..a3707afc6fd --- /dev/null +++ b/src/main/java/org/tron/core/net/TronManager.java @@ -0,0 +1,23 @@ +package org.tron.core.net; + +import lombok.Getter; +import lombok.Setter; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; + +public class TronManager { + + @Getter + private Object blockLock; + + @Setter + @Getter + private boolean syncBlockFetchFlag; + + public void check (boolean flag, String msg) throws Exception { + if (!flag){ + throw new P2pException(TypeEnum.CHECK_FAILED, msg); + } + } + +} diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronProxy.java index e459252e265..1bff0cbbd04 100644 --- a/src/main/java/org/tron/core/net/TronProxy.java +++ b/src/main/java/org/tron/core/net/TronProxy.java @@ -1,5 +1,6 @@ package org.tron.core.net; +import java.util.LinkedList; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -23,24 +24,8 @@ public class TronProxy { @Autowired private Manager dbManager; - public Message getData(Sha256Hash hash, MessageTypes type) throws StoreException { - switch (type) { - case BLOCK: - return new BlockMessage(dbManager.getBlockById(hash)); - case TRX: - TransactionCapsule tx = dbManager.getTransactionStore().get(hash.getBytes()); - if (tx != null) { - return new TransactionMessage(tx.getData()); - } - throw new ItemNotFoundException("transaction is not found"); - default: - throw new BadItemException("message type not block or trx."); - } - } - - public void syncToCli(long unSyncNum) { - logger.info("There are {} blocks we need to sync.", unSyncNum); - dbManager.setSyncMode(unSyncNum == 0); + public long getSyncBeginNumber() { + return dbManager.getSyncBeginNumber(); } public long getBlockTime(BlockId id) { @@ -67,8 +52,9 @@ public BlockId getGenesisBlockId() { public BlockId getBlockIdByNum(long num) throws Exception {return dbManager.getBlockIdByNum(num);} - - + public BlockCapsule getGenesisBlock() { + return dbManager.getGenesisBlock(); + } public long getHeadBlockTimeStamp() { return dbManager.getHeadBlockTimeStamp(); } @@ -81,6 +67,14 @@ public boolean containBlockInMainChain(BlockId id) { return dbManager.containBlockInMainChain(id); } + public LinkedList getBlockChainHashesOnFork(BlockId forkBlockHash) throws Exception { + return dbManager.getBlockChainHashesOnFork(forkBlockHash); + } + + public boolean canChainRevoke(long num) { + return num >= dbManager.getSyncBeginNumber(); + } + public boolean contain(Sha256Hash hash, MessageTypes type) { if (type.equals(MessageTypes.BLOCK)) { return dbManager.containBlock(hash); @@ -90,12 +84,19 @@ public boolean contain(Sha256Hash hash, MessageTypes type) { return false; } - public BlockCapsule getGenesisBlock() { - return dbManager.getGenesisBlock(); - } - - public boolean canChainRevoke(long num) { - return num >= dbManager.getSyncBeginNumber(); + public Message getData(Sha256Hash hash, MessageTypes type) throws StoreException { + switch (type) { + case BLOCK: + return new BlockMessage(dbManager.getBlockById(hash)); + case TRX: + TransactionCapsule tx = dbManager.getTransactionStore().get(hash.getBytes()); + if (tx != null) { + return new TransactionMessage(tx.getData()); + } + throw new ItemNotFoundException("transaction is not found"); + default: + throw new BadItemException("message type not block or trx."); + } } } diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java new file mode 100644 index 00000000000..9654ebd34ef --- /dev/null +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -0,0 +1,187 @@ +package org.tron.core.net.messagehandler; + +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.config.Parameter.NodeConstant; +import org.tron.core.exception.BadBlockException; +import org.tron.core.exception.NonCommonBlockException; +import org.tron.core.exception.UnLinkedBlockException; +import org.tron.core.net.TronManager; +import org.tron.core.net.TronProxy; +import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.message.ChainInventoryMessage; +import org.tron.core.net.message.TronMessage; +import org.tron.core.net.peer.Item; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerSync; +import org.tron.core.services.WitnessProductBlockService; +import org.tron.protos.Protocol.Inventory.InventoryType; +import org.tron.protos.Protocol.ReasonCode; + +@Slf4j +@Component +public class BlockMsgHandler implements TronMsgHandler { + + @Autowired + private TronProxy tronProxy; + + @Autowired + private TronManager tronManager; + + @Autowired + private PeerSync peerSync; + + @Autowired + private WitnessProductBlockService witnessProductBlockService; + + private Map blockWaitToProc = new ConcurrentHashMap<>(); + + private Map blockJustReceived = new ConcurrentHashMap<>(); + + private Queue freshBlockId = new ConcurrentLinkedQueue() { + @Override + public boolean offer(BlockId blockId) { + if (size() > 200) { + super.poll(); + } + return super.offer(blockId); + } + }; + + private boolean isHandleSyncBlockActive; + + @Override + public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { + + BlockMessage blockMessage = (BlockMessage) msg; + + BlockId blockId = blockMessage.getBlockId(); + Item item = new Item(blockId, InventoryType.BLOCK); + boolean syncFlag = false; + if (peer.getSyncBlockRequested().containsKey(blockId)) { + peer.getSyncBlockRequested().remove(blockId); + synchronized (blockJustReceived) { + blockJustReceived.put(blockMessage, peer); + } + isHandleSyncBlockActive = true; + syncFlag = true; + if (!peer.isBusy()) { + if (peer.getUnfetchSyncNum() > 0 && peer.getSyncBlockToFetch().size() <= NodeConstant.SYNC_FETCH_BATCH_NUM) { + peerSync.syncNext(peer); + } else { + tronManager.setSyncBlockFetchFlag(true); + } + } + } + if (peer.getAdvObjWeRequested().containsKey(item)) { + peer.getAdvObjWeRequested().remove(item); + if (!syncFlag) { + processAdvBlock(peer, blockMessage.getBlockCapsule()); + } + } + } + + private void check(PeerConnection peer, ChainInventoryMessage msg) throws Exception { + + } + + private void processAdvBlock(PeerConnection peer, BlockCapsule block) { + synchronized (tronManager.getBlockLock()) { + if (!freshBlockId.contains(block.getBlockId())) { + try { + witnessProductBlockService.validWitnessProductTwoBlock(block); + LinkedList trxIds = null; + trxIds = del.handleBlock(block, false); + freshBlockId.offer(block.getBlockId()); + + trxIds.forEach(trxId -> advObjToFetch.remove(trxId)); + + getActivePeer().stream() + .filter(p -> p.getAdvObjSpreadToUs().containsKey(block.getBlockId())) + .forEach(p -> updateBlockWeBothHave(p, block)); + + broadcast(new BlockMessage(block)); + + } catch (BadBlockException e) { + logger.error("We get a bad block {}, from {}, reason is {} ", + block.getBlockId().getString(), peer.getNode().getHost(), e.getMessage()); + disconnectPeer(peer, ReasonCode.BAD_BLOCK); + } catch (UnLinkedBlockException e) { + logger.error("We get a unlinked block {}, from {}, head is {}", block.getBlockId(). + getString(), peer.getNode().getHost(), del.getHeadBlockId().getString()); + startSyncWithPeer(peer); + } catch (NonCommonBlockException e) { + logger.error( + "We get a block {} that do not have the most recent common ancestor with the main chain, from {}, reason is {} ", + block.getBlockId().getString(), peer.getNode().getHost(), e.getMessage()); + disconnectPeer(peer, ReasonCode.FORKED); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + } + + private boolean processSyncBlock(BlockCapsule block) { + boolean isAccept = false; + ReasonCode reason = null; + try { + try { + del.handleBlock(block, true); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + freshBlockId.offer(block.getBlockId()); + logger.info("Success handle block {}", block.getBlockId().getString()); + isAccept = true; + } catch (BadBlockException e) { + logger.error("We get a bad block {}, reason is {} ", block.getBlockId().getString(), + e.getMessage()); + reason = ReasonCode.BAD_BLOCK; + } catch (UnLinkedBlockException e) { + logger.error("We get a unlinked block {}, head is {}", block.getBlockId().getString(), + del.getHeadBlockId().getString()); + reason = ReasonCode.UNLINKABLE; + } catch (NonCommonBlockException e) { + logger.error( + "We get a block {} that do not have the most recent common ancestor with the main chain, head is {}", + block.getBlockId().getString(), + del.getHeadBlockId().getString()); + reason = ReasonCode.FORKED; + } + + if (!isAccept) { + ReasonCode finalReason = reason; + getActivePeer().stream() + .filter(peer -> peer.getBlockInProc().contains(block.getBlockId())) + .forEach(peer -> disconnectPeer(peer, finalReason)); + } + isHandleSyncBlockActive = true; + return isAccept; + } + + private void finishProcessSyncBlock(BlockCapsule block) { + getActivePeer().forEach(peer -> { + if (peer.getSyncBlockToFetch().isEmpty() + && peer.getBlockInProc().isEmpty() + && !peer.isNeedSyncFromPeer() + && !peer.isNeedSyncFromUs()) { + startSyncWithPeer(peer); + } else if (peer.getBlockInProc().remove(block.getBlockId())) { + updateBlockWeBothHave(peer, block); + if (peer.getSyncBlockToFetch().isEmpty()) { //send sync to let peer know we are sync. + syncNextBatchChainIds(peer); + } + } + }); + } +} diff --git a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java new file mode 100644 index 00000000000..b393e320ffb --- /dev/null +++ b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -0,0 +1,136 @@ +package org.tron.core.net.messagehandler; + +import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.config.Parameter.ChainConstant; +import org.tron.core.config.Parameter.NodeConstant; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; +import org.tron.core.net.TronManager; +import org.tron.core.net.TronProxy; +import org.tron.core.net.message.ChainInventoryMessage; +import org.tron.core.net.message.TronMessage; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerSync; + +@Slf4j +@Component +public class ChainInventoryMsgHandler implements TronMsgHandler { + + @Autowired + private TronProxy tronProxy; + + @Autowired + private PeerSync peerSync; + + @Setter + private TronManager tronManager; + + @Override + public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { + + ChainInventoryMessage chainInventoryMessage = (ChainInventoryMessage) msg; + + check(peer, chainInventoryMessage); + + peer.setNeedSyncFromPeer(true); + + peer.setSyncChainRequested(null); + + Deque blockIdWeGet = new LinkedList<>(chainInventoryMessage.getBlockIds()); + + if (blockIdWeGet.size() == 1 && tronProxy.containBlock(blockIdWeGet.peek())) { + peer.setNeedSyncFromPeer(false); +// unSyncNum = getUnSyncNum(); +// if (unSyncNum == 0) { +// del.syncToCli(0); +// } + return; + } + + while (!peer.getSyncBlockToFetch().isEmpty()){ + if (peer.getSyncBlockToFetch().peekLast().equals(blockIdWeGet.peekFirst())) { + break; + } + peer.getSyncBlockToFetch().pollLast(); + } + + blockIdWeGet.poll(); + + peer.setUnfetchSyncNum(chainInventoryMessage.getRemainNum()); + peer.getSyncBlockToFetch().addAll(blockIdWeGet); + + synchronized (tronManager.getBlockLock()) { + while (!peer.getSyncBlockToFetch().isEmpty() && tronProxy.containBlock(peer.getSyncBlockToFetch().peek())) { + BlockId blockId = peer.getSyncBlockToFetch().pop(); + logger.info("Block {} from {} is processed", blockId.getString(), peer.getNode().getHost()); + } + } + + if (chainInventoryMessage.getRemainNum() == 0 && peer.getSyncBlockToFetch().isEmpty()) { + peer.setNeedSyncFromPeer(false); + } + +// long newUnSyncNum = getUnSyncNum(); +// if (unSyncNum != newUnSyncNum) { +// unSyncNum = newUnSyncNum; +// del.syncToCli(unSyncNum); +// } + + if ((chainInventoryMessage.getRemainNum() == 0 && !peer.getSyncBlockToFetch().isEmpty()) || + (chainInventoryMessage.getRemainNum() != 0 && peer.getSyncBlockToFetch().size() > NodeConstant.SYNC_FETCH_BATCH_NUM)) { + tronManager.setSyncBlockFetchFlag(true); + }else { + peerSync.syncNext(peer); + } + } + + private void check(PeerConnection peer, ChainInventoryMessage msg) throws Exception { + if (peer.getSyncChainRequested() == null) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "not send syncBlockChainMsg"); + } + + List blockIds = msg.getBlockIds(); + if (CollectionUtils.isEmpty(blockIds)) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "blockIds is empty"); + } + + if (msg.getRemainNum() == 0 && blockIds.size() < NodeConstant.SYNC_FETCH_BATCH_NUM) { + throw new P2pException(TypeEnum.BAD_MESSAGE, + "remain blockNum: 0, blockIds size: " + blockIds.size()); + } + + long num = blockIds.get(0).getNum(); + for (BlockId id : msg.getBlockIds()) { + if (id.getNum() != num++) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "not continuous block"); + } + } + + if (!peer.getSyncChainRequested().getKey().contains(blockIds.get(0))) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "unlinked block, my head: " + + peer.getSyncChainRequested().getKey().getLast().getString() + + ", peer: " + blockIds.get(0).getString()); + } + + if (tronProxy.getHeadBlockId().getNum() > 0) { + long maxRemainTime = ChainConstant.CLOCK_MAX_DELAY + System.currentTimeMillis() - tronProxy.getBlockTime(tronProxy.getSolidBlockId()); + long maxFutureNum = maxRemainTime / BLOCK_PRODUCED_INTERVAL + tronProxy.getSolidBlockId().getNum(); + long lastNum = blockIds.get(blockIds.size() - 1).getNum(); + if (lastNum + msg.getRemainNum() > maxFutureNum) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "lastNum: " + lastNum + " + remainNum: " + + msg.getRemainNum() + " > futureMaxNum: " + maxFutureNum); + } + } + } + +} diff --git a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java index d16f6a484f5..4e060605703 100644 --- a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java +++ b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java @@ -34,29 +34,40 @@ public class SyncBlockChainMsgHadler implements TronMsgHandler { @Autowired - TronProxy tronProxy; + private TronProxy tronProxy; - private LinkedList getLostBlockIds(List blockIds) throws Exception{ + @Override + public void processMessage(PeerConnection peer, TronMessage msg) throws Exception { - BlockId unForkId = null; - for (int i = blockIds.size() - 1; i >= 0; i--){ - if (tronProxy.containBlockInMainChain(blockIds.get(i))){ - unForkId = blockIds.get(i); - break; - } - } + SyncBlockChainMessage syncBlockChainMessage = (SyncBlockChainMessage) msg; - long len = Math.min(tronProxy.getHeadBlockId().getNum(), unForkId.getNum() + NodeConstant.SYNC_FETCH_BATCH_NUM); + check(peer, syncBlockChainMessage); - LinkedList ids = new LinkedList<>(); - for (long i = unForkId.getNum(); i <= len; i++) { - BlockId id = tronProxy.getBlockIdByNum(i); - ids.add(id); + long remainNum = 0; + + List summaryChainIds = syncBlockChainMessage.getBlockIds(); + + LinkedList blockIds = getLostBlockIds(summaryChainIds); + + if (blockIds.size() == 1 && summaryChainIds.contains(blockIds.get(0))){ + peer.setNeedSyncFromUs(false); + }else { + peer.setNeedSyncFromUs(true); + remainNum = tronProxy.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); } - return ids; + + if (!peer.isNeedSyncFromPeer() + && !tronProxy.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) + && tronProxy.canChainRevoke(summaryChainIds.get(0).getNum())) { + //startSyncWithPeer(peer); + } + + peer.setLastSyncBlockId(blockIds.peekLast()); + peer.setRemainNum(remainNum); + peer.sendMessage(new ChainInventoryMessage(blockIds, remainNum)); } - private void checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage msg) throws Exception{ + private void check(PeerConnection peer, SyncBlockChainMessage msg) throws Exception{ List blockIds = msg.getBlockIds(); if (CollectionUtils.isEmpty(blockIds)){ throw new P2pException(TypeEnum.BAD_MESSAGE, "SyncBlockChain blockIds is empty"); @@ -79,33 +90,24 @@ private void checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessa } } - public void processMessage(PeerConnection peer, TronMessage msg) throws Exception { - - SyncBlockChainMessage syncBlockChainMessage = (SyncBlockChainMessage) msg; - - checkSyncBlockChainMessage(peer, syncBlockChainMessage); - - long remainNum = 0; - - List summaryChainIds = syncBlockChainMessage.getBlockIds(); - - LinkedList blockIds = getLostBlockIds(summaryChainIds); + private LinkedList getLostBlockIds(List blockIds) throws Exception{ - if (blockIds.size() == 1 && summaryChainIds.contains(blockIds.get(0))){ - peer.setNeedSyncFromUs(false); - }else { - peer.setNeedSyncFromUs(true); - remainNum = tronProxy.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); + BlockId unForkId = null; + for (int i = blockIds.size() - 1; i >= 0; i--){ + if (tronProxy.containBlockInMainChain(blockIds.get(i))){ + unForkId = blockIds.get(i); + break; + } } - if (!peer.isNeedSyncFromPeer() - && !tronProxy.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) - && tronProxy.canChainRevoke(summaryChainIds.get(0).getNum())) { - //startSyncWithPeer(peer); - } + long len = Math.min(tronProxy.getHeadBlockId().getNum(), unForkId.getNum() + NodeConstant.SYNC_FETCH_BATCH_NUM); - peer.setLastSyncBlockId(blockIds.peekLast()); - peer.setRemainNum(remainNum); - peer.sendMessage(new ChainInventoryMessage(blockIds, remainNum)); + LinkedList ids = new LinkedList<>(); + for (long i = unForkId.getNum(); i <= len; i++) { + BlockId id = tronProxy.getBlockIdByNum(i); + ids.add(id); + } + return ids; } + } diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index 16b3a6f1228..f5288bd54d4 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -11,20 +11,21 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.tron.core.config.args.Args; -import org.tron.core.exception.TraitorPeerException; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; import org.tron.core.net.message.TransactionMessage; import org.tron.core.net.message.TransactionsMessage; -import org.tron.core.net.node.Item; +import org.tron.core.net.message.TronMessage; +import org.tron.core.net.peer.Item; import org.tron.core.net.node.NodeImpl; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Inventory.InventoryType; -import org.tron.protos.Protocol.ReasonCode; import org.tron.protos.Protocol.Transaction; import org.tron.protos.Protocol.Transaction.Contract.ContractType; @Slf4j @Component -public class TransactionsMsgHandler { +public class TransactionsMsgHandler implements TronMsgHandler { private NodeImpl nodeImpl; @@ -44,11 +45,59 @@ public class TransactionsMsgHandler { private ScheduledExecutorService smartContractExecutor = Executors.newSingleThreadScheduledExecutor(); + 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(); + } + } + public void init(NodeImpl nodeImpl) { this.nodeImpl = nodeImpl; handleSmartContract(); } + public boolean isBusy() { + return queue.size() > MAX_TRX_SIZE; + } + + @Override + public void processMessage(PeerConnection peer, TronMessage msg) throws Exception { + + TransactionsMessage transactionsMessage = (TransactionsMessage) msg; + + check (peer, transactionsMessage); + + for (Transaction trx : transactionsMessage.getTransactions().getTransactionsList()) { + int type = trx.getRawData().getContract(0).getType().getNumber(); + if (type == ContractType.TriggerSmartContract_VALUE || type == ContractType.CreateSmartContract_VALUE) { + if (!smartContractQueue.offer(new TrxEvent(peer, new TransactionMessage(trx)))) { + logger.warn("Add smart contract failed, queueSize {}:{}", smartContractQueue.size(), queue.size()); + } + } else { + trxHandlePool.submit(() -> nodeImpl.onHandleTransactionMessage(peer, new TransactionMessage(trx))); + } + } + } + + private void check(PeerConnection peer, TransactionsMessage msg) throws Exception { + for (Transaction trx : msg.getTransactions().getTransactionsList()) { + Item item = new Item(new TransactionMessage(trx).getMessageId(), InventoryType.TRX); + if (!peer.getAdvObjWeRequested().containsKey(item)) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "trx: " + msg.getMessageId() + " without request."); + } + peer.getAdvObjWeRequested().remove(item); + } + } + private void handleSmartContract() { smartContractExecutor.scheduleWithFixedDelay(() -> { try { @@ -66,45 +115,4 @@ private void handleSmartContract() { }, 1000, 20, TimeUnit.MILLISECONDS); } - public void handleTransactionsMessage(PeerConnection peer, TransactionsMessage msg) { - for (Transaction trx : msg.getTransactions().getTransactionsList()) { - Item item = new Item(new TransactionMessage(trx).getMessageId(), InventoryType.TRX); - if (!peer.getAdvObjWeRequested().containsKey(item)) { - logger.warn("Receive trx {} from peer {} without fetch request.", - msg.getMessageId(), peer.getInetAddress()); - peer.setSyncFlag(false); - peer.disconnect(ReasonCode.BAD_PROTOCOL); - return; - } - peer.getAdvObjWeRequested().remove(item); - int type = trx.getRawData().getContract(0).getType().getNumber(); - if (type == ContractType.TriggerSmartContract_VALUE || type == ContractType.CreateSmartContract_VALUE) { - if (!smartContractQueue.offer(new TrxEvent(peer, new TransactionMessage(trx)))) { - logger.warn("Add smart contract failed, smartContractQueue size {} queueSize {}", - smartContractQueue.size(), queue.size()); - } - } else { - trxHandlePool.submit(() -> nodeImpl.onHandleTransactionMessage(peer, new TransactionMessage(trx))); - } - } - } - - public boolean isBusy() { - return queue.size() > MAX_TRX_SIZE; - } - - 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(); - } - } } \ No newline at end of file diff --git a/src/main/java/org/tron/core/net/node/NodeImpl.java b/src/main/java/org/tron/core/net/node/NodeImpl.java index e8e45f4ce7f..05aed818465 100644 --- a/src/main/java/org/tron/core/net/node/NodeImpl.java +++ b/src/main/java/org/tron/core/net/node/NodeImpl.java @@ -68,8 +68,8 @@ import org.tron.core.net.message.TransactionsMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.messagehandler.TransactionsMsgHandler; +import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerConnection; -import org.tron.core.net.peer.PeerConnectionDelegate; import org.tron.core.services.WitnessProductBlockService; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Inventory.InventoryType; @@ -289,7 +289,7 @@ public void onMessage(PeerConnection peer, TronMessage msg) { onHandleBlockMessage(peer, (BlockMessage) msg); break; case TRXS: - transactionsMsgHandler.handleTransactionsMessage(peer, (TransactionsMessage) msg); + transactionsMsgHandler.processMessage(peer, msg); break; case SYNC_BLOCK_CHAIN: onHandleSyncBlockChainMessage(peer, (SyncBlockChainMessage) msg); @@ -1252,7 +1252,6 @@ private void updateBlockWeBothHave(PeerConnection peer, BlockCapsule block) { logger.info("update peer {} block both we have {}", peer.getNode().getHost(), block.getBlockId().getString()); peer.setHeadBlockWeBothHave(block.getBlockId()); - peer.setHeadBlockTimeWeBothHave(block.getTimeStamp()); peer.setLastBlockUpdateTime(System.currentTimeMillis()); } @@ -1263,7 +1262,6 @@ private void updateBlockWeBothHave(PeerConnection peer, BlockId blockId) peer.setHeadBlockWeBothHave(blockId); long time = ((BlockMessage) del.getData(blockId, MessageTypes.BLOCK)).getBlockCapsule() .getTimeStamp(); - peer.setHeadBlockTimeWeBothHave(time); peer.setLastBlockUpdateTime(System.currentTimeMillis()); } @@ -1346,7 +1344,6 @@ public void shutDown() { } private void disconnectPeer(PeerConnection peer, ReasonCode reason) { - peer.setSyncFlag(false); peer.disconnect(reason); } diff --git a/src/main/java/org/tron/core/net/peer/PeerConnectionDelegate.java b/src/main/java/org/tron/core/net/node/PeerConnectionDelegate.java similarity index 84% rename from src/main/java/org/tron/core/net/peer/PeerConnectionDelegate.java rename to src/main/java/org/tron/core/net/node/PeerConnectionDelegate.java index 2182f575858..4db31022169 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnectionDelegate.java +++ b/src/main/java/org/tron/core/net/node/PeerConnectionDelegate.java @@ -1,8 +1,9 @@ -package org.tron.core.net.peer; +package org.tron.core.net.node; import org.tron.common.overlay.message.Message; import org.tron.common.utils.Sha256Hash; import org.tron.core.net.message.TronMessage; +import org.tron.core.net.peer.PeerConnection; public abstract class PeerConnectionDelegate { diff --git a/src/main/java/org/tron/core/net/node/Item.java b/src/main/java/org/tron/core/net/peer/Item.java similarity index 95% rename from src/main/java/org/tron/core/net/node/Item.java rename to src/main/java/org/tron/core/net/peer/Item.java index 89f7504bded..74a55e15c59 100644 --- a/src/main/java/org/tron/core/net/node/Item.java +++ b/src/main/java/org/tron/core/net/peer/Item.java @@ -1,4 +1,4 @@ -package org.tron.core.net.node; +package org.tron.core.net.peer; import lombok.Getter; import org.tron.common.utils.Sha256Hash; diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index 2b03e064e9b..1f41bd95069 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -2,8 +2,6 @@ import static org.tron.core.config.Parameter.NetConstants.MAX_INVENTORY_SIZE_IN_MINUTES; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; import java.util.Deque; import java.util.HashSet; import java.util.Iterator; @@ -18,6 +16,7 @@ import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.tron.common.overlay.message.HelloMessage; @@ -26,17 +25,15 @@ import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.Time; import org.tron.core.capsule.BlockCapsule.BlockId; -import org.tron.core.config.Parameter.NodeConstant; -import org.tron.core.config.args.Args; -import org.tron.core.net.node.Item; +import org.tron.core.net.TronProxy; @Slf4j @Component @Scope("prototype") public class PeerConnection extends Channel { - private Cache syncBlockIdCache = CacheBuilder.newBuilder() - .maximumSize(2 * NodeConstant.SYNC_FETCH_BATCH_NUM).build(); + @Autowired + private TronProxy tronProxy; @Setter @Getter @@ -50,210 +47,86 @@ public class PeerConnection extends Channel { @Getter private long lastBlockUpdateTime = System.currentTimeMillis(); - private volatile boolean syncFlag = true; - + @Setter private HelloMessage helloMessage; - //broadcast + @Setter + @Getter private Queue invToUs = new LinkedBlockingQueue<>(); + @Setter + @Getter private Queue invWeAdv = new LinkedBlockingQueue<>(); + @Setter + @Getter private Map advObjSpreadToUs = new ConcurrentHashMap<>(); + @Setter + @Getter private Map advObjWeSpread = new ConcurrentHashMap<>(); + @Setter + @Getter private Map advObjWeRequested = new ConcurrentHashMap<>(); - private boolean advInhibit = false; - - public Map getAdvObjSpreadToUs() { - return advObjSpreadToUs; - } - - public Map getAdvObjWeSpread() { - return advObjWeSpread; - } - - public boolean isAdvInhibit() { - return advInhibit; - } - - public void setAdvInhibit(boolean advInhibit) { - this.advInhibit = advInhibit; - } - - //sync chain + @Setter + @Getter private BlockId headBlockWeBothHave = new BlockId(); - private long headBlockTimeWeBothHave; - + @Setter + @Getter private Deque syncBlockToFetch = new ConcurrentLinkedDeque<>(); + @Setter + @Getter private Map syncBlockRequested = new ConcurrentHashMap<>(); + @Setter + @Getter private Pair, Long> syncChainRequested = null; - public Pair, Long> getSyncChainRequested() { - return syncChainRequested; - } - - public Cache getSyncBlockIdCache() { - return syncBlockIdCache; - } - - public void setSyncChainRequested( - Pair, Long> syncChainRequested) { - this.syncChainRequested = syncChainRequested; - } - - public Map getSyncBlockRequested() { - return syncBlockRequested; - } - - public void setSyncBlockRequested(ConcurrentHashMap syncBlockRequested) { - this.syncBlockRequested = syncBlockRequested; - } - - public long getUnfetchSyncNum() { - return unfetchSyncNum; - } - - public void setUnfetchSyncNum(long unfetchSyncNum) { - this.unfetchSyncNum = unfetchSyncNum; - } - + @Setter + @Getter private long unfetchSyncNum = 0L; + @Setter + @Getter private boolean needSyncFromPeer; + @Setter + @Getter private boolean needSyncFromUs; - public Set getBlockInProc() { - return blockInProc; - } - - public void setBlockInProc(Set blockInProc) { - this.blockInProc = blockInProc; - } - - private boolean banned; - + @Setter + @Getter private Set blockInProc = new HashSet<>(); - public Map getAdvObjWeRequested() { - return advObjWeRequested; - } - - public void setAdvObjWeRequested(ConcurrentHashMap advObjWeRequested) { - this.advObjWeRequested = advObjWeRequested; - } - - public void setHelloMessage(HelloMessage helloMessage) { - this.helloMessage = helloMessage; - } - - public HelloMessage getHelloMessage() { - return this.helloMessage; - } - public void cleanInvGarbage() { - long oldestTimestamp = - Time.getCurrentMillis() - MAX_INVENTORY_SIZE_IN_MINUTES * 60 * 1000; + + long time = Time.getCurrentMillis() - MAX_INVENTORY_SIZE_IN_MINUTES * 60 * 1000; Iterator> iterator = this.advObjSpreadToUs.entrySet().iterator(); - removeIterator(iterator, oldestTimestamp); + removeIterator(iterator, time); iterator = this.advObjWeSpread.entrySet().iterator(); - removeIterator(iterator, oldestTimestamp); + removeIterator(iterator, time); } private void removeIterator(Iterator> iterator, long oldestTimestamp) { while (iterator.hasNext()) { Map.Entry entry = iterator.next(); Long ts = (Long) entry.getValue(); - if (ts < oldestTimestamp) { iterator.remove(); } } } - public boolean isAdvInvFull() { - return advObjSpreadToUs.size() > MAX_INVENTORY_SIZE_IN_MINUTES - * 60 - * Args.getInstance().getNetMaxTrxPerSecond(); - } - - public boolean isBanned() { - return banned; - } - - public void setBanned(boolean banned) { - this.banned = banned; - } - - public BlockId getHeadBlockWeBothHave() { - return headBlockWeBothHave; - } - - public void setHeadBlockWeBothHave(BlockId headBlockWeBothHave) { - this.headBlockWeBothHave = headBlockWeBothHave; - } - - public long getHeadBlockTimeWeBothHave() { - return headBlockTimeWeBothHave; - } - public void setHeadBlockTimeWeBothHave(long headBlockTimeWeBothHave) { - this.headBlockTimeWeBothHave = headBlockTimeWeBothHave; - } - public Deque getSyncBlockToFetch() { - return syncBlockToFetch; - } - - public boolean isNeedSyncFromPeer() { - return needSyncFromPeer; - } - - public void setNeedSyncFromPeer(boolean needSyncFromPeer) { - this.needSyncFromPeer = needSyncFromPeer; - } - - public boolean isNeedSyncFromUs() { - return needSyncFromUs; - } - - public void setNeedSyncFromUs(boolean needSyncFromUs) { - this.needSyncFromUs = needSyncFromUs; - } - - public Queue getInvToUs() { - return invToUs; - } - - public void setInvToUs(Queue invToUs) { - this.invToUs = invToUs; - } - - public Queue getInvWeAdv() { - return invWeAdv; - } - - public void setInvWeAdv(Queue invWeAdv) { - this.invWeAdv = invWeAdv; - } - - public boolean getSyncFlag() { - return syncFlag; - } - - public void setSyncFlag(boolean syncFlag) { - this.syncFlag = syncFlag; - } public String logSyncStats() { return String.format( diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java new file mode 100644 index 00000000000..d9e3e192d45 --- /dev/null +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -0,0 +1,96 @@ +package org.tron.core.net.peer; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import javafx.util.Pair; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.common.overlay.server.Channel.TronState; +import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; +import org.tron.core.net.TronManager; +import org.tron.core.net.TronProxy; +import org.tron.core.net.message.SyncBlockChainMessage; + +@Slf4j +@Component +public class PeerSync { + + @Autowired + private TronProxy tronProxy; + + @Autowired + private TronManager tronManager; + + public void startSync(PeerConnection peer) throws Exception { + peer.setTronState(TronState.SYNCING); + peer.setNeedSyncFromPeer(true); + peer.getSyncBlockToFetch().clear(); + peer.setRemainNum(0); + peer.setHeadBlockWeBothHave(tronProxy.getGenesisBlockId()); + syncNext(peer); + } + + public void syncNext(PeerConnection peer) throws Exception { + if (peer.getSyncChainRequested() != null) { + logger.warn("Peer {} is in sync.", peer.getNode().getHost()); + return; + } + LinkedList chainSummary = getBlockChainSummary(peer); + peer.setSyncChainRequested(new Pair<>(chainSummary, System.currentTimeMillis())); + peer.sendMessage(new SyncBlockChainMessage(chainSummary)); + } + + private LinkedList getBlockChainSummary(PeerConnection peer) throws Exception { + + BlockId beginBlockId = peer.getHeadBlockWeBothHave(); + List blockIds = new ArrayList<>(peer.getSyncBlockToFetch()); + LinkedList forkList = new LinkedList<>(); + LinkedList retSummary = new LinkedList<>(); + long syncBeginNumber = tronProxy.getSyncBeginNumber(); + long low = syncBeginNumber < 0 ? 0 : syncBeginNumber; + long highNoFork; + long high; + + if (beginBlockId.getNum() == 0){ + highNoFork = high = tronProxy.getHeadBlockId().getNum(); + }else { + if (tronProxy.containBlockInMainChain(beginBlockId)) { + highNoFork = high = beginBlockId.getNum(); + } else { + forkList = tronProxy.getBlockChainHashesOnFork(beginBlockId); + if (forkList.isEmpty()) { + throw new P2pException(TypeEnum.SYNC_FAILED, "can't find blockId: " + beginBlockId.getString()); + } + highNoFork = forkList.peekLast().getNum(); + forkList.pollLast(); + Collections.reverse(forkList); + high = highNoFork + forkList.size(); + } + } + + logger.info("Get block chain summary, low: {}, highNoFork: {}, high: {}", low, highNoFork, high); + + tronManager.check(low <= highNoFork, "low gt highNoFork"); + + long realHighBlkNum = high + blockIds.size(); + while (low <= realHighBlkNum) { + if (low <= highNoFork) { + retSummary.offer(tronProxy.getBlockIdByNum(low)); + } else if (low <= high) { + retSummary.offer(forkList.get((int) (low - highNoFork - 1))); + } else { + retSummary.offer(blockIds.get((int) (low - high - 1))); + } + low += (realHighBlkNum - low + 2) / 2; + } + + return retSummary; + } + +} diff --git a/src/test/java/org/tron/core/net/node/BroadTest.java b/src/test/java/org/tron/core/net/node/BroadTest.java index f895f4ce29c..b6fc7676f69 100644 --- a/src/test/java/org/tron/core/net/node/BroadTest.java +++ b/src/test/java/org/tron/core/net/node/BroadTest.java @@ -10,7 +10,6 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.MapUtils; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -38,6 +37,7 @@ import org.tron.core.net.node.override.HandshakeHandlerTest; import org.tron.core.net.node.override.PeerClientTest; import org.tron.core.net.node.override.TronChannelInitializerTest; +import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerConnection; import org.tron.core.services.RpcApiService; import org.tron.core.services.WitnessService; diff --git a/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java b/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java index 7eba6cd576a..20c091e53da 100644 --- a/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java +++ b/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java @@ -13,7 +13,6 @@ import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.crypto.ECKey; -import org.tron.common.overlay.client.PeerClient; import org.tron.common.overlay.discover.node.Node; import org.tron.common.overlay.server.Channel; import org.tron.common.overlay.server.ChannelManager; @@ -31,6 +30,7 @@ import org.tron.core.net.node.override.HandshakeHandlerTest; import org.tron.core.net.node.override.PeerClientTest; import org.tron.core.net.node.override.TronChannelInitializerTest; +import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerConnection; import org.tron.core.services.RpcApiService; import org.tron.core.services.WitnessService; diff --git a/src/test/java/org/tron/core/net/node/HandleTransactionTest.java b/src/test/java/org/tron/core/net/node/HandleTransactionTest.java index afa5823102f..a79c0957b06 100644 --- a/src/test/java/org/tron/core/net/node/HandleTransactionTest.java +++ b/src/test/java/org/tron/core/net/node/HandleTransactionTest.java @@ -32,6 +32,7 @@ import org.tron.core.net.node.override.HandshakeHandlerTest; import org.tron.core.net.node.override.PeerClientTest; import org.tron.core.net.node.override.TronChannelInitializerTest; +import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerConnection; import org.tron.core.services.RpcApiService; import org.tron.core.services.WitnessService; diff --git a/src/test/java/org/tron/core/net/node/NodeImplTest.java b/src/test/java/org/tron/core/net/node/NodeImplTest.java index 490716498f9..ce59926689f 100644 --- a/src/test/java/org/tron/core/net/node/NodeImplTest.java +++ b/src/test/java/org/tron/core/net/node/NodeImplTest.java @@ -23,6 +23,7 @@ import org.tron.core.config.args.Args; import org.tron.core.db.Manager; import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Block; import org.tron.protos.Protocol.BlockHeader; From 38471b9a6d41be75a49e654d84432cfea3a82db5 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 5 Nov 2018 19:54:37 +0800 Subject: [PATCH 06/41] add peer adv --- .../org/tron/core/exception/P2pException.java | 23 +- .../java/org/tron/core/net/TronProxy.java | 19 ++ .../net/messagehandler/BlockMsgHandler.java | 232 ++++++++++++------ .../java/org/tron/core/net/peer/PeerAdv.java | 52 ++++ .../java/org/tron/core/net/peer/PeerSync.java | 4 +- 5 files changed, 241 insertions(+), 89 deletions(-) create mode 100644 src/main/java/org/tron/core/net/peer/PeerAdv.java diff --git a/src/main/java/org/tron/core/exception/P2pException.java b/src/main/java/org/tron/core/exception/P2pException.java index 9975512f813..eb689a3f3b6 100644 --- a/src/main/java/org/tron/core/exception/P2pException.java +++ b/src/main/java/org/tron/core/exception/P2pException.java @@ -9,19 +9,26 @@ public P2pException(TypeEnum type, String errMsg){ this.type = type; } + public P2pException(TypeEnum type, String errMsg, Throwable throwable){ + super(errMsg, throwable); + this.type = type; + } + public TypeEnum getType() { return type; } public enum TypeEnum { - NO_SUCH_MESSAGE (1, "No such message"), - PARSE_MESSAGE_FAILED (2, "Parse message failed"), - MESSAGE_WITH_WRONG_LENGTH (3, "Message with wrong length"), - BAD_MESSAGE (4, "Bad message"), - DIFF_GENESIS_BLOCK (5, "Different genesis block"), - HARD_FORKED (6, "Hard forked"), - SYNC_FAILED (7, "Sync failed"), - CHECK_FAILED (8, "Check failed"), + NO_SUCH_MESSAGE (1, "no such message"), + PARSE_MESSAGE_FAILED (2, "parse message failed"), + MESSAGE_WITH_WRONG_LENGTH (3, "message with wrong length"), + BAD_MESSAGE (4, "bad message"), + DIFF_GENESIS_BLOCK (5, "different genesis block"), + HARD_FORKED (6, "hard forked"), + SYNC_FAILED (7, "sync failed"), + CHECK_FAILED (8, "check failed"), + BAD_BLOCK (9, "bad block"), + UNLINK_BLOCK (10, "unlink block"), DEFAULT (100, "default exception"); private Integer value; diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronProxy.java index 1bff0cbbd04..625247f794e 100644 --- a/src/main/java/org/tron/core/net/TronProxy.java +++ b/src/main/java/org/tron/core/net/TronProxy.java @@ -1,10 +1,12 @@ package org.tron.core.net; +import java.util.Collection; import java.util.LinkedList; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.overlay.message.Message; +import org.tron.common.overlay.server.SyncPool; import org.tron.common.utils.Sha256Hash; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BlockCapsule.BlockId; @@ -16,14 +18,22 @@ import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.MessageTypes; import org.tron.core.net.message.TransactionMessage; +import org.tron.core.net.peer.PeerConnection; @Slf4j @Component public class TronProxy { + @Autowired + private SyncPool syncPool; + @Autowired private Manager dbManager; + public Collection getActivePeer() { + return syncPool.getActivePeers(); + } + public long getSyncBeginNumber() { return dbManager.getSyncBeginNumber(); } @@ -38,6 +48,14 @@ public long getBlockTime(BlockId id) { } } + public void preValidateTransactionSign (BlockCapsule block) throws Exception { + dbManager.preValidateTransactionSign(block); + } + + public void pushBlock (BlockCapsule block) throws Exception { + dbManager.pushBlock(block); + } + public BlockId getHeadBlockId() { return dbManager.getHeadBlockId(); } @@ -55,6 +73,7 @@ public BlockId getGenesisBlockId() { public BlockCapsule getGenesisBlock() { return dbManager.getGenesisBlock(); } + public long getHeadBlockTimeStamp() { return dbManager.getHeadBlockTimeStamp(); } diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 9654ebd34ef..7c327afe5ad 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -1,26 +1,53 @@ package org.tron.core.net.messagehandler; +import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; +import static org.tron.core.config.Parameter.ChainConstant.BLOCK_SIZE; + +import java.util.HashMap; import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executors; +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.utils.Sha256Hash; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.Parameter.NodeConstant; +import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.BadBlockException; +import org.tron.core.exception.BadNumberBlockException; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.DupTransactionException; import org.tron.core.exception.NonCommonBlockException; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; +import org.tron.core.exception.ReceiptCheckErrException; +import org.tron.core.exception.TaposException; +import org.tron.core.exception.TooBigTransactionException; +import org.tron.core.exception.TooBigTransactionResultException; +import org.tron.core.exception.TransactionExpirationException; import org.tron.core.exception.UnLinkedBlockException; +import org.tron.core.exception.VMIllegalException; +import org.tron.core.exception.ValidateScheduleException; +import org.tron.core.exception.ValidateSignatureException; import org.tron.core.net.TronManager; import org.tron.core.net.TronProxy; import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.ChainInventoryMessage; import org.tron.core.net.message.TronMessage; +import org.tron.core.net.node.NodeImpl.PriorItem; import org.tron.core.net.peer.Item; +import org.tron.core.net.peer.PeerAdv; import org.tron.core.net.peer.PeerConnection; import org.tron.core.net.peer.PeerSync; import org.tron.core.services.WitnessProductBlockService; @@ -37,6 +64,9 @@ public class BlockMsgHandler implements TronMsgHandler { @Autowired private TronManager tronManager; + @Autowired + private PeerAdv peerAdv; + @Autowired private PeerSync peerSync; @@ -47,6 +77,8 @@ public class BlockMsgHandler implements TronMsgHandler { private Map blockJustReceived = new ConcurrentHashMap<>(); + private HashMap advObjWeRequested = new HashMap<>(); + private Queue freshBlockId = new ConcurrentLinkedQueue() { @Override public boolean offer(BlockId blockId) { @@ -57,13 +89,30 @@ public boolean offer(BlockId blockId) { } }; - private boolean isHandleSyncBlockActive; + private ScheduledExecutorService syncHandleExecutor = Executors.newSingleThreadScheduledExecutor(); + + private boolean syncHandleFlag; + + public void init () { + syncHandleExecutor.scheduleWithFixedDelay(() -> { + try { + if (syncHandleFlag) { + syncHandleFlag = false; + handleSyncBlock(); + } + } catch (Throwable t) { + logger.error("Unhandled exception", t); + } + }, 10, 1, TimeUnit.SECONDS); + } @Override public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { BlockMessage blockMessage = (BlockMessage) msg; + check(peer, blockMessage); + BlockId blockId = blockMessage.getBlockId(); Item item = new Item(blockId, InventoryType.BLOCK); boolean syncFlag = false; @@ -72,7 +121,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti synchronized (blockJustReceived) { blockJustReceived.put(blockMessage, peer); } - isHandleSyncBlockActive = true; + syncHandleFlag = true; syncFlag = true; if (!peer.isBusy()) { if (peer.getUnfetchSyncNum() > 0 && peer.getSyncBlockToFetch().size() <= NodeConstant.SYNC_FETCH_BATCH_NUM) { @@ -90,98 +139,123 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti } } - private void check(PeerConnection peer, ChainInventoryMessage msg) throws Exception { + private void check (PeerConnection peer, BlockMessage msg) throws Exception { + BlockCapsule blockCapsule = msg.getBlockCapsule(); + if (blockCapsule.getInstance().getSerializedSize() > BLOCK_SIZE + 100) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "block size over limit"); + } + long gap = blockCapsule.getTimeStamp() - System.currentTimeMillis(); + if (gap >= BLOCK_PRODUCED_INTERVAL) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "block time error"); + } } - private void processAdvBlock(PeerConnection peer, BlockCapsule block) { + private void processAdvBlock(PeerConnection peer, BlockCapsule block) throws Exception { synchronized (tronManager.getBlockLock()) { - if (!freshBlockId.contains(block.getBlockId())) { + BlockId blockId = block.getBlockId(); + if (freshBlockId.contains(blockId)) { + return; + } + if (!tronProxy.containBlock(block.getBlockId())) { + logger.warn("Get unlink block {} from {}, head is {}.", blockId.getString(), + peer.getInetAddress(), tronProxy.getHeadBlockId().getString()); + peerSync.startSync(peer); + return; + } + witnessProductBlockService.validWitnessProductTwoBlock(block); + handleBlock(block); + //trxIds.forEach(trxId -> advObjToFetch.remove(trxId)); + tronProxy.getActivePeer().forEach(p -> { + if (p.getAdvObjSpreadToUs().containsKey(blockId)) { + p.setHeadBlockWeBothHave(blockId); + } + }); + peerAdv.broadcast(new BlockMessage(block)); + } + } + + private void processSyncBlock (BlockCapsule block) { + synchronized (tronManager.getBlockLock()) { + boolean flag = true; + BlockId blockId = block.getBlockId(); + if (!freshBlockId.contains(blockId)) { try { - witnessProductBlockService.validWitnessProductTwoBlock(block); - LinkedList trxIds = null; - trxIds = del.handleBlock(block, false); - freshBlockId.offer(block.getBlockId()); - - trxIds.forEach(trxId -> advObjToFetch.remove(trxId)); - - getActivePeer().stream() - .filter(p -> p.getAdvObjSpreadToUs().containsKey(block.getBlockId())) - .forEach(p -> updateBlockWeBothHave(p, block)); - - broadcast(new BlockMessage(block)); - - } catch (BadBlockException e) { - logger.error("We get a bad block {}, from {}, reason is {} ", - block.getBlockId().getString(), peer.getNode().getHost(), e.getMessage()); - disconnectPeer(peer, ReasonCode.BAD_BLOCK); - } catch (UnLinkedBlockException e) { - logger.error("We get a unlinked block {}, from {}, head is {}", block.getBlockId(). - getString(), peer.getNode().getHost(), del.getHeadBlockId().getString()); - startSyncWithPeer(peer); - } catch (NonCommonBlockException e) { - logger.error( - "We get a block {} that do not have the most recent common ancestor with the main chain, from {}, reason is {} ", - block.getBlockId().getString(), peer.getNode().getHost(), e.getMessage()); - disconnectPeer(peer, ReasonCode.FORKED); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + handleBlock(block); + } catch (Exception e) { + logger.error("Process sync block failed.", e); + flag = false; } } + for (PeerConnection peer: tronProxy.getActivePeer()) { + if (peer.getBlockInProc().remove(blockId)) { + if (flag){ + peer.setHeadBlockWeBothHave(blockId); + if (peer.getSyncBlockToFetch().isEmpty()) { + peerSync.syncNext(peer); + } + }else { + peer.disconnect(ReasonCode.BAD_BLOCK); + } + } + } + syncHandleFlag = true; } } - private boolean processSyncBlock(BlockCapsule block) { - boolean isAccept = false; - ReasonCode reason = null; + + private void handleBlock(BlockCapsule block) throws Exception { try { - try { - del.handleBlock(block, true); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - freshBlockId.offer(block.getBlockId()); - logger.info("Success handle block {}", block.getBlockId().getString()); - isAccept = true; - } catch (BadBlockException e) { - logger.error("We get a bad block {}, reason is {} ", block.getBlockId().getString(), - e.getMessage()); - reason = ReasonCode.BAD_BLOCK; - } catch (UnLinkedBlockException e) { - logger.error("We get a unlinked block {}, head is {}", block.getBlockId().getString(), - del.getHeadBlockId().getString()); - reason = ReasonCode.UNLINKABLE; - } catch (NonCommonBlockException e) { - logger.error( - "We get a block {} that do not have the most recent common ancestor with the main chain, head is {}", - block.getBlockId().getString(), - del.getHeadBlockId().getString()); - reason = ReasonCode.FORKED; + tronProxy.preValidateTransactionSign(block); + tronProxy.pushBlock(block); + freshBlockId.add(block.getBlockId()); + }catch (UnLinkedBlockException e){ + throw new P2pException(TypeEnum.UNLINK_BLOCK, block.getBlockId().getString(), e); + }catch (Exception e){ + throw new P2pException(TypeEnum.BAD_BLOCK, block.getBlockId().getString(), e); } + } + + private synchronized void handleSyncBlock() { - if (!isAccept) { - ReasonCode finalReason = reason; - getActivePeer().stream() - .filter(peer -> peer.getBlockInProc().contains(block.getBlockId())) - .forEach(peer -> disconnectPeer(peer, finalReason)); + synchronized (blockJustReceived) { + blockWaitToProc.putAll(blockJustReceived); + blockJustReceived.clear(); } - isHandleSyncBlockActive = true; - return isAccept; - } - private void finishProcessSyncBlock(BlockCapsule block) { - getActivePeer().forEach(peer -> { - if (peer.getSyncBlockToFetch().isEmpty() - && peer.getBlockInProc().isEmpty() - && !peer.isNeedSyncFromPeer() - && !peer.isNeedSyncFromUs()) { - startSyncWithPeer(peer); - } else if (peer.getBlockInProc().remove(block.getBlockId())) { - updateBlockWeBothHave(peer, block); - if (peer.getSyncBlockToFetch().isEmpty()) { //send sync to let peer know we are sync. - syncNextBatchChainIds(peer); + final boolean[] isBlockProc = {true}; + + while (isBlockProc[0]) { + + isBlockProc[0] = false; + + blockWaitToProc.forEach((msg, peerConnection) -> { + if (peerConnection.isDisconnect()) { + logger.error("Peer {} is disconnect, drop block {}", peerConnection.getInetAddress(), msg.getBlockId().getString()); + blockWaitToProc.remove(msg); + syncBlockIdWeRequested.invalidate(msg.getBlockId()); + isFetchSyncActive = true; + isBlockProc[0] = true; + return; } - } - }); + synchronized (freshBlockId) { + final boolean[] isFound = {false}; + tronProxy.getActivePeer().stream() + .filter(peer -> !peer.getSyncBlockToFetch().isEmpty() && + peer.getSyncBlockToFetch().peek().equals(msg.getBlockId())) + .forEach(peer -> { + peer.getSyncBlockToFetch().pop(); + peer.getBlockInProc().add(msg.getBlockId()); + isFound[0] = true; + }); + if (isFound[0]) { + blockWaitToProc.remove(msg); + isBlockProc[0] = true; + processSyncBlock(msg.getBlockCapsule()); + } + } + }); + } } + } diff --git a/src/main/java/org/tron/core/net/peer/PeerAdv.java b/src/main/java/org/tron/core/net/peer/PeerAdv.java new file mode 100644 index 00000000000..e0ee5b37826 --- /dev/null +++ b/src/main/java/org/tron/core/net/peer/PeerAdv.java @@ -0,0 +1,52 @@ +package org.tron.core.net.peer; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.tron.common.overlay.message.Message; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.message.TransactionMessage; +import org.tron.protos.Protocol.Inventory.InventoryType; + +@Slf4j +@Component +public class PeerAdv { + + @Getter + private Cache TrxCache = CacheBuilder.newBuilder() + .maximumSize(50_000).expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(50_000) + .recordStats().build(); + + private Cache BlockCache = CacheBuilder.newBuilder() + .maximumSize(10).expireAfterWrite(60, TimeUnit.SECONDS) + .recordStats().build(); + + private ConcurrentHashMap advObjToSpread = new ConcurrentHashMap<>(); + + public void broadcast(Message msg) { + InventoryType type; + if (msg instanceof BlockMessage) { + logger.info("Ready to broadcast block {}", ((BlockMessage) msg).getBlockId()); + //freshBlockId.offer(((BlockMessage) msg).getBlockId()); + BlockCache.put(msg.getMessageId(), (BlockMessage) msg); + type = InventoryType.BLOCK; + } else if (msg instanceof TransactionMessage) { + TrxCache.put(msg.getMessageId(), (TransactionMessage) msg); + type = InventoryType.TRX; + } else { + return; + } + synchronized (advObjToSpread) { + advObjToSpread.put(msg.getMessageId(), type); + } + } + + + + +} diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java index d9e3e192d45..d0b5388ad22 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -27,7 +27,7 @@ public class PeerSync { @Autowired private TronManager tronManager; - public void startSync(PeerConnection peer) throws Exception { + public void startSync(PeerConnection peer) { peer.setTronState(TronState.SYNCING); peer.setNeedSyncFromPeer(true); peer.getSyncBlockToFetch().clear(); @@ -36,7 +36,7 @@ public void startSync(PeerConnection peer) throws Exception { syncNext(peer); } - public void syncNext(PeerConnection peer) throws Exception { + public void syncNext(PeerConnection peer) { if (peer.getSyncChainRequested() != null) { logger.warn("Peer {} is in sync.", peer.getNode().getHost()); return; From 44283b7ccff49cd94c89973be1e6aa0fe7bcaa6c Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 6 Nov 2018 11:08:37 +0800 Subject: [PATCH 07/41] add invetory handler --- .../net/messagehandler/BlockMsgHandler.java | 2 +- .../messagehandler/InventoryMsgHandler.java | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 7c327afe5ad..b34cbc697c4 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -157,7 +157,7 @@ private void processAdvBlock(PeerConnection peer, BlockCapsule block) throws Ex if (freshBlockId.contains(blockId)) { return; } - if (!tronProxy.containBlock(block.getBlockId())) { + if (!tronProxy.containBlock(block.getParentBlockId())) { logger.warn("Get unlink block {} from {}, head is {}.", blockId.getString(), peer.getInetAddress(), tronProxy.getHeadBlockId().getString()); peerSync.startSync(peer); diff --git a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java new file mode 100644 index 00000000000..4df984beffa --- /dev/null +++ b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -0,0 +1,81 @@ +package org.tron.core.net.messagehandler; + +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.net.TronManager; +import org.tron.core.net.TronProxy; +import org.tron.core.net.message.InventoryMessage; +import org.tron.core.net.message.TronMessage; +import org.tron.core.net.node.NodeImpl.PriorItem; +import org.tron.core.net.peer.Item; +import org.tron.core.net.peer.PeerAdv; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerSync; +import org.tron.protos.Protocol.Inventory.InventoryType; + +@Slf4j +@Component +public class InventoryMsgHandler implements TronMsgHandler{ + + @Autowired + private TronProxy tronProxy; + + @Autowired + private PeerSync peerSync; + + @Autowired + private PeerAdv peerAdv; + + @Setter + private TronManager tronManager; + + @Autowired + private TransactionsMsgHandler transactionsMsgHandler; + + @Override + public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { + + InventoryMessage inventoryMessage = (InventoryMessage) msg; + InventoryType type = inventoryMessage.getInventoryType(); + + if (transactionsMsgHandler.isBusy() && type.equals(InventoryType.TRX)) { + logger.warn("Too many trx msg to handle, drop inventory msg from peer {}, size {}", + peer.getInetAddress(), inventoryMessage.getHashList().size()); + return; + } + for (Sha256Hash id : inventoryMessage.getHashList()) { + if (type.equals(InventoryType.TRX) && peerAdv.getTrxCache().getIfPresent(id) != null) { + logger.info("trx {} from peer {} Already exist.", id, peer.getNode().getHost()); + continue; + } + boolean spreadFlag = false; + boolean requestFlag = false; + for (PeerConnection p: tronProxy.getActivePeer()) { + if (p.getAdvObjWeSpread().containsKey(id)) { + spreadFlag = true; + } + if (p.getAdvObjWeRequested().containsKey(new Item(id, type))) { + requestFlag = true; + } + } + + if (!spreadFlag && !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) { + peer.getAdvObjSpreadToUs().put(id, System.currentTimeMillis()); + if (!requestFlag) { + PriorItem targetPriorItem = this.advObjToFetch.get(id); + if (targetPriorItem != null) { + //another peer tell this trx to us, refresh its time. + targetPriorItem.refreshTime(); + } else { + fetchWaterLine.increase(); + this.advObjToFetch.put(id, new PriorItem(new Item(id, msg.getInventoryType()), + fetchSequenceCounter.incrementAndGet())); + } + } + } + } + } +} From 56ceb8aa2179f605bd4320a970c9bd2f81f6002c Mon Sep 17 00:00:00 2001 From: wubin01 Date: Fri, 9 Nov 2018 11:40:26 +0800 Subject: [PATCH 08/41] add msg handler --- .../tron/common/overlay/server/Channel.java | 1 + .../common/overlay/server/ChannelManager.java | 2 + .../tron/common/overlay/server/SyncPool.java | 23 +- .../java/org/tron/core/config/Parameter.java | 2 +- .../org/tron/core/exception/P2pException.java | 11 +- .../java/org/tron/core/net/TronHandler.java | 17 +- .../java/org/tron/core/net/TronManager.java | 23 -- .../java/org/tron/core/net/TronNetClient.java | 18 ++ .../org/tron/core/net/TronNetService.java | 117 +++++++++ .../java/org/tron/core/net/TronProxy.java | 95 ++++++- .../net/messagehandler/BlockMsgHandler.java | 207 ++-------------- .../ChainInventoryMsgHandler.java | 20 +- .../FetchInvDataMsgHandler.java | 148 +++++++++++ .../messagehandler/InventoryMsgHandler.java | 42 ++-- .../TransactionsMsgHandler.java | 52 +++- .../java/org/tron/core/net/node/NodeImpl.java | 1 + .../java/org/tron/core/net/peer/Item.java | 12 +- .../java/org/tron/core/net/peer/PeerAdv.java | 230 ++++++++++++++++- .../tron/core/net/peer/PeerConnection.java | 93 +++---- .../java/org/tron/core/net/peer/PeerSync.java | 234 ++++++++++++++++-- 20 files changed, 978 insertions(+), 370 deletions(-) delete mode 100644 src/main/java/org/tron/core/net/TronManager.java create mode 100644 src/main/java/org/tron/core/net/TronNetClient.java create mode 100644 src/main/java/org/tron/core/net/TronNetService.java create mode 100644 src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java diff --git a/src/main/java/org/tron/common/overlay/server/Channel.java b/src/main/java/org/tron/common/overlay/server/Channel.java index 7ae943595bf..d92a5a6d2f9 100644 --- a/src/main/java/org/tron/common/overlay/server/Channel.java +++ b/src/main/java/org/tron/common/overlay/server/Channel.java @@ -248,6 +248,7 @@ public long getStartTime() { public void setTronState(TronState tronState) { this.tronState = tronState; + logger.info("Peer {} status change to {}.", inetSocketAddress, tronState); } public TronState getTronState() { diff --git a/src/main/java/org/tron/common/overlay/server/ChannelManager.java b/src/main/java/org/tron/common/overlay/server/ChannelManager.java index 794dbe0cbc5..e4782040fdb 100644 --- a/src/main/java/org/tron/common/overlay/server/ChannelManager.java +++ b/src/main/java/org/tron/common/overlay/server/ChannelManager.java @@ -68,6 +68,8 @@ private ChannelManager(final PeerServer peerServer, final PeerClient peerClient) trustPeers.put(new InetSocketAddress(node.getHost(), node.getPort()).getAddress(), node); } logger.info("Trust peer size {}", trustPeers.size()); + + syncPool.init(); } public void processDisconnect(Channel channel, ReasonCode reason) { diff --git a/src/main/java/org/tron/common/overlay/server/SyncPool.java b/src/main/java/org/tron/common/overlay/server/SyncPool.java index 5671db9d88a..310b9fd7281 100644 --- a/src/main/java/org/tron/common/overlay/server/SyncPool.java +++ b/src/main/java/org/tron/common/overlay/server/SyncPool.java @@ -70,8 +70,6 @@ public class SyncPool { private ChannelManager channelManager; - private PeerConnectionDelegate peerDel; - private Args args = Args.getInstance(); private int maxActiveNodes = args.getNodeMaxActiveNodes(); @@ -84,8 +82,7 @@ public class SyncPool { private PeerClient peerClient; - public void init(PeerConnectionDelegate peerDel) { - this.peerDel = peerDel; + public void init() { channelManager = ctx.getBean(ChannelManager.class); @@ -175,27 +172,29 @@ public synchronized List getActivePeers() { } public synchronized void onConnect(Channel peer) { - if (!activePeers.contains(peer)) { - if (!peer.isActive()) { + PeerConnection peerConnection = (PeerConnection) peer; + if (!activePeers.contains(peerConnection)) { + if (!peerConnection.isActive()) { passivePeersCount.incrementAndGet(); } else { activePeersCount.incrementAndGet(); } - activePeers.add((PeerConnection) peer); + activePeers.add(peerConnection); activePeers.sort(Comparator.comparingDouble(c -> c.getPeerStats().getAvgLatency())); - peerDel.onConnectPeer((PeerConnection) peer); + peerConnection.onConnectPeer(); } } public synchronized void onDisconnect(Channel peer) { - if (activePeers.contains(peer)) { - if (!peer.isActive()) { + PeerConnection peerConnection = (PeerConnection) peer; + if (activePeers.contains(peerConnection)) { + if (!peerConnection.isActive()) { passivePeersCount.decrementAndGet(); } else { activePeersCount.decrementAndGet(); } - activePeers.remove(peer); - peerDel.onDisconnectPeer((PeerConnection) peer); + activePeers.remove(peerConnection); + peerConnection.onDisconnectPeer(); } } diff --git a/src/main/java/org/tron/core/config/Parameter.java b/src/main/java/org/tron/core/config/Parameter.java index fd2c07ae09d..590dadc7c89 100644 --- a/src/main/java/org/tron/core/config/Parameter.java +++ b/src/main/java/org/tron/core/config/Parameter.java @@ -46,7 +46,7 @@ interface NetConstants { long HEAD_NUM_CHECK_TIME = 60000L; int MAX_INVENTORY_SIZE_IN_MINUTES = 2; long NET_MAX_TRX_PER_SECOND = 700L; - long MAX_TRX_PER_PEER = 200L; + long MAX_INV_FETCH_PER_PEER = 200L; int NET_MAX_INV_SIZE_IN_MINUTES = 2; int MSG_CACHE_DURATION_IN_BLOCKS = 5; } diff --git a/src/main/java/org/tron/core/exception/P2pException.java b/src/main/java/org/tron/core/exception/P2pException.java index eb689a3f3b6..31d1f0df921 100644 --- a/src/main/java/org/tron/core/exception/P2pException.java +++ b/src/main/java/org/tron/core/exception/P2pException.java @@ -9,6 +9,11 @@ public P2pException(TypeEnum type, String errMsg){ this.type = type; } + public P2pException(TypeEnum type, Throwable throwable){ + super(throwable); + this.type = type; + } + public P2pException(TypeEnum type, String errMsg, Throwable throwable){ super(errMsg, throwable); this.type = type; @@ -27,8 +32,10 @@ public enum TypeEnum { HARD_FORKED (6, "hard forked"), SYNC_FAILED (7, "sync failed"), CHECK_FAILED (8, "check failed"), - BAD_BLOCK (9, "bad block"), - UNLINK_BLOCK (10, "unlink block"), + UNLINK_BLOCK (9, "unlink block"), + BAD_BLOCK (10, "bad block"), + BAD_TRX (11, "bad trx"), + TRX_EXE_FAILED (12, "trx exe failed"), DEFAULT (100, "default exception"); private Integer value; diff --git a/src/main/java/org/tron/core/net/TronHandler.java b/src/main/java/org/tron/core/net/TronHandler.java index 09986d5a3f4..52f7cb579ba 100644 --- a/src/main/java/org/tron/core/net/TronHandler.java +++ b/src/main/java/org/tron/core/net/TronHandler.java @@ -2,6 +2,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.tron.common.overlay.server.Channel; @@ -16,22 +18,19 @@ public class TronHandler extends SimpleChannelInboundHandler { protected PeerConnection peer; - private MessageQueue msgQueue = null; + private MessageQueue msgQueue; - public PeerConnectionDelegate peerDel; + private TronNetService tronNetService; - public void setPeerDel(PeerConnectionDelegate peerDel) { - this.peerDel = peerDel; + @Autowired + private TronHandler (final ApplicationContext ctx){ + tronNetService = ctx.getBean(TronNetService.class); } @Override public void channelRead0(final ChannelHandlerContext ctx, TronMessage msg) { - if (!peer.isDisconnect()) { - logger.warn("Received a block {} from disconnect peer {}", blockId.getNum(), peer.getNode().getHost()); - return; - } msgQueue.receivedMessage(msg); - peerDel.onMessage(peer, msg); + tronNetService.onMessage(peer, msg); } @Override diff --git a/src/main/java/org/tron/core/net/TronManager.java b/src/main/java/org/tron/core/net/TronManager.java deleted file mode 100644 index a3707afc6fd..00000000000 --- a/src/main/java/org/tron/core/net/TronManager.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.tron.core.net; - -import lombok.Getter; -import lombok.Setter; -import org.tron.core.exception.P2pException; -import org.tron.core.exception.P2pException.TypeEnum; - -public class TronManager { - - @Getter - private Object blockLock; - - @Setter - @Getter - private boolean syncBlockFetchFlag; - - public void check (boolean flag, String msg) throws Exception { - if (!flag){ - throw new P2pException(TypeEnum.CHECK_FAILED, msg); - } - } - -} diff --git a/src/main/java/org/tron/core/net/TronNetClient.java b/src/main/java/org/tron/core/net/TronNetClient.java new file mode 100644 index 00000000000..14b383ddd2a --- /dev/null +++ b/src/main/java/org/tron/core/net/TronNetClient.java @@ -0,0 +1,18 @@ +package org.tron.core.net; + +import lombok.Getter; +import org.springframework.stereotype.Component; +import org.tron.common.overlay.message.Message; +import org.tron.core.net.peer.PeerAdv; + +@Component +public class TronNetClient { + + @Getter + private PeerAdv peerAdv; + + public void broadcast(Message msg) { + peerAdv.broadcast(msg); + } + +} diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java new file mode 100644 index 00000000000..d8677cd5607 --- /dev/null +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -0,0 +1,117 @@ +package org.tron.core.net; + +import io.netty.channel.ChannelInboundHandler; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; +import org.tron.core.net.message.TronMessage; +import org.tron.core.net.messagehandler.BlockMsgHandler; +import org.tron.core.net.messagehandler.FetchInvDataMsgHandler; +import org.tron.core.net.messagehandler.InventoryMsgHandler; +import org.tron.core.net.messagehandler.SyncBlockChainMsgHadler; +import org.tron.core.net.messagehandler.TransactionsMsgHandler; +import org.tron.core.net.peer.PeerAdv; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerSync; +import org.tron.protos.Protocol.ReasonCode; + +@Slf4j +@Component +public class TronNetService { + + @Autowired + private PeerAdv peerAdv; + + @Autowired + private PeerSync peerSync; + + @Autowired + private BlockMsgHandler blockMsgHandler; + + @Autowired + private ChannelInboundHandler channelInboundHandler; + + @Autowired + private FetchInvDataMsgHandler fetchInvDataMsgHandler; + + @Autowired + private InventoryMsgHandler inventoryMsgHandler; + + @Autowired + private SyncBlockChainMsgHadler syncBlockChainMsgHadler; + + @Autowired + private TransactionsMsgHandler transactionsMsgHandler; + + public void start () { + peerAdv.init(); + peerSync.init(); + transactionsMsgHandler.init(); + } + + public void onMessage(PeerConnection peer, TronMessage msg) { + try { + switch (msg.getType()) { + case BLOCK: + blockMsgHandler.processMessage(peer, msg); + break; + case TRXS: + transactionsMsgHandler.processMessage(peer, msg); + break; + case SYNC_BLOCK_CHAIN: + syncBlockChainMsgHadler.processMessage(peer, msg); + break; + case FETCH_INV_DATA: + fetchInvDataMsgHandler.processMessage(peer, msg); + break; + case BLOCK_CHAIN_INVENTORY: + syncBlockChainMsgHadler.processMessage(peer, msg); + break; + case INVENTORY: + inventoryMsgHandler.processMessage(peer, msg); + break; + default: + throw new P2pException(TypeEnum.NO_SUCH_MESSAGE, "No such message"); + } + }catch (Exception e) { + processException(peer, msg, e); + } + } + + private void processException (PeerConnection peer, TronMessage msg, Exception ex) { + + ReasonCode code = null; + if (ex instanceof P2pException) { + TypeEnum type = ((P2pException) ex).getType(); + switch (type) { + case BAD_TRX: + code = ReasonCode.BAD_TX; + break; + case BAD_BLOCK: + code = ReasonCode.BAD_BLOCK; + break; + case NO_SUCH_MESSAGE: + case MESSAGE_WITH_WRONG_LENGTH: + case BAD_MESSAGE: + code = ReasonCode.BAD_PROTOCOL; + break; + case SYNC_FAILED: + code = ReasonCode.SYNC_FAIL; + break; + case UNLINK_BLOCK: + code = ReasonCode.UNLINKABLE; + break; + case DEFAULT: + code = ReasonCode.UNLINKABLE; + break; + } + logger.error("Process {} from peer {} failed, reason: ", peer.getInetAddress(), msg.getType(), type.getDesc(), ex); + }else { + logger.error("Process {} from peer {} failed.", peer.getInetAddress(), msg.getType(), ex); + code = ReasonCode.UNKNOWN; + } + peer.disconnect(code); + } +} diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronProxy.java index 625247f794e..7aa6f39c0fa 100644 --- a/src/main/java/org/tron/core/net/TronProxy.java +++ b/src/main/java/org/tron/core/net/TronProxy.java @@ -2,6 +2,9 @@ import java.util.Collection; import java.util.LinkedList; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -12,13 +15,33 @@ import org.tron.core.capsule.BlockCapsule.BlockId; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.db.Manager; +import org.tron.core.exception.AccountResourceInsufficientException; +import org.tron.core.exception.BadBlockException; import org.tron.core.exception.BadItemException; +import org.tron.core.exception.BadNumberBlockException; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractSizeNotEqualToOneException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.DupTransactionException; import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.exception.NonCommonBlockException; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; +import org.tron.core.exception.ReceiptCheckErrException; import org.tron.core.exception.StoreException; +import org.tron.core.exception.TaposException; +import org.tron.core.exception.TooBigTransactionException; +import org.tron.core.exception.TooBigTransactionResultException; +import org.tron.core.exception.TransactionExpirationException; +import org.tron.core.exception.UnLinkedBlockException; +import org.tron.core.exception.VMIllegalException; +import org.tron.core.exception.ValidateScheduleException; +import org.tron.core.exception.ValidateSignatureException; import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.MessageTypes; import org.tron.core.net.message.TransactionMessage; import org.tron.core.net.peer.PeerConnection; +import org.tron.protos.Protocol.Inventory.InventoryType; @Slf4j @Component @@ -30,6 +53,19 @@ public class TronProxy { @Autowired private Manager dbManager; + @Getter + private Object blockLock; + + private Queue freshBlockId = new ConcurrentLinkedQueue() { + @Override + public boolean offer(BlockId blockId) { + if (size() > 200) { + super.poll(); + } + return super.offer(blockId); + } + }; + public Collection getActivePeer() { return syncPool.getActivePeers(); } @@ -48,14 +84,6 @@ public long getBlockTime(BlockId id) { } } - public void preValidateTransactionSign (BlockCapsule block) throws Exception { - dbManager.preValidateTransactionSign(block); - } - - public void pushBlock (BlockCapsule block) throws Exception { - dbManager.pushBlock(block); - } - public BlockId getHeadBlockId() { return dbManager.getHeadBlockId(); } @@ -103,7 +131,7 @@ public boolean contain(Sha256Hash hash, MessageTypes type) { return false; } - public Message getData(Sha256Hash hash, MessageTypes type) throws StoreException { + public Message getData(Sha256Hash hash, InventoryType type) throws StoreException { switch (type) { case BLOCK: return new BlockMessage(dbManager.getBlockById(hash)); @@ -118,4 +146,53 @@ public Message getData(Sha256Hash hash, MessageTypes type) throws StoreException } } + public void processBlock(BlockCapsule block) throws Exception { + synchronized (blockLock) { + try { + if (freshBlockId.contains(block.getBlockId())) { + dbManager.preValidateTransactionSign(block); + dbManager.pushBlock(block); + freshBlockId.add(block.getBlockId()); + logger.info("Success process block {}.", block.getBlockId().getString()); + } + } catch (ValidateSignatureException + | ContractValidateException + | ContractExeException + | UnLinkedBlockException + | ValidateScheduleException + | AccountResourceInsufficientException + | TaposException + | TooBigTransactionException + | TooBigTransactionResultException + | DupTransactionException + | TransactionExpirationException + | BadNumberBlockException + | BadBlockException + | NonCommonBlockException + | ReceiptCheckErrException + | VMIllegalException e) { + throw new P2pException(TypeEnum.BAD_BLOCK, e); + } + } + } + + public void pushTransaction (TransactionCapsule trx) throws Exception { + try { + dbManager.pushTransaction(trx); + } catch (ContractSizeNotEqualToOneException + | ValidateSignatureException + | VMIllegalException e) { + throw new P2pException(TypeEnum.BAD_TRX, e); + } catch (ContractValidateException + | ContractExeException + | DupTransactionException + | TaposException + | TooBigTransactionException + | TransactionExpirationException + | ReceiptCheckErrException + | TooBigTransactionResultException + | AccountResourceInsufficientException e) { + throw new P2pException(TypeEnum.TRX_EXE_FAILED, e); + } + } } diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index b34cbc697c4..56ea01b270c 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -3,56 +3,23 @@ import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import static org.tron.core.config.Parameter.ChainConstant.BLOCK_SIZE; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.Executors; -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.utils.Sha256Hash; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BlockCapsule.BlockId; -import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.config.Parameter.NodeConstant; -import org.tron.core.exception.AccountResourceInsufficientException; -import org.tron.core.exception.BadBlockException; -import org.tron.core.exception.BadNumberBlockException; -import org.tron.core.exception.ContractExeException; -import org.tron.core.exception.ContractValidateException; -import org.tron.core.exception.DupTransactionException; -import org.tron.core.exception.NonCommonBlockException; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.exception.ReceiptCheckErrException; -import org.tron.core.exception.TaposException; -import org.tron.core.exception.TooBigTransactionException; -import org.tron.core.exception.TooBigTransactionResultException; -import org.tron.core.exception.TransactionExpirationException; -import org.tron.core.exception.UnLinkedBlockException; -import org.tron.core.exception.VMIllegalException; -import org.tron.core.exception.ValidateScheduleException; -import org.tron.core.exception.ValidateSignatureException; -import org.tron.core.net.TronManager; +import org.tron.core.net.TronNetClient; import org.tron.core.net.TronProxy; import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.message.ChainInventoryMessage; import org.tron.core.net.message.TronMessage; -import org.tron.core.net.node.NodeImpl.PriorItem; import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerAdv; import org.tron.core.net.peer.PeerConnection; import org.tron.core.net.peer.PeerSync; import org.tron.core.services.WitnessProductBlockService; import org.tron.protos.Protocol.Inventory.InventoryType; -import org.tron.protos.Protocol.ReasonCode; @Slf4j @Component @@ -62,7 +29,7 @@ public class BlockMsgHandler implements TronMsgHandler { private TronProxy tronProxy; @Autowired - private TronManager tronManager; + private TronNetClient tronManager; @Autowired private PeerAdv peerAdv; @@ -73,39 +40,6 @@ public class BlockMsgHandler implements TronMsgHandler { @Autowired private WitnessProductBlockService witnessProductBlockService; - private Map blockWaitToProc = new ConcurrentHashMap<>(); - - private Map blockJustReceived = new ConcurrentHashMap<>(); - - private HashMap advObjWeRequested = new HashMap<>(); - - private Queue freshBlockId = new ConcurrentLinkedQueue() { - @Override - public boolean offer(BlockId blockId) { - if (size() > 200) { - super.poll(); - } - return super.offer(blockId); - } - }; - - private ScheduledExecutorService syncHandleExecutor = Executors.newSingleThreadScheduledExecutor(); - - private boolean syncHandleFlag; - - public void init () { - syncHandleExecutor.scheduleWithFixedDelay(() -> { - try { - if (syncHandleFlag) { - syncHandleFlag = false; - handleSyncBlock(); - } - } catch (Throwable t) { - logger.error("Unhandled exception", t); - } - }, 10, 1, TimeUnit.SECONDS); - } - @Override public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { @@ -117,24 +51,13 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti Item item = new Item(blockId, InventoryType.BLOCK); boolean syncFlag = false; if (peer.getSyncBlockRequested().containsKey(blockId)) { - peer.getSyncBlockRequested().remove(blockId); - synchronized (blockJustReceived) { - blockJustReceived.put(blockMessage, peer); - } - syncHandleFlag = true; + peerSync.processBlock(peer, blockMessage); syncFlag = true; - if (!peer.isBusy()) { - if (peer.getUnfetchSyncNum() > 0 && peer.getSyncBlockToFetch().size() <= NodeConstant.SYNC_FETCH_BATCH_NUM) { - peerSync.syncNext(peer); - } else { - tronManager.setSyncBlockFetchFlag(true); - } - } } - if (peer.getAdvObjWeRequested().containsKey(item)) { - peer.getAdvObjWeRequested().remove(item); + if (peer.getAdvInvRequest().containsKey(item)) { + peer.getAdvInvRequest().remove(item); if (!syncFlag) { - processAdvBlock(peer, blockMessage.getBlockCapsule()); + processBlock(peer, blockMessage.getBlockCapsule()); } } } @@ -144,118 +67,28 @@ private void check (PeerConnection peer, BlockMessage msg) throws Exception { if (blockCapsule.getInstance().getSerializedSize() > BLOCK_SIZE + 100) { throw new P2pException(TypeEnum.BAD_MESSAGE, "block size over limit"); } - long gap = blockCapsule.getTimeStamp() - System.currentTimeMillis(); if (gap >= BLOCK_PRODUCED_INTERVAL) { throw new P2pException(TypeEnum.BAD_MESSAGE, "block time error"); } } - private void processAdvBlock(PeerConnection peer, BlockCapsule block) throws Exception { - synchronized (tronManager.getBlockLock()) { - BlockId blockId = block.getBlockId(); - if (freshBlockId.contains(blockId)) { - return; - } - if (!tronProxy.containBlock(block.getParentBlockId())) { - logger.warn("Get unlink block {} from {}, head is {}.", blockId.getString(), - peer.getInetAddress(), tronProxy.getHeadBlockId().getString()); - peerSync.startSync(peer); - return; - } - witnessProductBlockService.validWitnessProductTwoBlock(block); - handleBlock(block); - //trxIds.forEach(trxId -> advObjToFetch.remove(trxId)); - tronProxy.getActivePeer().forEach(p -> { - if (p.getAdvObjSpreadToUs().containsKey(blockId)) { - p.setHeadBlockWeBothHave(blockId); - } - }); - peerAdv.broadcast(new BlockMessage(block)); + private void processBlock(PeerConnection peer, BlockCapsule block) throws Exception { + BlockId blockId = block.getBlockId(); + if (!tronProxy.containBlock(block.getParentBlockId())) { + logger.warn("Get unlink block {} from {}, head is {}.", blockId.getString(), peer.getInetAddress(), tronProxy.getHeadBlockId().getString()); + peerSync.startSync(peer); + return; } - } - - private void processSyncBlock (BlockCapsule block) { - synchronized (tronManager.getBlockLock()) { - boolean flag = true; - BlockId blockId = block.getBlockId(); - if (!freshBlockId.contains(blockId)) { - try { - handleBlock(block); - } catch (Exception e) { - logger.error("Process sync block failed.", e); - flag = false; - } - } - for (PeerConnection peer: tronProxy.getActivePeer()) { - if (peer.getBlockInProc().remove(blockId)) { - if (flag){ - peer.setHeadBlockWeBothHave(blockId); - if (peer.getSyncBlockToFetch().isEmpty()) { - peerSync.syncNext(peer); - } - }else { - peer.disconnect(ReasonCode.BAD_BLOCK); - } - } + tronProxy.processBlock(block); + witnessProductBlockService.validWitnessProductTwoBlock(block); + //trxIds.forEach(trxId -> advObjToFetch.remove(trxId)); + tronProxy.getActivePeer().forEach(p -> { + if (p.getAdvInvReceive().containsKey(blockId)) { + p.setBlockBothHave(blockId); } - syncHandleFlag = true; - } - } - - - private void handleBlock(BlockCapsule block) throws Exception { - try { - tronProxy.preValidateTransactionSign(block); - tronProxy.pushBlock(block); - freshBlockId.add(block.getBlockId()); - }catch (UnLinkedBlockException e){ - throw new P2pException(TypeEnum.UNLINK_BLOCK, block.getBlockId().getString(), e); - }catch (Exception e){ - throw new P2pException(TypeEnum.BAD_BLOCK, block.getBlockId().getString(), e); - } - } - - private synchronized void handleSyncBlock() { - - synchronized (blockJustReceived) { - blockWaitToProc.putAll(blockJustReceived); - blockJustReceived.clear(); - } - - final boolean[] isBlockProc = {true}; - - while (isBlockProc[0]) { - - isBlockProc[0] = false; - - blockWaitToProc.forEach((msg, peerConnection) -> { - if (peerConnection.isDisconnect()) { - logger.error("Peer {} is disconnect, drop block {}", peerConnection.getInetAddress(), msg.getBlockId().getString()); - blockWaitToProc.remove(msg); - syncBlockIdWeRequested.invalidate(msg.getBlockId()); - isFetchSyncActive = true; - isBlockProc[0] = true; - return; - } - synchronized (freshBlockId) { - final boolean[] isFound = {false}; - tronProxy.getActivePeer().stream() - .filter(peer -> !peer.getSyncBlockToFetch().isEmpty() && - peer.getSyncBlockToFetch().peek().equals(msg.getBlockId())) - .forEach(peer -> { - peer.getSyncBlockToFetch().pop(); - peer.getBlockInProc().add(msg.getBlockId()); - isFound[0] = true; - }); - if (isFound[0]) { - blockWaitToProc.remove(msg); - isBlockProc[0] = true; - processSyncBlock(msg.getBlockCapsule()); - } - } - }); - } + }); + peerAdv.broadcast(new BlockMessage(block)); } } diff --git a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java index b393e320ffb..1b22817510d 100644 --- a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -15,7 +15,7 @@ import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.net.TronManager; +import org.tron.core.net.TronNetClient; import org.tron.core.net.TronProxy; import org.tron.core.net.message.ChainInventoryMessage; import org.tron.core.net.message.TronMessage; @@ -33,7 +33,7 @@ public class ChainInventoryMsgHandler implements TronMsgHandler { private PeerSync peerSync; @Setter - private TronManager tronManager; + private TronNetClient tronManager; @Override public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { @@ -50,10 +50,6 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti if (blockIdWeGet.size() == 1 && tronProxy.containBlock(blockIdWeGet.peek())) { peer.setNeedSyncFromPeer(false); -// unSyncNum = getUnSyncNum(); -// if (unSyncNum == 0) { -// del.syncToCli(0); -// } return; } @@ -66,10 +62,10 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti blockIdWeGet.poll(); - peer.setUnfetchSyncNum(chainInventoryMessage.getRemainNum()); + peer.setRemainNum(chainInventoryMessage.getRemainNum()); peer.getSyncBlockToFetch().addAll(blockIdWeGet); - synchronized (tronManager.getBlockLock()) { + synchronized (tronProxy.getBlockLock()) { while (!peer.getSyncBlockToFetch().isEmpty() && tronProxy.containBlock(peer.getSyncBlockToFetch().peek())) { BlockId blockId = peer.getSyncBlockToFetch().pop(); logger.info("Block {} from {} is processed", blockId.getString(), peer.getNode().getHost()); @@ -80,15 +76,9 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti peer.setNeedSyncFromPeer(false); } -// long newUnSyncNum = getUnSyncNum(); -// if (unSyncNum != newUnSyncNum) { -// unSyncNum = newUnSyncNum; -// del.syncToCli(unSyncNum); -// } - if ((chainInventoryMessage.getRemainNum() == 0 && !peer.getSyncBlockToFetch().isEmpty()) || (chainInventoryMessage.getRemainNum() != 0 && peer.getSyncBlockToFetch().size() > NodeConstant.SYNC_FETCH_BATCH_NUM)) { - tronManager.setSyncBlockFetchFlag(true); + peerSync.setFetchFlag(true); }else { peerSync.syncNext(peer); } diff --git a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java new file mode 100644 index 00000000000..45768cc089f --- /dev/null +++ b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -0,0 +1,148 @@ +package org.tron.core.net.messagehandler; + +import com.google.common.collect.Lists; +import java.util.List; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.common.overlay.discover.node.statistics.MessageCount; +import org.tron.common.overlay.message.Message; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.config.Parameter.ChainConstant; +import org.tron.core.config.Parameter.NodeConstant; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; +import org.tron.core.net.TronProxy; +import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.message.FetchInvDataMessage; +import org.tron.core.net.message.MessageTypes; +import org.tron.core.net.message.TransactionMessage; +import org.tron.core.net.message.TransactionsMessage; +import org.tron.core.net.message.TronMessage; +import org.tron.core.net.peer.Item; +import org.tron.core.net.peer.PeerAdv; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerSync; +import org.tron.protos.Protocol.Inventory.InventoryType; +import org.tron.protos.Protocol.ReasonCode; +import org.tron.protos.Protocol.Transaction; + +@Slf4j +@Component +public class FetchInvDataMsgHandler implements TronMsgHandler { + + @Autowired + private TronProxy tronProxy; + + @Autowired + private PeerSync peerSync; + + @Setter + private PeerAdv peerAdv; + + private int MAX_SIZE = 1_000_000; + + private int MAX_COUNT = 200; + + @Override + public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { + + FetchInvDataMessage fetchInvDataMsg = (FetchInvDataMessage) msg; + + checkFetchInvDataMsg(peer, fetchInvDataMsg); + + InventoryType type = fetchInvDataMsg.getInventoryType(); + List transactions = Lists.newArrayList(); + + int size = 0; + + for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { + Item item = new Item(hash, type); + Message message = peerAdv.getMessage(item); + if (message == null) { + try { + message = tronProxy.getData(hash, type); + } catch (Exception e) { + logger.error("Fetch item {} failed. reason: {}", item, hash, e.getMessage()); + peer.disconnect(ReasonCode.FETCH_FAIL); + return; + } + } + + if (type.equals(InventoryType.BLOCK)) { + BlockId blockId = ((BlockMessage) message).getBlockCapsule().getBlockId(); + if (peer.getBlockBothHave().getNum() < blockId.getNum()) { + peer.setBlockBothHave(blockId); + } + peer.sendMessage(message); + } else { + transactions.add(((TransactionMessage) message).getTransactionCapsule().getInstance()); + size += ((TransactionMessage) message).getTransactionCapsule().getInstance().getSerializedSize(); + if (size > MAX_SIZE) { + peer.sendMessage(new TransactionsMessage(transactions)); + transactions = Lists.newArrayList(); + size = 0; + } + } + } + if (transactions.size() > 0) { + peer.sendMessage(new TransactionsMessage(transactions)); + } + } + + private void checkFetchInvDataMsg(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) throws Exception{ + MessageTypes type = fetchInvDataMsg.getInvMessageType(); + + //todo check inv size not gt MAX_INV_FETCH_PER_PEER + + if (type == MessageTypes.TRX) { + int fetchCount = peer.getNodeStatistics().messageStatistics.tronInTrxFetchInvDataElement + .getCount(10); + int maxCount = peerAdv.getTrxCount().getCount(60); + if (fetchCount > maxCount) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "maxCount: " + maxCount + ", fetchCount: " + fetchCount); + } + for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { + if (!peer.getAdvInvSpread().containsKey(hash)) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "not spread inv: {}" + hash); + } + } + } else { + boolean isAdv = true; + for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { + if (!peer.getAdvInvSpread().containsKey(hash)) { + isAdv = false; + break; + } + } + if (isAdv) { + MessageCount tronOutAdvBlock = peer.getNodeStatistics().messageStatistics.tronOutAdvBlock; + tronOutAdvBlock.add(fetchInvDataMsg.getHashList().size()); + int outBlockCountIn1min = tronOutAdvBlock.getCount(60); + int producedBlockIn2min = 120_000 / ChainConstant.BLOCK_PRODUCED_INTERVAL; + if (outBlockCountIn1min > producedBlockIn2min) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "producedBlockIn2min: " + producedBlockIn2min + + ", outBlockCountIn1min: " + outBlockCountIn1min); + } + } else { + if (!peer.isNeedSyncFromUs()) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "no need sync"); + } + for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { + long blockNum = new BlockId(hash).getNum(); + long minBlockNum = peer.getLastSyncBlockId().getNum() - 2 * NodeConstant.SYNC_FETCH_BATCH_NUM; + if (blockNum < minBlockNum) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "minBlockNum: " + minBlockNum + ", blockNum: " + blockNum); + } + if (peer.getSyncBlockIdCache().getIfPresent(hash) != null) { + throw new P2pException(TypeEnum.BAD_MESSAGE, new BlockId(hash).getString() + " is exist"); + } + peer.getSyncBlockIdCache().put(hash, System.currentTimeMillis()); + } + } + } + } + +} diff --git a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index 4df984beffa..b4facd78a43 100644 --- a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -1,19 +1,15 @@ package org.tron.core.net.messagehandler; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.utils.Sha256Hash; -import org.tron.core.net.TronManager; import org.tron.core.net.TronProxy; import org.tron.core.net.message.InventoryMessage; import org.tron.core.net.message.TronMessage; -import org.tron.core.net.node.NodeImpl.PriorItem; import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerAdv; import org.tron.core.net.peer.PeerConnection; -import org.tron.core.net.peer.PeerSync; import org.tron.protos.Protocol.Inventory.InventoryType; @Slf4j @@ -23,18 +19,14 @@ public class InventoryMsgHandler implements TronMsgHandler{ @Autowired private TronProxy tronProxy; - @Autowired - private PeerSync peerSync; - @Autowired private PeerAdv peerAdv; - @Setter - private TronManager tronManager; - @Autowired private TransactionsMsgHandler transactionsMsgHandler; + private int maxCountIn10s = 10_000; + @Override public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { @@ -46,33 +38,31 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti peer.getInetAddress(), inventoryMessage.getHashList().size()); return; } + + int count = peer.getNodeStatistics().messageStatistics.tronInTrxInventoryElement.getCount(10); + if (count > maxCountIn10s) { + logger.warn("Inv is overload from peer {}, size {}", peer.getInetAddress(), count); + return; + } + for (Sha256Hash id : inventoryMessage.getHashList()) { - if (type.equals(InventoryType.TRX) && peerAdv.getTrxCache().getIfPresent(id) != null) { - logger.info("trx {} from peer {} Already exist.", id, peer.getNode().getHost()); - continue; - } + Item item = new Item(id, type); boolean spreadFlag = false; boolean requestFlag = false; for (PeerConnection p: tronProxy.getActivePeer()) { - if (p.getAdvObjWeSpread().containsKey(id)) { + if (p.getAdvInvSpread().containsKey(item)) { spreadFlag = true; } - if (p.getAdvObjWeRequested().containsKey(new Item(id, type))) { + if (p.getAdvInvRequest().containsKey(item)) { requestFlag = true; } } - if (!spreadFlag && !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) { - peer.getAdvObjSpreadToUs().put(id, System.currentTimeMillis()); + peer.getAdvInvReceive().put(item, System.currentTimeMillis()); if (!requestFlag) { - PriorItem targetPriorItem = this.advObjToFetch.get(id); - if (targetPriorItem != null) { - //another peer tell this trx to us, refresh its time. - targetPriorItem.refreshTime(); - } else { - fetchWaterLine.increase(); - this.advObjToFetch.put(id, new PriorItem(new Item(id, msg.getInventoryType()), - fetchSequenceCounter.incrementAndGet())); + if (!peerAdv.addInv(item)) { + logger.info("This item {} from peer {} Already exist.", item, peer.getInetAddress()); + continue; } } } diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index f5288bd54d4..faa07b8f78c 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -9,10 +9,26 @@ import java.util.concurrent.TimeUnit; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.args.Args; +import org.tron.core.exception.AccountResourceInsufficientException; +import org.tron.core.exception.BadTransactionException; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractSizeNotEqualToOneException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.DupTransactionException; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; +import org.tron.core.exception.ReceiptCheckErrException; +import org.tron.core.exception.TaposException; +import org.tron.core.exception.TooBigTransactionException; +import org.tron.core.exception.TooBigTransactionResultException; +import org.tron.core.exception.TransactionExpirationException; +import org.tron.core.exception.VMIllegalException; +import org.tron.core.exception.ValidateSignatureException; +import org.tron.core.net.TronProxy; import org.tron.core.net.message.TransactionMessage; import org.tron.core.net.message.TransactionsMessage; import org.tron.core.net.message.TronMessage; @@ -20,6 +36,7 @@ import org.tron.core.net.node.NodeImpl; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Inventory.InventoryType; +import org.tron.protos.Protocol.ReasonCode; import org.tron.protos.Protocol.Transaction; import org.tron.protos.Protocol.Transaction.Contract.ContractType; @@ -27,7 +44,8 @@ @Component public class TransactionsMsgHandler implements TronMsgHandler { - private NodeImpl nodeImpl; + @Autowired + private TronProxy tronProxy; private static int MAX_TRX_SIZE = 10_000; @@ -60,8 +78,7 @@ public TrxEvent(PeerConnection peer, TransactionMessage msg) { } } - public void init(NodeImpl nodeImpl) { - this.nodeImpl = nodeImpl; + public void init() { handleSmartContract(); } @@ -71,11 +88,8 @@ public boolean isBusy() { @Override public void processMessage(PeerConnection peer, TronMessage msg) throws Exception { - TransactionsMessage transactionsMessage = (TransactionsMessage) msg; - check (peer, transactionsMessage); - for (Transaction trx : transactionsMessage.getTransactions().getTransactionsList()) { int type = trx.getRawData().getContract(0).getType().getNumber(); if (type == ContractType.TriggerSmartContract_VALUE || type == ContractType.CreateSmartContract_VALUE) { @@ -83,7 +97,7 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws Exceptio logger.warn("Add smart contract failed, queueSize {}:{}", smartContractQueue.size(), queue.size()); } } else { - trxHandlePool.submit(() -> nodeImpl.onHandleTransactionMessage(peer, new TransactionMessage(trx))); + trxHandlePool.submit(() -> handleTransaction(peer, new TransactionMessage(trx))); } } } @@ -91,10 +105,10 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws Exceptio private void check(PeerConnection peer, TransactionsMessage msg) throws Exception { for (Transaction trx : msg.getTransactions().getTransactionsList()) { Item item = new Item(new TransactionMessage(trx).getMessageId(), InventoryType.TRX); - if (!peer.getAdvObjWeRequested().containsKey(item)) { + if (!peer.getAdvInvRequest().containsKey(item)) { throw new P2pException(TypeEnum.BAD_MESSAGE, "trx: " + msg.getMessageId() + " without request."); } - peer.getAdvObjWeRequested().remove(item); + peer.getAdvInvRequest().remove(item); } } @@ -107,7 +121,7 @@ private void handleSmartContract() { logger.warn("Drop smart contract {} from peer {}."); continue; } - trxHandlePool.submit(() -> nodeImpl.onHandleTransactionMessage(event.getPeer(), event.getMsg())); + trxHandlePool.submit(() -> handleTransaction(event.getPeer(), event.getMsg())); } } catch (Exception e) { logger.error("Handle smart contract exception", e); @@ -115,4 +129,22 @@ private void handleSmartContract() { }, 1000, 20, TimeUnit.MILLISECONDS); } + private boolean handleTransaction (PeerConnection peer, TransactionMessage trx) { + if (peer.isDisconnect()) { + logger.warn("Peer {} is disconnect, drop trx {}", peer.getInetAddress(), trx.getMessageId()); + return false; + } + try { + tronProxy.pushTransaction(trx.getTransactionCapsule()); + return true; + }catch (P2pException e) { + logger.warn("Trx {} from peer {} process failed. type: {}", trx.getMessageId(), peer.getInetAddress(), e.getType(), e); + if (e.getType().equals(TypeEnum.BAD_TRX)) { + peer.disconnect(ReasonCode.BAD_TX); + } + }catch (Exception e) { + logger.warn("Trx {} from peer {} process failed.", trx.getMessageId(), peer.getInetAddress(), e); + } + return false; + } } \ No newline at end of file diff --git a/src/main/java/org/tron/core/net/node/NodeImpl.java b/src/main/java/org/tron/core/net/node/NodeImpl.java index 05aed818465..a07696a2e26 100644 --- a/src/main/java/org/tron/core/net/node/NodeImpl.java +++ b/src/main/java/org/tron/core/net/node/NodeImpl.java @@ -1330,6 +1330,7 @@ public void onDisconnectPeer(PeerConnection peer) { } } + public void shutDown() { logExecutor.shutdown(); trxsHandlePool.shutdown(); diff --git a/src/main/java/org/tron/core/net/peer/Item.java b/src/main/java/org/tron/core/net/peer/Item.java index 74a55e15c59..03155ad6acd 100644 --- a/src/main/java/org/tron/core/net/peer/Item.java +++ b/src/main/java/org/tron/core/net/peer/Item.java @@ -7,13 +7,18 @@ @Getter public class Item { + @Getter private Sha256Hash hash; - + @Getter private InventoryType type; + @Getter + private long time; + public Item(Sha256Hash hash, InventoryType type) { this.hash = hash; this.type = type; + this.time = System.currentTimeMillis(); } @Override @@ -33,4 +38,9 @@ public boolean equals(Object o) { public int hashCode() { return hash.hashCode(); } + + @Override + public String toString() { + return type + ":" + hash; + } } diff --git a/src/main/java/org/tron/core/net/peer/PeerAdv.java b/src/main/java/org/tron/core/net/peer/PeerAdv.java index e0ee5b37826..1afed0335dd 100644 --- a/src/main/java/org/tron/core/net/peer/PeerAdv.java +++ b/src/main/java/org/tron/core/net/peer/PeerAdv.java @@ -1,15 +1,34 @@ package org.tron.core.net.peer; +import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; +import static org.tron.core.config.Parameter.NetConstants.MAX_INV_FETCH_PER_PEER; +import static org.tron.core.config.Parameter.NetConstants.MSG_CACHE_DURATION_IN_BLOCKS; + import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.overlay.discover.node.statistics.MessageCount; import org.tron.common.overlay.message.Message; import org.tron.common.utils.Sha256Hash; +import org.tron.common.utils.Time; +import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.net.TronProxy; import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.message.FetchInvDataMessage; +import org.tron.core.net.message.InventoryMessage; import org.tron.core.net.message.TransactionMessage; import org.tron.protos.Protocol.Inventory.InventoryType; @@ -17,36 +36,223 @@ @Component public class PeerAdv { + @Autowired + private TronProxy tronProxy; + + private ConcurrentHashMap advObjToFetch = new ConcurrentHashMap<>(); + + private ConcurrentHashMap advObjToSpread = new ConcurrentHashMap<>(); + + private Cache messageCache = CacheBuilder.newBuilder() + .maximumSize(100_000).expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); + +// private Cache trxCache = CacheBuilder.newBuilder() +// .maximumSize(50_000).expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(50_000) +// .recordStats().build(); +// +// private Cache blockCache = CacheBuilder.newBuilder() +// .maximumSize(10).expireAfterWrite(60, TimeUnit.SECONDS) +// .recordStats().build(); + + private ScheduledExecutorService spreadExecutor = Executors.newSingleThreadScheduledExecutor(); + + private ScheduledExecutorService fetchExecutor = Executors.newSingleThreadScheduledExecutor(); + @Getter - private Cache TrxCache = CacheBuilder.newBuilder() - .maximumSize(50_000).expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(50_000) - .recordStats().build(); + private MessageCount trxCount = new MessageCount(); - private Cache BlockCache = CacheBuilder.newBuilder() - .maximumSize(10).expireAfterWrite(60, TimeUnit.SECONDS) - .recordStats().build(); + public void init () { + spreadExecutor.scheduleWithFixedDelay(() -> { + try { + consumerAdvObjToSpread(); + } catch (Throwable t) { + logger.error("Spread thread error.", t); + } + }, 100, 30, TimeUnit.MILLISECONDS); - private ConcurrentHashMap advObjToSpread = new ConcurrentHashMap<>(); + fetchExecutor.scheduleWithFixedDelay(() -> { + try { + consumerAdvObjToFetch(); + } catch (Throwable t) { + logger.error("fetch thread error.", t); + } + }, 100, 30, TimeUnit.MILLISECONDS); + } + + synchronized public boolean addInv (Item item) { + InventoryType type = item.getType(); + Sha256Hash hash = item.getHash(); + if (messageCache.getIfPresent(item) != null) { + return false; + } +// if (type.equals(InventoryType.TRX) && trxCache.getIfPresent(hash) != null) { +// return false; +// } +// if (type.equals(InventoryType.BLOCK) && blockCache.getIfPresent(hash) != null) { +// return false; +// } + if (advObjToFetch.get(item) != null) { + return false; + } + advObjToFetch.put(item, System.currentTimeMillis()); + return true; + } + + public Message getMessage (Item item) { +// if (item.getType().equals(InventoryType.TRX)) { +// return trxCache.getIfPresent(item.getHash()); +// } +// if (item.getType().equals(InventoryType.BLOCK)) { +// return blockCache.getIfPresent(item.getHash()); +// } + return messageCache.getIfPresent(item); + } public void broadcast(Message msg) { InventoryType type; if (msg instanceof BlockMessage) { - logger.info("Ready to broadcast block {}", ((BlockMessage) msg).getBlockId()); - //freshBlockId.offer(((BlockMessage) msg).getBlockId()); - BlockCache.put(msg.getMessageId(), (BlockMessage) msg); + BlockMessage blockMsg = (BlockMessage) msg; + logger.info("Ready to broadcast block {}", blockMsg.getBlockId().getString()); + messageCache.put(new Item(blockMsg.getMessageId(), InventoryType.BLOCK), blockMsg); type = InventoryType.BLOCK; + blockMsg.getBlockCapsule().getTransactions().forEach(transactionCapsule -> { + advObjToSpread.remove(transactionCapsule.getTransactionId()); + }); } else if (msg instanceof TransactionMessage) { - TrxCache.put(msg.getMessageId(), (TransactionMessage) msg); + TransactionMessage trxMsg = (TransactionMessage) msg; + messageCache.put(new Item(trxMsg.getMessageId(), InventoryType.BLOCK), trxMsg); type = InventoryType.TRX; + trxCount.add(); } else { + logger.error("Adv item is neither block nor trx."); + return; + } + synchronized (advObjToSpread) { + advObjToSpread.put(new Item(msg.getMessageId(), type), System.currentTimeMillis()); + } + } + + public void onDisconnect (PeerConnection peer) { + if (!peer.getAdvInvRequest().isEmpty()) { + peer.getAdvInvRequest().keySet().forEach(item -> { + if (tronProxy.getActivePeer().stream() + .filter(peerConnection -> !peerConnection.equals(peer)) + .filter(peerConnection -> peerConnection.getAdvInvReceive().containsKey(item)) + .findFirst() + .isPresent()) { + advObjToFetch.put(item, System.currentTimeMillis()); + } + }); + } + } + + private void consumerAdvObjToFetch() { + Collection peers = tronProxy.getActivePeer().stream() + .filter(peer -> peer.isIdle()) + .collect(Collectors.toList()); + + if (advObjToFetch.isEmpty() || peers.isEmpty()) { + return; + } + + InvSender invSender = new InvSender(); + long now = Time.getCurrentMillis(); + advObjToFetch.forEach((item, time) -> { + Sha256Hash hash = item.getHash(); + if (time < now - MSG_CACHE_DURATION_IN_BLOCKS * BLOCK_PRODUCED_INTERVAL) { + logger.info("This obj is too late to fetch, type: {} hash: {}.", item.getType(), item.getHash()); + advObjToFetch.remove(item); + return; + } + peers.stream() + .filter(peer -> peer.getAdvInvReceive().containsKey(hash) && invSender.getSize(peer) < MAX_INV_FETCH_PER_PEER) + .sorted(Comparator.comparingInt(peer -> invSender.getSize(peer))) + .findFirst().ifPresent(peer -> { + invSender.add(item, peer); + peer.getAdvInvRequest().put(item, now); + advObjToFetch.remove(item); + }); + }); + + invSender.sendFetch(); + } + + private void consumerAdvObjToSpread() { + if (advObjToSpread.isEmpty()) { return; } + + InvSender invSender = new InvSender(); + HashMap spread = new HashMap<>(); synchronized (advObjToSpread) { - advObjToSpread.put(msg.getMessageId(), type); + spread.putAll(advObjToSpread); + advObjToSpread.clear(); } + + tronProxy.getActivePeer().stream() + .filter(peer -> !peer.isNeedSyncFromUs()) + .forEach(peer -> spread.entrySet().stream() + .filter(entry -> !peer.getAdvInvReceive().containsKey(entry.getKey()) && !peer.getAdvInvSpread().containsKey(entry.getKey())) + .forEach(entry -> { + peer.getAdvInvSpread().put(entry.getKey(), Time.getCurrentMillis()); + invSender.add(entry.getKey(), peer); + })); + + invSender.sendInv(); } + class InvSender { + private HashMap>> send = new HashMap<>(); + public void clear() { + this.send.clear(); + } + + public void add(Entry id, PeerConnection peer) { + if (send.containsKey(peer) && !send.get(peer).containsKey(id.getValue())) { + send.get(peer).put(id.getValue(), new LinkedList<>()); + } else if (!send.containsKey(peer)) { + send.put(peer, new HashMap<>()); + send.get(peer).put(id.getValue(), new LinkedList<>()); + } + send.get(peer).get(id.getValue()).offer(id.getKey()); + } + + public void add(Item id, PeerConnection peer) { + if (send.containsKey(peer) && !send.get(peer).containsKey(id.getType())) { + send.get(peer).put(id.getType(), new LinkedList<>()); + } else if (!send.containsKey(peer)) { + send.put(peer, new HashMap<>()); + send.get(peer).put(id.getType(), new LinkedList<>()); + } + send.get(peer).get(id.getType()).offer(id.getHash()); + } + + public int getSize(PeerConnection peer) { + if (send.containsKey(peer)) { + return send.get(peer).values().stream().mapToInt(LinkedList::size).sum(); + } + return 0; + } + + public void sendInv() { + send.forEach((peer, ids) -> ids.forEach((key, value) -> { + if (key.equals(InventoryType.BLOCK)) { + value.sort(Comparator.comparingLong(value1 -> new BlockId(value1).getNum())); + } + peer.sendMessage(new InventoryMessage(value, key)); + })); + } + + void sendFetch() { + send.forEach((peer, ids) -> ids.forEach((key, value) -> { + if (key.equals(InventoryType.BLOCK)) { + value.sort(Comparator.comparingLong(value1 -> new BlockId(value1).getNum())); + } + peer.sendMessage(new FetchInvDataMessage(value, key)); + })); + } + } } diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index 1f41bd95069..d937dce2227 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -2,16 +2,16 @@ import static org.tron.core.config.Parameter.NetConstants.MAX_INVENTORY_SIZE_IN_MINUTES; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import java.util.Deque; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; -import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.LinkedBlockingQueue; import javafx.util.Pair; import lombok.Getter; import lombok.Setter; @@ -25,6 +25,7 @@ import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.Time; import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.net.TronProxy; @Slf4j @@ -35,44 +36,50 @@ public class PeerConnection extends Channel { @Autowired private TronProxy tronProxy; - @Setter - @Getter - private BlockId lastSyncBlockId; + @Autowired + private PeerSync peerSync; + + @Autowired + private PeerAdv peerAdv; @Setter @Getter - private long remainNum; + private HelloMessage helloMessage; @Setter @Getter - private long lastBlockUpdateTime = System.currentTimeMillis(); + private Map advInvReceive = new ConcurrentHashMap<>(); @Setter - private HelloMessage helloMessage; + @Getter + private Map advInvSpread = new ConcurrentHashMap<>(); @Setter @Getter - private Queue invToUs = new LinkedBlockingQueue<>(); + private Map advInvRequest = new ConcurrentHashMap<>(); @Setter @Getter - private Queue invWeAdv = new LinkedBlockingQueue<>(); + private BlockId blockBothHave = tronProxy.getGenesisBlockId(); + public void setBlockBothHave (BlockId blockId) { + this.blockBothHave = blockId; + this.blockBothHaveUpdateTime = System.currentTimeMillis(); + } - @Setter @Getter - private Map advObjSpreadToUs = new ConcurrentHashMap<>(); + private long blockBothHaveUpdateTime = System.currentTimeMillis(); @Setter @Getter - private Map advObjWeSpread = new ConcurrentHashMap<>(); + private BlockId lastSyncBlockId; @Setter @Getter - private Map advObjWeRequested = new ConcurrentHashMap<>(); + private long remainNum; - @Setter @Getter - private BlockId headBlockWeBothHave = new BlockId(); + private Cache syncBlockIdCache = CacheBuilder.newBuilder() + .maximumSize(2 * NodeConstant.SYNC_FETCH_BATCH_NUM).recordStats().build(); @Setter @Getter @@ -88,7 +95,7 @@ public class PeerConnection extends Channel { @Setter @Getter - private long unfetchSyncNum = 0L; + private Set syncBlockInProcess = new HashSet<>(); @Setter @Getter @@ -98,24 +105,20 @@ public class PeerConnection extends Channel { @Getter private boolean needSyncFromUs; - @Setter - @Getter - private Set blockInProc = new HashSet<>(); - public void cleanInvGarbage() { long time = Time.getCurrentMillis() - MAX_INVENTORY_SIZE_IN_MINUTES * 60 * 1000; - Iterator> iterator = this.advObjSpreadToUs.entrySet().iterator(); + Iterator> iterator = this.advInvReceive.entrySet().iterator(); removeIterator(iterator, time); - iterator = this.advObjWeSpread.entrySet().iterator(); + iterator = this.advInvSpread.entrySet().iterator(); removeIterator(iterator, time); } - private void removeIterator(Iterator> iterator, long oldestTimestamp) { + private void removeIterator(Iterator> iterator, long oldestTimestamp) { while (iterator.hasNext()) { Map.Entry entry = iterator.next(); Long ts = (Long) entry.getValue(); @@ -125,8 +128,27 @@ private void removeIterator(Iterator> iterator, long old } } + public boolean isIdle() { + return advInvRequest.isEmpty() && syncBlockRequested.isEmpty() && syncChainRequested == null; + } + + public void sendMessage(Message message) { + msgQueue.sendMessage(message); + } + public void onConnectPeer() { + if (getHelloMessage().getHeadBlockId().getNum() > tronProxy.getHeadBlockId().getNum()) { + setTronState(TronState.SYNCING); + peerSync.startSync(this); + } else { + setTronState(TronState.SYNC_COMPLETED); + } + } + public void onDisconnectPeer() { + peerSync.onDisconnect(this); + peerAdv.onDisconnect(this); + } public String logSyncStats() { return String.format( @@ -138,36 +160,23 @@ public String logSyncStats() { + "syncToFetchSize:%d\n" + "syncToFetchSizePeekNum:%d\n" + "syncBlockRequestedSize:%d\n" - + "unFetchSynNum:%d\n" + + "remainNum:%d\n" + "syncChainRequested:%s\n" - + "blockInPorc:%d\n", + + "blockInProcess:%d\n", this.getNode().getHost() + ":" + this.getNode().getPort(), this.getNode().getHexIdShort(), (int) this.getPeerStats().getAvgLatency(), Time.getTimeString(super.getStartTime()), - headBlockWeBothHave.getNum(), + blockBothHave.getNum(), isNeedSyncFromPeer(), isNeedSyncFromUs(), syncBlockToFetch.size(), syncBlockToFetch.size() > 0 ? syncBlockToFetch.peek().getNum() : -1, syncBlockRequested.size(), - unfetchSyncNum, + remainNum, syncChainRequested == null ? "NULL" : Time.getTimeString(syncChainRequested.getValue()), - blockInProc.size()) + syncBlockInProcess.size()) + nodeStatistics.toString() + "\n"; } - public boolean isBusy() { - return !idle(); - } - - public boolean idle() { - return advObjWeRequested.isEmpty() - && syncBlockRequested.isEmpty() - && syncChainRequested == null; - } - - public void sendMessage(Message message) { - msgQueue.sendMessage(message); - } } diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java index d0b5388ad22..74109423da6 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -1,21 +1,39 @@ package org.tron.core.net.peer; +import static org.tron.core.config.Parameter.NetConstants.MAX_INV_FETCH_PER_PEER; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import java.util.ArrayList; import java.util.Collections; -import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import javafx.util.Pair; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.overlay.server.Channel.TronState; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.net.TronManager; +import org.tron.core.net.TronNetClient; import org.tron.core.net.TronProxy; +import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.message.FetchInvDataMessage; import org.tron.core.net.message.SyncBlockChainMessage; +import org.tron.protos.Protocol.Inventory.InventoryType; +import org.tron.protos.Protocol.ReasonCode; @Slf4j @Component @@ -25,33 +43,107 @@ public class PeerSync { private TronProxy tronProxy; @Autowired - private TronManager tronManager; + private TronNetClient tronManager; + + private Map blockWaitToProc = new ConcurrentHashMap<>(); + + private Map blockJustReceived = new ConcurrentHashMap<>(); + + private Cache requestBlockIds = CacheBuilder.newBuilder().maximumSize(10000) + .expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(10000) + .recordStats().build(); + + private ScheduledExecutorService fetchSyncBlocksExecutor = Executors.newSingleThreadScheduledExecutor(); + + private ScheduledExecutorService syncHandleExecutor = Executors.newSingleThreadScheduledExecutor(); + + private boolean syncHandleFlag = false; + + @Setter + private boolean fetchFlag = false; + + public void init () { + fetchSyncBlocksExecutor.scheduleWithFixedDelay(() -> { + try { + if (fetchFlag) { + startFetchSyncBlock(); + } + fetchFlag = false; + } catch (Throwable t) { + logger.error("Fetch sync block error.", t); + } + }, 10, 1, TimeUnit.SECONDS); + + syncHandleExecutor.scheduleWithFixedDelay(() -> { + try { + if (syncHandleFlag) { + syncHandleFlag = false; + handleSyncBlock(); + } + } catch (Throwable t) { + logger.error("Unhandled exception", t); + } + }, 10, 1, TimeUnit.SECONDS); + } public void startSync(PeerConnection peer) { peer.setTronState(TronState.SYNCING); peer.setNeedSyncFromPeer(true); peer.getSyncBlockToFetch().clear(); peer.setRemainNum(0); - peer.setHeadBlockWeBothHave(tronProxy.getGenesisBlockId()); + peer.setBlockBothHave(tronProxy.getGenesisBlockId()); syncNext(peer); } public void syncNext(PeerConnection peer) { - if (peer.getSyncChainRequested() != null) { - logger.warn("Peer {} is in sync.", peer.getNode().getHost()); - return; + try { + if (peer.getSyncChainRequested() != null) { + logger.warn("Peer {} is in sync.", peer.getNode().getHost()); + return; + } + LinkedList chainSummary = getBlockChainSummary(peer); + peer.setSyncChainRequested(new Pair<>(chainSummary, System.currentTimeMillis())); + peer.sendMessage(new SyncBlockChainMessage(chainSummary)); + }catch (Exception e) { + logger.error("Peer {} sync failed, reason: {}", peer.getInetAddress(), e.getMessage()); + peer.disconnect(ReasonCode.SYNC_FAIL); } - LinkedList chainSummary = getBlockChainSummary(peer); - peer.setSyncChainRequested(new Pair<>(chainSummary, System.currentTimeMillis())); - peer.sendMessage(new SyncBlockChainMessage(chainSummary)); + } + + public void processBlock(PeerConnection peer, BlockMessage blockMessage) { + BlockCapsule block = blockMessage.getBlockCapsule(); + BlockId blockId = block.getBlockId(); + peer.getSyncBlockRequested().remove(blockId); + synchronized (blockJustReceived) { + blockJustReceived.put(blockMessage, peer); + } + syncHandleFlag = true; + if (peer.isIdle()) { + if (peer.getRemainNum() > 0 && peer.getSyncBlockToFetch().size() <= NodeConstant.SYNC_FETCH_BATCH_NUM) { + syncNext(peer); + } else { + fetchFlag = true; + } + } + } + + public void onDisconnect (PeerConnection peer) { + if (!peer.getSyncBlockRequested().isEmpty()) { + peer.getSyncBlockRequested().keySet().forEach(blockId -> invalid(blockId)); + } + } + + private void invalid (BlockId blockId) { + requestBlockIds.invalidate(blockId); + fetchFlag = true; } private LinkedList getBlockChainSummary(PeerConnection peer) throws Exception { - BlockId beginBlockId = peer.getHeadBlockWeBothHave(); + BlockId beginBlockId = peer.getBlockBothHave(); List blockIds = new ArrayList<>(peer.getSyncBlockToFetch()); LinkedList forkList = new LinkedList<>(); - LinkedList retSummary = new LinkedList<>(); + LinkedList summary = new LinkedList<>(); long syncBeginNumber = tronProxy.getSyncBeginNumber(); long low = syncBeginNumber < 0 ? 0 : syncBeginNumber; long highNoFork; @@ -74,23 +166,123 @@ private LinkedList getBlockChainSummary(PeerConnection peer) throws Exc } } - logger.info("Get block chain summary, low: {}, highNoFork: {}, high: {}", low, highNoFork, high); + if (low > highNoFork){ + throw new P2pException(TypeEnum.SYNC_FAILED, "low: " + low + " gt highNoFork: " + highNoFork); + } - tronManager.check(low <= highNoFork, "low gt highNoFork"); + long realHigh = high + blockIds.size(); - long realHighBlkNum = high + blockIds.size(); - while (low <= realHighBlkNum) { + logger.info("Get block chain summary, low: {}, highNoFork: {}, high: {}, realHigh: {}", + low, highNoFork, high, realHigh); + + while (low <= realHigh) { if (low <= highNoFork) { - retSummary.offer(tronProxy.getBlockIdByNum(low)); + summary.offer(tronProxy.getBlockIdByNum(low)); } else if (low <= high) { - retSummary.offer(forkList.get((int) (low - highNoFork - 1))); + summary.offer(forkList.get((int) (low - highNoFork - 1))); } else { - retSummary.offer(blockIds.get((int) (low - high - 1))); + summary.offer(blockIds.get((int) (low - high - 1))); } - low += (realHighBlkNum - low + 2) / 2; + low += (realHigh - low + 2) / 2; } - return retSummary; + return summary; + } + + private synchronized void startFetchSyncBlock() { + HashMap> send = new HashMap<>(); + HashSet request = new HashSet<>(); + + tronProxy.getActivePeer().stream() + .filter(peer -> peer.isNeedSyncFromPeer() && peer.isIdle()) + .forEach(peer -> { + if (!send.containsKey(peer)) { + send.put(peer, new LinkedList<>()); + } + for (BlockId blockId : peer.getSyncBlockToFetch()) { + if (!request.contains(blockId) && (requestBlockIds.getIfPresent(blockId) == null)) { + send.get(peer).add(blockId); + request.add(blockId); + if (send.get(peer).size() >= MAX_INV_FETCH_PER_PEER) { + break; + } + } + } + }); + + send.forEach((peer, blockIds) -> { + blockIds.forEach(blockId -> { + requestBlockIds.put(blockId, System.currentTimeMillis()); + peer.getSyncBlockRequested().put(blockId, System.currentTimeMillis()); + }); + List ids = new LinkedList<>(); + ids.addAll(blockIds); + if (!ids.isEmpty()) { + peer.sendMessage(new FetchInvDataMessage(ids, InventoryType.BLOCK)); + } + }); + + send.clear(); + } + + private void processSyncBlock (BlockCapsule block) { + boolean flag = true; + BlockId blockId = block.getBlockId(); + try { + tronProxy.processBlock(block); + } catch (Exception e) { + logger.error("Process sync block {} failed.", blockId.getString(), e); + flag = false; + } + for (PeerConnection peer: tronProxy.getActivePeer()) { + if (peer.getSyncBlockInProcess().remove(blockId)) { + if (flag){ + peer.setBlockBothHave(blockId); + if (peer.getSyncBlockToFetch().isEmpty()) { + syncNext(peer); + } + }else { + peer.disconnect(ReasonCode.BAD_BLOCK); + } + } + } + } + + private synchronized void handleSyncBlock() { + + synchronized (blockJustReceived) { + blockWaitToProc.putAll(blockJustReceived); + blockJustReceived.clear(); + } + + final boolean[] isProcessed = {true}; + + while (isProcessed[0]) { + + isProcessed[0] = false; + + blockWaitToProc.forEach((msg, peerConnection) -> { + if (peerConnection.isDisconnect()) { + logger.error("Peer {} is disconnect, drop block {}", peerConnection.getInetAddress(), msg.getBlockId().getString()); + blockWaitToProc.remove(msg); + invalid(msg.getBlockId()); + return; + } + final boolean[] isFound = {false}; + tronProxy.getActivePeer().stream() + .filter(peer -> !peer.getSyncBlockToFetch().isEmpty() && peer.getSyncBlockToFetch().peek().equals(msg.getBlockId())) + .forEach(peer -> { + peer.getSyncBlockToFetch().pop(); + peer.getSyncBlockInProcess().add(msg.getBlockId()); + isFound[0] = true; + }); + if (isFound[0]) { + blockWaitToProc.remove(msg); + isProcessed[0] = true; + processSyncBlock(msg.getBlockCapsule()); + } + }); + } } } From 6b688912fb7808a4d03dcf3d1214082d2dd8652c Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 12 Nov 2018 12:18:07 +0800 Subject: [PATCH 09/41] remove nodeimpl --- .../tron/common/application/Application.java | 3 - .../common/application/ApplicationImpl.java | 35 - .../common/application/CliApplication.java | 6 - .../common/overlay/client/PeerClient.java | 7 - .../tron/common/overlay/server/Channel.java | 9 +- .../common/overlay/server/PeerServer.java | 6 - .../tron/common/overlay/server/SyncPool.java | 1 - .../server/TronChannelInitializer.java | 9 +- src/main/java/org/tron/core/Wallet.java | 6 +- .../java/org/tron/core/net/TronHandler.java | 1 - .../TransactionsMsgHandler.java | 15 - .../java/org/tron/core/net/node/Node.java | 18 - .../org/tron/core/net/node/NodeDelegate.java | 52 - .../tron/core/net/node/NodeDelegateImpl.java | 362 ----- .../java/org/tron/core/net/node/NodeImpl.java | 1352 ----------------- .../core/net/node/PeerConnectionDelegate.java | 18 - .../tron/core/services/WitnessService.java | 6 +- .../net/node/override/PeerClientTest.java | 1 - .../override/TronChannelInitializerTest.java | 1 - 19 files changed, 10 insertions(+), 1898 deletions(-) delete mode 100644 src/main/java/org/tron/core/net/node/Node.java delete mode 100644 src/main/java/org/tron/core/net/node/NodeDelegate.java delete mode 100755 src/main/java/org/tron/core/net/node/NodeDelegateImpl.java delete mode 100644 src/main/java/org/tron/core/net/node/NodeImpl.java delete mode 100644 src/main/java/org/tron/core/net/node/PeerConnectionDelegate.java diff --git a/src/main/java/org/tron/common/application/Application.java b/src/main/java/org/tron/common/application/Application.java index d9279ddb25b..b408e15bd42 100644 --- a/src/main/java/org/tron/common/application/Application.java +++ b/src/main/java/org/tron/common/application/Application.java @@ -18,7 +18,6 @@ import org.tron.core.config.args.Args; import org.tron.core.db.BlockStore; import org.tron.core.db.Manager; -import org.tron.core.net.node.Node; public interface Application { @@ -36,8 +35,6 @@ public interface Application { void shutdownServices(); - Node getP2pNode(); - BlockStore getBlockStoreS(); void addService(Service service); diff --git a/src/main/java/org/tron/common/application/ApplicationImpl.java b/src/main/java/org/tron/common/application/ApplicationImpl.java index ca3fd05554f..eff5a4d9584 100644 --- a/src/main/java/org/tron/common/application/ApplicationImpl.java +++ b/src/main/java/org/tron/common/application/ApplicationImpl.java @@ -6,34 +6,19 @@ import org.tron.core.config.args.Args; import org.tron.core.db.BlockStore; import org.tron.core.db.Manager; -import org.tron.core.db2.common.IRevokingDB; -import org.tron.core.db2.core.SnapshotManager; -import org.tron.core.net.node.Node; -import org.tron.core.net.node.NodeDelegate; -import org.tron.core.net.node.NodeDelegateImpl; -import org.tron.core.net.node.NodeImpl; @Slf4j @Component public class ApplicationImpl implements Application { - @Autowired - private NodeImpl p2pNode; - private BlockStore blockStoreDb; private ServiceContainer services; - private NodeDelegate nodeDelegate; @Autowired private Manager dbManager; private boolean isProducer; - private void resetP2PNode() { - p2pNode.listen(); - p2pNode.syncFrom(null); - } - @Override public void setOptions(Args args) { // not used @@ -44,7 +29,6 @@ public void setOptions(Args args) { public void init(Args args) { blockStoreDb = dbManager.getBlockStore(); services = new ServiceContainer(); - nodeDelegate = new NodeDelegateImpl(dbManager); } @Override @@ -61,8 +45,6 @@ public void initServices(Args args) { * start up the app. */ public void startup() { - p2pNode.setNodeDelegate(nodeDelegate); - resetP2PNode(); } @Override @@ -72,7 +54,6 @@ public void shutdown() { closeRevokingStore(); closeAllStore(); } - closeConnection(); dbManager.stopRepushThread(); logger.info("******** end to shutdown ********"); } @@ -87,11 +68,6 @@ public void shutdownServices() { services.stop(); } - @Override - public Node getP2pNode() { - return p2pNode; - } - @Override public BlockStore getBlockStoreS() { return blockStoreDb; @@ -110,17 +86,6 @@ public void setIsProducer(boolean producer) { isProducer = producer; } - private void closeConnection() { - logger.info("******** begin to shutdown connection ********"); - try { - p2pNode.close(); - } catch (Exception e) { - logger.info("failed to close p2pNode. " + e); - } finally { - logger.info("******** end to shutdown connection ********"); - } - } - private void closeRevokingStore() { dbManager.getRevokingStore().shutdown(); } diff --git a/src/main/java/org/tron/common/application/CliApplication.java b/src/main/java/org/tron/common/application/CliApplication.java index 9bcffd106b2..d63d227f212 100644 --- a/src/main/java/org/tron/common/application/CliApplication.java +++ b/src/main/java/org/tron/common/application/CliApplication.java @@ -17,7 +17,6 @@ import org.tron.core.config.args.Args; import org.tron.core.db.BlockStore; import org.tron.core.db.Manager; -import org.tron.core.net.node.Node; public class CliApplication implements Application { @@ -56,11 +55,6 @@ public void shutdownServices() { } - @Override - public Node getP2pNode() { - return null; - } - @Override public BlockStore getBlockStoreS() { return null; diff --git a/src/main/java/org/tron/common/overlay/client/PeerClient.java b/src/main/java/org/tron/common/overlay/client/PeerClient.java index a3bf856afb2..1ca6ccf44fb 100644 --- a/src/main/java/org/tron/common/overlay/client/PeerClient.java +++ b/src/main/java/org/tron/common/overlay/client/PeerClient.java @@ -14,13 +14,11 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import org.tron.common.overlay.discover.node.Node; import org.tron.common.overlay.discover.node.NodeHandler; import org.tron.common.overlay.server.TronChannelInitializer; import org.tron.core.config.args.Args; -import org.tron.core.net.node.NodeImpl; import org.tron.protos.Protocol.ReasonCode; @Component @@ -31,10 +29,6 @@ public class PeerClient { @Autowired private ApplicationContext ctx; - @Autowired - @Lazy - private NodeImpl node; - private EventLoopGroup workerGroup; public PeerClient() { @@ -79,7 +73,6 @@ public ChannelFuture connectAsync(String host, int port, String remoteId, boolea TronChannelInitializer tronChannelInitializer = ctx .getBean(TronChannelInitializer.class, remoteId); tronChannelInitializer.setPeerDiscoveryMode(discoveryMode); - tronChannelInitializer.setNodeImpl(node); Bootstrap b = new Bootstrap(); b.group(workerGroup); diff --git a/src/main/java/org/tron/common/overlay/server/Channel.java b/src/main/java/org/tron/common/overlay/server/Channel.java index d92a5a6d2f9..188e551f183 100644 --- a/src/main/java/org/tron/common/overlay/server/Channel.java +++ b/src/main/java/org/tron/common/overlay/server/Channel.java @@ -40,7 +40,6 @@ import org.tron.common.overlay.message.StaticMessages; import org.tron.core.db.ByteArrayWrapper; import org.tron.core.exception.P2pException; -import org.tron.core.net.node.PeerConnectionDelegate; import org.tron.core.net.TronHandler; import org.tron.protos.Protocol.ReasonCode; @@ -84,8 +83,6 @@ public class Channel { private long startTime; - private PeerConnectionDelegate peerDel; - private TronState tronState = TronState.INIT; protected NodeStatistics nodeStatistics; @@ -101,7 +98,7 @@ public class Channel { private boolean isTrustPeer; public void init(ChannelPipeline pipeline, String remoteId, boolean discoveryMode, - ChannelManager channelManager, PeerConnectionDelegate peerDel) { + ChannelManager channelManager) { this.channelManager = channelManager; @@ -120,8 +117,6 @@ public void init(ChannelPipeline pipeline, String remoteId, boolean discoveryMod //handshake first pipeline.addLast("handshakeHandler", handshakeHandler); - this.peerDel = peerDel; - messageCodec.setChannel(this); msgQueue.setChannel(this); handshakeHandler.setChannel(this, remoteId); @@ -130,8 +125,6 @@ public void init(ChannelPipeline pipeline, String remoteId, boolean discoveryMod p2pHandler.setMsgQueue(msgQueue); tronHandler.setMsgQueue(msgQueue); - tronHandler.setPeerDel(peerDel); - } public void publicHandshakeFinished(ChannelHandlerContext ctx, HelloMessage msg) { diff --git a/src/main/java/org/tron/common/overlay/server/PeerServer.java b/src/main/java/org/tron/common/overlay/server/PeerServer.java index 13b5f4edef1..0a8be289e71 100644 --- a/src/main/java/org/tron/common/overlay/server/PeerServer.java +++ b/src/main/java/org/tron/common/overlay/server/PeerServer.java @@ -31,7 +31,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import org.tron.core.config.args.Args; -import org.tron.core.net.node.NodeImpl; @Component public class PeerServer { @@ -46,9 +45,6 @@ public class PeerServer { private boolean listening; - @Autowired - private NodeImpl p2pNode; - EventLoopGroup bossGroup; EventLoopGroup workerGroup; ChannelFuture channelFuture; @@ -64,8 +60,6 @@ public void start(int port) { workerGroup = new NioEventLoopGroup(args.getTcpNettyWorkThreadNum()); tronChannelInitializer = ctx.getBean(TronChannelInitializer.class, ""); - tronChannelInitializer.setNodeImpl(p2pNode); - try { ServerBootstrap b = new ServerBootstrap(); diff --git a/src/main/java/org/tron/common/overlay/server/SyncPool.java b/src/main/java/org/tron/common/overlay/server/SyncPool.java index 310b9fd7281..f6f4b133c4d 100644 --- a/src/main/java/org/tron/common/overlay/server/SyncPool.java +++ b/src/main/java/org/tron/common/overlay/server/SyncPool.java @@ -44,7 +44,6 @@ import org.tron.common.overlay.discover.node.statistics.NodeStatistics; import org.tron.core.config.args.Args; import org.tron.core.net.peer.PeerConnection; -import org.tron.core.net.node.PeerConnectionDelegate; @Component public class SyncPool { diff --git a/src/main/java/org/tron/common/overlay/server/TronChannelInitializer.java b/src/main/java/org/tron/common/overlay/server/TronChannelInitializer.java index d3c2c0120ba..4b330cc1854 100644 --- a/src/main/java/org/tron/common/overlay/server/TronChannelInitializer.java +++ b/src/main/java/org/tron/common/overlay/server/TronChannelInitializer.java @@ -28,7 +28,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -import org.tron.core.net.node.NodeImpl; import org.tron.core.net.peer.PeerConnection; /** @@ -47,8 +46,6 @@ public class TronChannelInitializer extends ChannelInitializer @Autowired ChannelManager channelManager; - private NodeImpl p2pNode; - private String remoteId; private boolean peerDiscoveryMode = false; @@ -62,7 +59,7 @@ public void initChannel(NioSocketChannel ch) throws Exception { try { final Channel channel = ctx.getBean(PeerConnection.class); - channel.init(ch.pipeline(), remoteId, peerDiscoveryMode, channelManager, p2pNode); + channel.init(ch.pipeline(), remoteId, peerDiscoveryMode, channelManager); // limit the size of receiving buffer to 1024 ch.config().setRecvByteBufAllocator(new FixedRecvByteBufAllocator(256 * 1024)); @@ -89,8 +86,4 @@ private boolean isInbound() { public void setPeerDiscoveryMode(boolean peerDiscoveryMode) { this.peerDiscoveryMode = peerDiscoveryMode; } - - public void setNodeImpl(NodeImpl p2pNode) { - this.p2pNode = p2pNode; - } } diff --git a/src/main/java/org/tron/core/Wallet.java b/src/main/java/org/tron/core/Wallet.java index e7d20fa67a2..5b55f8d5e27 100755 --- a/src/main/java/org/tron/core/Wallet.java +++ b/src/main/java/org/tron/core/Wallet.java @@ -102,8 +102,8 @@ import org.tron.core.exception.TransactionExpirationException; import org.tron.core.exception.VMIllegalException; import org.tron.core.exception.ValidateSignatureException; +import org.tron.core.net.TronNetClient; import org.tron.core.net.message.TransactionMessage; -import org.tron.core.net.node.NodeImpl; import org.tron.protos.Contract.AssetIssueContract; import org.tron.protos.Contract.CreateSmartContract; import org.tron.protos.Contract.TransferContract; @@ -128,7 +128,7 @@ public class Wallet { @Getter private final ECKey ecKey; @Autowired - private NodeImpl p2pNode; + private TronNetClient tronNetClient; @Autowired private Manager dbManager; @Autowired @@ -421,7 +421,7 @@ public GrpcAPI.Return broadcastTransaction(Transaction signaturedTransaction) { trx.resetResult(); } dbManager.pushTransaction(trx); - p2pNode.broadcast(message); + tronNetClient.broadcast(message); return builder.setResult(true).setCode(response_code.SUCCESS).build(); } catch (ValidateSignatureException e) { diff --git a/src/main/java/org/tron/core/net/TronHandler.java b/src/main/java/org/tron/core/net/TronHandler.java index 52f7cb579ba..d97f47e802e 100644 --- a/src/main/java/org/tron/core/net/TronHandler.java +++ b/src/main/java/org/tron/core/net/TronHandler.java @@ -10,7 +10,6 @@ import org.tron.common.overlay.server.MessageQueue; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.PeerConnection; -import org.tron.core.net.node.PeerConnectionDelegate; @Component @Scope("prototype") diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index faa07b8f78c..fdbf425cebe 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -11,29 +11,14 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.args.Args; -import org.tron.core.exception.AccountResourceInsufficientException; -import org.tron.core.exception.BadTransactionException; -import org.tron.core.exception.ContractExeException; -import org.tron.core.exception.ContractSizeNotEqualToOneException; -import org.tron.core.exception.ContractValidateException; -import org.tron.core.exception.DupTransactionException; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.exception.ReceiptCheckErrException; -import org.tron.core.exception.TaposException; -import org.tron.core.exception.TooBigTransactionException; -import org.tron.core.exception.TooBigTransactionResultException; -import org.tron.core.exception.TransactionExpirationException; -import org.tron.core.exception.VMIllegalException; -import org.tron.core.exception.ValidateSignatureException; import org.tron.core.net.TronProxy; import org.tron.core.net.message.TransactionMessage; import org.tron.core.net.message.TransactionsMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.Item; -import org.tron.core.net.node.NodeImpl; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Inventory.InventoryType; import org.tron.protos.Protocol.ReasonCode; diff --git a/src/main/java/org/tron/core/net/node/Node.java b/src/main/java/org/tron/core/net/node/Node.java deleted file mode 100644 index 21b964dfb3c..00000000000 --- a/src/main/java/org/tron/core/net/node/Node.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.tron.core.net.node; - -import org.tron.common.overlay.message.Message; -import org.tron.common.utils.Quitable; -import org.tron.common.utils.Sha256Hash; - -public interface Node extends Quitable { - - void setNodeDelegate(NodeDelegate nodeDel); - - void broadcast(Message msg); - - void listen(); - - void syncFrom(Sha256Hash myHeadBlockHash); - - void close() throws InterruptedException; -} diff --git a/src/main/java/org/tron/core/net/node/NodeDelegate.java b/src/main/java/org/tron/core/net/node/NodeDelegate.java deleted file mode 100644 index 2a3f6ccdc75..00000000000 --- a/src/main/java/org/tron/core/net/node/NodeDelegate.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.tron.core.net.node; - -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import org.tron.common.overlay.message.Message; -import org.tron.common.utils.Sha256Hash; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.capsule.BlockCapsule.BlockId; -import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.exception.BadBlockException; -import org.tron.core.exception.BadTransactionException; -import org.tron.core.exception.NonCommonBlockException; -import org.tron.core.exception.StoreException; -import org.tron.core.exception.TronException; -import org.tron.core.exception.UnLinkedBlockException; -import org.tron.core.net.message.MessageTypes; - -public interface NodeDelegate { - - LinkedList handleBlock(BlockCapsule block, boolean syncMode) - throws BadBlockException, UnLinkedBlockException, InterruptedException, NonCommonBlockException; - - boolean handleTransaction(TransactionCapsule trx) throws BadTransactionException; - - LinkedList getLostBlockIds(List blockChainSummary) throws StoreException; - - Deque getBlockChainSummary(BlockId beginBLockId, Deque blockIds) - throws TronException; - - Message getData(Sha256Hash msgId, MessageTypes type) throws StoreException; - - void syncToCli(long unSyncNum); - - long getBlockTime(BlockId id); - - BlockId getHeadBlockId(); - - BlockId getSolidBlockId(); - - boolean contain(Sha256Hash hash, MessageTypes type); - - boolean containBlock(BlockId id); - - long getHeadBlockTimeStamp(); - - boolean containBlockInMainChain(BlockId id); - - BlockCapsule getGenesisBlock(); - - boolean canChainRevoke(long num); -} diff --git a/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java b/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java deleted file mode 100755 index 0446a0d1e0c..00000000000 --- a/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java +++ /dev/null @@ -1,362 +0,0 @@ -package org.tron.core.net.node; - -import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; -import static org.tron.core.config.Parameter.ChainConstant.BLOCK_SIZE; - -import com.google.common.primitives.Longs; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.Collectors; -import lombok.extern.slf4j.Slf4j; -import org.tron.common.overlay.message.Message; -import org.tron.common.utils.Sha256Hash; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.capsule.BlockCapsule.BlockId; -import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.config.Parameter.NodeConstant; -import org.tron.core.db.Manager; -import org.tron.core.exception.AccountResourceInsufficientException; -import org.tron.core.exception.BadBlockException; -import org.tron.core.exception.BadItemException; -import org.tron.core.exception.BadNumberBlockException; -import org.tron.core.exception.BadTransactionException; -import org.tron.core.exception.ContractExeException; -import org.tron.core.exception.ContractSizeNotEqualToOneException; -import org.tron.core.exception.ContractValidateException; -import org.tron.core.exception.DupTransactionException; -import org.tron.core.exception.ItemNotFoundException; -import org.tron.core.exception.NonCommonBlockException; -import org.tron.core.exception.ReceiptCheckErrException; -import org.tron.core.exception.StoreException; -import org.tron.core.exception.TaposException; -import org.tron.core.exception.TooBigTransactionException; -import org.tron.core.exception.TooBigTransactionResultException; -import org.tron.core.exception.TransactionExpirationException; -import org.tron.core.exception.TronException; -import org.tron.core.exception.UnLinkedBlockException; -import org.tron.core.exception.VMIllegalException; -import org.tron.core.exception.ValidateScheduleException; -import org.tron.core.exception.ValidateSignatureException; -import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.message.MessageTypes; -import org.tron.core.net.message.TransactionMessage; - -@Slf4j -public class NodeDelegateImpl implements NodeDelegate { - - private Manager dbManager; - - public NodeDelegateImpl(Manager dbManager) { - this.dbManager = dbManager; - } - - @Override - public synchronized LinkedList handleBlock(BlockCapsule block, boolean syncMode) - throws BadBlockException, UnLinkedBlockException, InterruptedException, NonCommonBlockException { - - if (block.getInstance().getSerializedSize() > BLOCK_SIZE + 100) { - throw new BadBlockException("block size over limit"); - } - - long gap = block.getTimeStamp() - System.currentTimeMillis(); - if (gap >= BLOCK_PRODUCED_INTERVAL) { - throw new BadBlockException("block time error"); - } - try { - dbManager.preValidateTransactionSign(block); - dbManager.pushBlock(block); - if (!syncMode) { - List trx = null; - trx = block.getTransactions(); - return trx.stream() - .map(TransactionCapsule::getTransactionId) - .collect(Collectors.toCollection(LinkedList::new)); - } else { - return null; - } - - } catch (AccountResourceInsufficientException e) { - throw new BadBlockException("AccountResourceInsufficientException," + e.getMessage()); - } catch (ValidateScheduleException e) { - throw new BadBlockException("validate schedule exception," + e.getMessage()); - } catch (ValidateSignatureException e) { - throw new BadBlockException("validate signature exception," + e.getMessage()); - } catch (ContractValidateException e) { - throw new BadBlockException("ContractValidate exception," + e.getMessage()); - } catch (ContractExeException e) { - throw new BadBlockException("Contract Execute exception," + e.getMessage()); - } catch (TaposException e) { - throw new BadBlockException("tapos exception," + e.getMessage()); - } catch (DupTransactionException e) { - throw new BadBlockException("DupTransaction exception," + e.getMessage()); - } catch (TooBigTransactionException e) { - throw new BadBlockException("TooBigTransaction exception," + e.getMessage()); - } catch (TooBigTransactionResultException e) { - throw new BadBlockException("TooBigTransaction exception," + e.getMessage()); - } catch (TransactionExpirationException e) { - throw new BadBlockException("Expiration exception," + e.getMessage()); - } catch (BadNumberBlockException e) { - throw new BadBlockException("bad number exception," + e.getMessage()); - } catch (ReceiptCheckErrException e) { - throw new BadBlockException("TransactionTrace Exception," + e.getMessage()); - } catch (VMIllegalException e) { - throw new BadBlockException(e.getMessage()); - } - - } - - - @Override - public boolean handleTransaction(TransactionCapsule trx) throws BadTransactionException { - if (dbManager.getDynamicPropertiesStore().supportVM()) { - trx.resetResult(); - } - logger.debug("handle transaction"); - if (dbManager.getTransactionIdCache().getIfPresent(trx.getTransactionId()) != null) { - logger.warn("This transaction has been processed"); - return false; - } else { - dbManager.getTransactionIdCache().put(trx.getTransactionId(), true); - } - try { - dbManager.pushTransaction(trx); - } catch (ContractSizeNotEqualToOneException e) { - logger.info("Contract validate failed" + e.getMessage()); - throw new BadTransactionException(); - } catch (ContractValidateException e) { - logger.info("Contract validate failed" + e.getMessage()); - //throw new BadTransactionException(); - return false; - } catch (ContractExeException e) { - logger.info("Contract execute failed" + e.getMessage()); - //throw new BadTransactionException(); - return false; - } catch (ValidateSignatureException e) { - logger.info("ValidateSignatureException" + e.getMessage()); - throw new BadTransactionException(); - } catch (AccountResourceInsufficientException e) { - logger.info("AccountResourceInsufficientException" + e.getMessage()); - return false; - } catch (DupTransactionException e) { - logger.info("Dup trans" + e.getMessage()); - return false; - } catch (TaposException e) { - logger.info("Tapos error" + e.getMessage()); - return false; - } catch (TooBigTransactionException e) { - logger.info("Too big transaction" + e.getMessage()); - return false; - } catch (TransactionExpirationException e) { - logger.info("Expiration transaction" + e.getMessage()); - return false; - } catch (ReceiptCheckErrException e) { - logger.info("ReceiptCheckErrException Exception" + e.getMessage()); - return false; - } catch (VMIllegalException e) { - logger.warn(e.getMessage()); - throw new BadTransactionException(); - } catch (TooBigTransactionResultException e) { - logger.info("Too big transactionresult" + e.getMessage()); - return false; - } - - return true; - } - - @Override - public LinkedList getLostBlockIds(List blockChainSummary) - throws StoreException { - - if (dbManager.getHeadBlockNum() == 0) { - return new LinkedList<>(); - } - - BlockId unForkedBlockId; - - if (blockChainSummary.isEmpty() || - (blockChainSummary.size() == 1 - && blockChainSummary.get(0).equals(dbManager.getGenesisBlockId()))) { - unForkedBlockId = dbManager.getGenesisBlockId(); - } else if (blockChainSummary.size() == 1 - && blockChainSummary.get(0).getNum() == 0) { - return new LinkedList(Arrays.asList(dbManager.getGenesisBlockId())); - } else { - - Collections.reverse(blockChainSummary); - unForkedBlockId = blockChainSummary.stream() - .filter(blockId -> containBlockInMainChain(blockId)) - .findFirst().orElse(null); - if (unForkedBlockId == null) { - return new LinkedList<>(); - } - } - - long unForkedBlockIdNum = unForkedBlockId.getNum(); - long len = Longs - .min(dbManager.getHeadBlockNum(), unForkedBlockIdNum + NodeConstant.SYNC_FETCH_BATCH_NUM); - - LinkedList blockIds = new LinkedList<>(); - for (long i = unForkedBlockIdNum; i <= len; i++) { - BlockId id = dbManager.getBlockIdByNum(i); - blockIds.add(id); - } - return blockIds; - } - - @Override - public Deque getBlockChainSummary(BlockId beginBlockId, Deque blockIdsToFetch) - throws TronException { - - Deque retSummary = new LinkedList<>(); - List blockIds = new ArrayList<>(blockIdsToFetch); - long highBlkNum; - long highNoForkBlkNum; - long syncBeginNumber = dbManager.getSyncBeginNumber(); - long lowBlkNum = syncBeginNumber < 0 ? 0 : syncBeginNumber; - - LinkedList forkList = new LinkedList<>(); - - if (!beginBlockId.equals(getGenesisBlock().getBlockId())) { - if (containBlockInMainChain(beginBlockId)) { - highBlkNum = beginBlockId.getNum(); - if (highBlkNum == 0) { - throw new TronException( - "This block don't equal my genesis block hash, but it is in my DB, the block id is :" - + beginBlockId.getString()); - } - highNoForkBlkNum = highBlkNum; - if (beginBlockId.getNum() < lowBlkNum) { - lowBlkNum = beginBlockId.getNum(); - } - } else { - forkList = dbManager.getBlockChainHashesOnFork(beginBlockId); - if (forkList.isEmpty()) { - throw new UnLinkedBlockException( - "We want to find forkList of this block: " + beginBlockId.getString() - + " ,but in KhasoDB we can not find it, It maybe a very old beginBlockId, we are sync once," - + " we switch and pop it after that time. "); - } - highNoForkBlkNum = forkList.peekLast().getNum(); - forkList.pollLast(); - Collections.reverse(forkList); - highBlkNum = highNoForkBlkNum + forkList.size(); - if (highNoForkBlkNum < lowBlkNum) { - throw new UnLinkedBlockException( - "It is a too old block that we take it as a forked block long long ago" - + "\n lowBlkNum:" + lowBlkNum - + "\n highNoForkBlkNum" + highNoForkBlkNum); - } - } - } else { - highBlkNum = dbManager.getHeadBlockNum(); - highNoForkBlkNum = highBlkNum; - - } - - if (!blockIds.isEmpty() && highBlkNum != blockIds.get(0).getNum() - 1) { - logger.error("Check ERROR: highBlkNum:" + highBlkNum + ",blockIdToSyncFirstNum is " - + blockIds.get(0).getNum() + ",blockIdToSyncEnd is " + blockIds.get(blockIds.size() - 1) - .getNum()); - } - - long realHighBlkNum = highBlkNum + blockIds.size(); - do { - if (lowBlkNum <= highNoForkBlkNum) { - retSummary.offer(dbManager.getBlockIdByNum(lowBlkNum)); - } else if (lowBlkNum <= highBlkNum) { - retSummary.offer(forkList.get((int) (lowBlkNum - highNoForkBlkNum - 1))); - } else { - retSummary.offer(blockIds.get((int) (lowBlkNum - highBlkNum - 1))); - } - lowBlkNum += (realHighBlkNum - lowBlkNum + 2) / 2; - } while (lowBlkNum <= realHighBlkNum); - - return retSummary; - } - - @Override - public Message getData(Sha256Hash hash, MessageTypes type) - throws StoreException { - switch (type) { - case BLOCK: - return new BlockMessage(dbManager.getBlockById(hash)); - case TRX: - TransactionCapsule tx = dbManager.getTransactionStore().get(hash.getBytes()); - if (tx != null) { - return new TransactionMessage(tx.getData()); - } - throw new ItemNotFoundException("transaction is not found"); - default: - throw new BadItemException("message type not block or trx."); - } - } - - @Override - public void syncToCli(long unSyncNum) { - logger.info("There are " + unSyncNum + " blocks we need to sync."); - if (unSyncNum == 0) { - logger.info("Sync Block Completed !!!"); - } - dbManager.setSyncMode(unSyncNum == 0); - } - - @Override - public long getBlockTime(BlockId id) { - try { - return dbManager.getBlockById(id).getTimeStamp(); - } catch (BadItemException e) { - return dbManager.getGenesisBlock().getTimeStamp(); - } catch (ItemNotFoundException e) { - return dbManager.getGenesisBlock().getTimeStamp(); - } - } - - @Override - public BlockId getHeadBlockId() { - return dbManager.getHeadBlockId(); - } - - @Override - public BlockId getSolidBlockId() { - return dbManager.getSolidBlockId(); - } - - @Override - public long getHeadBlockTimeStamp() { - return dbManager.getHeadBlockTimeStamp(); - } - - @Override - public boolean containBlock(BlockId id) { - return dbManager.containBlock(id); - } - - @Override - public boolean containBlockInMainChain(BlockId id) { - return dbManager.containBlockInMainChain(id); - } - - @Override - public boolean contain(Sha256Hash hash, MessageTypes type) { - if (type.equals(MessageTypes.BLOCK)) { - return dbManager.containBlock(hash); - } else if (type.equals(MessageTypes.TRX)) { - return dbManager.getTransactionStore().has(hash.getBytes()); - } - return false; - } - - @Override - public BlockCapsule getGenesisBlock() { - return dbManager.getGenesisBlock(); - } - - @Override - public boolean canChainRevoke(long num) { - return num >= dbManager.getSyncBeginNumber(); - } -} diff --git a/src/main/java/org/tron/core/net/node/NodeImpl.java b/src/main/java/org/tron/core/net/node/NodeImpl.java deleted file mode 100644 index a07696a2e26..00000000000 --- a/src/main/java/org/tron/core/net/node/NodeImpl.java +++ /dev/null @@ -1,1352 +0,0 @@ -package org.tron.core.net.node; - -import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; -import static org.tron.core.config.Parameter.NetConstants.MAX_TRX_PER_PEER; -import static org.tron.core.config.Parameter.NetConstants.MSG_CACHE_DURATION_IN_BLOCKS; -import static org.tron.core.config.Parameter.NodeConstant.MAX_BLOCKS_SYNC_FROM_ONE_PEER; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import java.util.Collection; -import java.util.Comparator; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import java.util.stream.Collectors; -import javafx.util.Pair; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.CollectionUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.tron.common.overlay.discover.node.statistics.MessageCount; -import org.tron.common.overlay.message.Message; -import org.tron.common.overlay.server.Channel.TronState; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.ExecutorLoop; -import org.tron.common.utils.Sha256Hash; -import org.tron.common.utils.SlidingWindowCounter; -import org.tron.common.utils.Time; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.capsule.BlockCapsule.BlockId; -import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.config.Parameter.ChainConstant; -import org.tron.core.config.Parameter.NetConstants; -import org.tron.core.config.Parameter.NodeConstant; -import org.tron.core.config.args.Args; -import org.tron.core.exception.BadBlockException; -import org.tron.core.exception.BadTransactionException; -import org.tron.core.exception.NonCommonBlockException; -import org.tron.core.exception.StoreException; -import org.tron.core.exception.TraitorPeerException; -import org.tron.core.exception.TronException; -import org.tron.core.exception.UnLinkedBlockException; -import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.message.ChainInventoryMessage; -import org.tron.core.net.message.FetchInvDataMessage; -import org.tron.core.net.message.InventoryMessage; -import org.tron.core.net.message.ItemNotFound; -import org.tron.core.net.message.MessageTypes; -import org.tron.core.net.message.SyncBlockChainMessage; -import org.tron.core.net.message.TransactionMessage; -import org.tron.core.net.message.TransactionsMessage; -import org.tron.core.net.message.TronMessage; -import org.tron.core.net.messagehandler.TransactionsMsgHandler; -import org.tron.core.net.peer.Item; -import org.tron.core.net.peer.PeerConnection; -import org.tron.core.services.WitnessProductBlockService; -import org.tron.protos.Protocol; -import org.tron.protos.Protocol.Inventory.InventoryType; -import org.tron.protos.Protocol.ReasonCode; - -@Slf4j -@Component -public class NodeImpl extends PeerConnectionDelegate implements Node { - - @Autowired - private TransactionsMsgHandler transactionsMsgHandler; - - @Autowired - private SyncPool pool; - - @Autowired - private WitnessProductBlockService witnessProductBlockService; - - private MessageCount trxCount = new MessageCount(); - - private Cache TrxCache = CacheBuilder.newBuilder() - .maximumSize(50_000).expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(50_000) - .recordStats().build(); - - private Cache BlockCache = CacheBuilder.newBuilder() - .maximumSize(10).expireAfterWrite(60, TimeUnit.SECONDS) - .recordStats().build(); - - private SlidingWindowCounter fetchWaterLine = - new SlidingWindowCounter(BLOCK_PRODUCED_INTERVAL * MSG_CACHE_DURATION_IN_BLOCKS / 100); - - private int maxTrxsSize = 1_000_000; - - private int maxTrxsCnt = 100; - - private long blockUpdateTimeout = 20_000; - - @Getter - class PriorItem implements java.lang.Comparable { - - private long count; - - private Item item; - - private long time; - - public Sha256Hash getHash() { - return item.getHash(); - } - - public InventoryType getType() { - return item.getType(); - } - - public PriorItem(Item item, long count) { - this.item = item; - this.count = count; - this.time = Time.getCurrentMillis(); - } - - public void refreshTime() { - this.time = Time.getCurrentMillis(); - } - - @Override - public int compareTo(final PriorItem o) { - if (!this.item.getType().equals(o.getItem().getType())) { - return this.item.getType().equals(InventoryType.BLOCK) ? -1 : 1; - } - return Long.compare(this.count, o.getCount()); - } - } - - class InvToSend { - - private HashMap>> send - = new HashMap<>(); - - public void clear() { - this.send.clear(); - } - - public void add(Entry id, PeerConnection peer) { - if (send.containsKey(peer) && !send.get(peer).containsKey(id.getValue())) { - send.get(peer).put(id.getValue(), new LinkedList<>()); - } else if (!send.containsKey(peer)) { - send.put(peer, new HashMap<>()); - send.get(peer).put(id.getValue(), new LinkedList<>()); - } - send.get(peer).get(id.getValue()).offer(id.getKey()); - } - - public void add(PriorItem id, PeerConnection peer) { - if (send.containsKey(peer) && !send.get(peer).containsKey(id.getType())) { - send.get(peer).put(id.getType(), new LinkedList<>()); - } else if (!send.containsKey(peer)) { - send.put(peer, new HashMap<>()); - send.get(peer).put(id.getType(), new LinkedList<>()); - } - send.get(peer).get(id.getType()).offer(id.getHash()); - } - - public int getSize(PeerConnection peer) { - if (send.containsKey(peer)) { - return send.get(peer).values().stream().mapToInt(LinkedList::size).sum(); - } - - return 0; - } - - void sendInv() { - send.forEach((peer, ids) -> - ids.forEach((key, value) -> { - if (key.equals(InventoryType.BLOCK)) { - value.sort(Comparator.comparingLong(value1 -> new BlockId(value1).getNum())); - } - peer.sendMessage(new InventoryMessage(value, key)); - })); - } - - void sendFetch() { - send.forEach((peer, ids) -> - ids.forEach((key, value) -> { - if (key.equals(InventoryType.BLOCK)) { - value.sort(Comparator.comparingLong(value1 -> new BlockId(value1).getNum())); - } - peer.sendMessage(new FetchInvDataMessage(value, key)); - })); - } - } - - private ScheduledExecutorService logExecutor = Executors.newSingleThreadScheduledExecutor(); - - private ExecutorService trxsHandlePool = Executors - .newFixedThreadPool(Args.getInstance().getValidateSignThreadNum(), - new ThreadFactoryBuilder() - .setNameFormat("TrxsHandlePool-%d").build()); - - private Queue freshBlockId = new ConcurrentLinkedQueue() { - @Override - public boolean offer(BlockId blockId) { - if (size() > 200) { - super.poll(); - } - return super.offer(blockId); - } - }; - - private ConcurrentHashMap syncMap = new ConcurrentHashMap<>(); - - private ConcurrentHashMap fetchMap = new ConcurrentHashMap<>(); - - private NodeDelegate del; - - private volatile boolean isAdvertiseActive; - - private volatile boolean isFetchActive; - - - private ScheduledExecutorService disconnectInactiveExecutor = Executors - .newSingleThreadScheduledExecutor(); - - private ScheduledExecutorService cleanInventoryExecutor = Executors - .newSingleThreadScheduledExecutor(); - - //broadcast - private ConcurrentHashMap advObjToSpread = new ConcurrentHashMap<>(); - - private HashMap advObjWeRequested = new HashMap<>(); - - private ConcurrentHashMap advObjToFetch = new ConcurrentHashMap(); - - private ExecutorService broadPool = Executors.newFixedThreadPool(2, new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "broad-msg"); - } - }); - - private Cache syncBlockIdWeRequested = CacheBuilder.newBuilder() - .maximumSize(10000).expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(10000) - .recordStats().build(); - - private Long unSyncNum = 0L; - - private Map blockWaitToProc = new ConcurrentHashMap<>(); - - private Map blockJustReceived = new ConcurrentHashMap<>(); - - private ExecutorLoop loopSyncBlockChain; - - private ExecutorLoop loopFetchBlocks; - - private ExecutorLoop loopAdvertiseInv; - - private ScheduledExecutorService fetchSyncBlocksExecutor = Executors - .newSingleThreadScheduledExecutor(); - - private ScheduledExecutorService handleSyncBlockExecutor = Executors - .newSingleThreadScheduledExecutor(); - - private ScheduledExecutorService fetchWaterLineExecutor = Executors - .newSingleThreadScheduledExecutor(); - - private volatile boolean isHandleSyncBlockActive = false; - - private AtomicLong fetchSequenceCounter = new AtomicLong(0L); - - private volatile boolean isSuspendFetch = false; - - private volatile boolean isFetchSyncActive = false; - - @Override - public void onMessage(PeerConnection peer, TronMessage msg) { - switch (msg.getType()) { - case BLOCK: - onHandleBlockMessage(peer, (BlockMessage) msg); - break; - case TRXS: - transactionsMsgHandler.processMessage(peer, msg); - break; - case SYNC_BLOCK_CHAIN: - onHandleSyncBlockChainMessage(peer, (SyncBlockChainMessage) msg); - break; - case FETCH_INV_DATA: - onHandleFetchDataMessage(peer, (FetchInvDataMessage) msg); - break; - case BLOCK_CHAIN_INVENTORY: - onHandleChainInventoryMessage(peer, (ChainInventoryMessage) msg); - break; - case INVENTORY: - onHandleInventoryMessage(peer, (InventoryMessage) msg); - break; - default: - throw new IllegalArgumentException("No such message"); - } - } - - @Override - public Message getMessage(Sha256Hash msgId) { - return null; - } - - - @Override - public void setNodeDelegate(NodeDelegate nodeDel) { - this.del = nodeDel; - } - - // for test only - public void setPool(SyncPool pool) { - this.pool = pool; - } - - public void broadcast(Message msg) { - InventoryType type; - if (msg instanceof BlockMessage) { - logger.info("Ready to broadcast block {}", ((BlockMessage) msg).getBlockId()); - freshBlockId.offer(((BlockMessage) msg).getBlockId()); - BlockCache.put(msg.getMessageId(), (BlockMessage) msg); - type = InventoryType.BLOCK; - } else if (msg instanceof TransactionMessage) { - TrxCache.put(msg.getMessageId(), (TransactionMessage) msg); - type = InventoryType.TRX; - } else { - return; - } - synchronized (advObjToSpread) { - advObjToSpread.put(msg.getMessageId(), type); - } - } - - @Override - public void listen() { - pool.init(this); - transactionsMsgHandler.init(this); - isAdvertiseActive = true; - isFetchActive = true; - activeTronPump(); - } - - @Override - public void close() { - getActivePeer().forEach(peer -> disconnectPeer(peer, ReasonCode.REQUESTED)); - } - - private void activeTronPump() { - loopAdvertiseInv = new ExecutorLoop<>(2, 10, b -> { - for (PeerConnection peer : getActivePeer()) { - if (!peer.isNeedSyncFromUs()) { - logger.info("Advertise adverInv to " + peer); - peer.sendMessage(b); - } - } - }, throwable -> logger.error("Unhandled exception: ", throwable)); - - // fetch blocks - loopFetchBlocks = new ExecutorLoop<>(2, 10, c -> { - logger.info("loop fetch blocks"); - if (fetchMap.containsKey(c.getMessageId())) { - fetchMap.get(c.getMessageId()).sendMessage(c); - } - }, throwable -> logger.error("Unhandled exception: ", throwable)); - - // sync block chain - loopSyncBlockChain = new ExecutorLoop<>(2, 10, d -> { - if (syncMap.containsKey(d.getMessageId())) { - syncMap.get(d.getMessageId()).sendMessage(d); - } - }, throwable -> logger.error("Unhandled exception: ", throwable)); - - broadPool.submit(() -> { - while (isAdvertiseActive) { - consumerAdvObjToSpread(); - } - }); - - broadPool.submit(() -> { - while (isFetchActive) { - consumerAdvObjToFetch(); - } - }); - - handleSyncBlockExecutor.scheduleWithFixedDelay(() -> { - try { - if (isHandleSyncBlockActive) { - isHandleSyncBlockActive = false; - handleSyncBlock(); - } - } catch (Throwable t) { - logger.error("Unhandled exception", t); - } - }, 10, 1, TimeUnit.SECONDS); - - //terminate inactive loop - disconnectInactiveExecutor.scheduleWithFixedDelay(() -> { - try { - disconnectInactive(); - } catch (Throwable t) { - logger.error("Unhandled exception", t); - } - }, 30000, BLOCK_PRODUCED_INTERVAL / 2, TimeUnit.MILLISECONDS); - - logExecutor.scheduleWithFixedDelay(() -> { - try { - logNodeStatus(); - } catch (Throwable t) { - logger.error("Exception in log worker", t); - } - }, 10, 10, TimeUnit.SECONDS); - - cleanInventoryExecutor.scheduleWithFixedDelay(() -> { - try { - getActivePeer().forEach(p -> p.cleanInvGarbage()); - } catch (Throwable t) { - logger.error("Unhandled exception", t); - } - }, 2, NetConstants.MAX_INVENTORY_SIZE_IN_MINUTES / 2, TimeUnit.MINUTES); - - fetchSyncBlocksExecutor.scheduleWithFixedDelay(() -> { - try { - if (isFetchSyncActive) { - if (!isSuspendFetch) { - startFetchSyncBlock(); - } else { - logger.debug("suspend"); - } - } - isFetchSyncActive = false; - } catch (Throwable t) { - logger.error("Unhandled exception", t); - } - }, 10, 1, TimeUnit.SECONDS); - - //fetchWaterLine: - fetchWaterLineExecutor.scheduleWithFixedDelay(() -> { - try { - fetchWaterLine.advance(); - } catch (Throwable t) { - logger.error("Unhandled exception", t); - } - }, 1000, 100, TimeUnit.MILLISECONDS); - } - - private void consumerAdvObjToFetch() { - Collection filterActivePeer = getActivePeer().stream() - .filter(peer -> !peer.isBusy()).collect(Collectors.toList()); - - if (advObjToFetch.isEmpty() || filterActivePeer.isEmpty()) { - try { - Thread.sleep(100); - return; - } catch (InterruptedException e) { - logger.debug(e.getMessage(), e); - } - } - InvToSend sendPackage = new InvToSend(); - long now = Time.getCurrentMillis(); - advObjToFetch.values().stream().sorted(PriorItem::compareTo).forEach(idToFetch -> { - Sha256Hash hash = idToFetch.getHash(); - if (idToFetch.getTime() < now - MSG_CACHE_DURATION_IN_BLOCKS * BLOCK_PRODUCED_INTERVAL) { - logger.info("This obj is too late to fetch, type: {} hash: {}.", idToFetch.getType(), - idToFetch.getHash()); - advObjToFetch.remove(hash); - return; - } - filterActivePeer.stream() - .filter(peer -> peer.getAdvObjSpreadToUs().containsKey(hash) - && sendPackage.getSize(peer) < MAX_TRX_PER_PEER) - .sorted(Comparator.comparingInt(peer -> sendPackage.getSize(peer))) - .findFirst().ifPresent(peer -> { - sendPackage.add(idToFetch, peer); - peer.getAdvObjWeRequested().put(idToFetch.getItem(), now); - advObjToFetch.remove(hash); - }); - }); - - sendPackage.sendFetch(); - } - - private void consumerAdvObjToSpread() { - if (advObjToSpread.isEmpty()) { - try { - Thread.sleep(100); - return; - } catch (InterruptedException e) { - logger.debug(e.getMessage(), e); - } - } - InvToSend sendPackage = new InvToSend(); - HashMap spread = new HashMap<>(); - synchronized (advObjToSpread) { - spread.putAll(advObjToSpread); - advObjToSpread.clear(); - } - for (InventoryType type : spread.values()) { - if (type == InventoryType.TRX) { - trxCount.add(); - } - } - getActivePeer().stream() - .filter(peer -> !peer.isNeedSyncFromUs()) - .forEach(peer -> - spread.entrySet().stream() - .filter(idToSpread -> - !peer.getAdvObjSpreadToUs().containsKey(idToSpread.getKey()) - && !peer.getAdvObjWeSpread().containsKey(idToSpread.getKey())) - .forEach(idToSpread -> { - peer.getAdvObjWeSpread().put(idToSpread.getKey(), Time.getCurrentMillis()); - sendPackage.add(idToSpread, peer); - })); - sendPackage.sendInv(); - } - - private synchronized void handleSyncBlock() { - if (isSuspendFetch) { - isSuspendFetch = false; - } - - final boolean[] isBlockProc = {true}; - - while (isBlockProc[0]) { - - isBlockProc[0] = false; - - synchronized (blockJustReceived) { - blockWaitToProc.putAll(blockJustReceived); - blockJustReceived.clear(); - } - - blockWaitToProc.forEach((msg, peerConnection) -> { - - if (peerConnection.isDisconnect()) { - logger.error("Peer {} is disconnect, drop block {}", peerConnection.getNode().getHost(), - msg.getBlockId().getString()); - blockWaitToProc.remove(msg); - syncBlockIdWeRequested.invalidate(msg.getBlockId()); - isFetchSyncActive = true; - return; - } - - synchronized (freshBlockId) { - final boolean[] isFound = {false}; - getActivePeer().stream() - .filter( - peer -> !peer.getSyncBlockToFetch().isEmpty() && peer.getSyncBlockToFetch().peek() - .equals(msg.getBlockId())) - .forEach(peer -> { - peer.getSyncBlockToFetch().pop(); - peer.getBlockInProc().add(msg.getBlockId()); - isFound[0] = true; - }); - if (isFound[0]) { - blockWaitToProc.remove(msg); - isBlockProc[0] = true; - if (freshBlockId.contains(msg.getBlockId()) || processSyncBlock( - msg.getBlockCapsule())) { - finishProcessSyncBlock(msg.getBlockCapsule()); - } - } - } - }); - - } - } - - private synchronized void logNodeStatus() { - StringBuilder sb = new StringBuilder("LocalNode stats:\n"); - sb.append("============\n"); - - sb.append(String.format( - "MyHeadBlockNum: %d\n" - + "advObjToSpread: %d\n" - + "advObjToFetch: %d\n" - + "advObjWeRequested: %d\n" - + "unSyncNum: %d\n" - + "blockWaitToProc: %d\n" - + "blockJustReceived: %d\n" - + "syncBlockIdWeRequested: %d\n", - del.getHeadBlockId().getNum(), - advObjToSpread.size(), - advObjToFetch.size(), - advObjWeRequested.size(), - getUnSyncNum(), - blockWaitToProc.size(), - blockJustReceived.size(), - syncBlockIdWeRequested.size() - )); - - logger.info(sb.toString()); - } - - public synchronized void disconnectInactive() { - - getActivePeer().forEach(peer -> { - final boolean[] isDisconnected = {false}; - - if (peer.isNeedSyncFromPeer() - && peer.getLastBlockUpdateTime() < System.currentTimeMillis() - blockUpdateTimeout) { - logger.warn("Peer {} not sync for a long time.", peer.getInetAddress()); - isDisconnected[0] = true; - } - - peer.getAdvObjWeRequested().values().stream() - .filter(time -> time < Time.getCurrentMillis() - NetConstants.ADV_TIME_OUT) - .findFirst().ifPresent(time -> isDisconnected[0] = true); - - if (!isDisconnected[0]) { - peer.getSyncBlockRequested().values().stream() - .filter(time -> time < Time.getCurrentMillis() - NetConstants.SYNC_TIME_OUT) - .findFirst().ifPresent(time -> isDisconnected[0] = true); - } - - if (isDisconnected[0]) { - disconnectPeer(peer, ReasonCode.TIME_OUT); - } - }); - } - - - private void onHandleInventoryMessage(PeerConnection peer, InventoryMessage msg) { - if (transactionsMsgHandler.isBusy() && msg.getInventoryType().equals(InventoryType.TRX)) { - logger.warn("Too many trx msg to handle, drop inventory msg from peer {}, size {}", - peer.getInetAddress(), msg.getHashList().size()); - return; - } - for (Sha256Hash id : msg.getHashList()) { - if (msg.getInventoryType().equals(InventoryType.TRX) && TrxCache.getIfPresent(id) != null) { - logger.info("{} {} from peer {} Already exist.", msg.getInventoryType(), id, - peer.getNode().getHost()); - continue; - } - final boolean[] spreaded = {false}; - final boolean[] requested = {false}; - getActivePeer().forEach(p -> { - if (p.getAdvObjWeSpread().containsKey(id)) { - spreaded[0] = true; - } - if (p.getAdvObjWeRequested().containsKey(new Item(id, msg.getInventoryType()))) { - requested[0] = true; - } - }); - - if (!spreaded[0] - && !peer.isNeedSyncFromPeer() - && !peer.isNeedSyncFromUs()) { - - //avoid TRX flood attack here. -// if (msg.getInventoryType().equals(InventoryType.TRX) -// && (peer.isAdvInvFull() || isFlooded())) { -// logger.warn("A peer is flooding us, stop handle inv, the peer is: " + peer); -// return; -// } - - peer.getAdvObjSpreadToUs().put(id, System.currentTimeMillis()); - if (!requested[0]) { - PriorItem targetPriorItem = this.advObjToFetch.get(id); - if (targetPriorItem != null) { - //another peer tell this trx to us, refresh its time. - targetPriorItem.refreshTime(); - } else { - fetchWaterLine.increase(); - this.advObjToFetch.put(id, new PriorItem(new Item(id, msg.getInventoryType()), - fetchSequenceCounter.incrementAndGet())); - } - } - } - } - } - - private boolean isFlooded() { - return fetchWaterLine.totalCount() - > BLOCK_PRODUCED_INTERVAL - * Args.getInstance().getNetMaxTrxPerSecond() - * MSG_CACHE_DURATION_IN_BLOCKS - / 1000; - } - - @Override - public void syncFrom(Sha256Hash myHeadBlockHash) { - try { - while (getActivePeer().isEmpty()) { - logger.info("other peer is nil, please wait ... "); - Thread.sleep(10000L); - } - } catch (InterruptedException e) { - logger.debug(e.getMessage(), e); - } - logger.info("wait end"); - } - - private void onHandleBlockMessage(PeerConnection peer, BlockMessage blkMsg) { - Map advObjWeRequested = peer.getAdvObjWeRequested(); - Map syncBlockRequested = peer.getSyncBlockRequested(); - BlockId blockId = blkMsg.getBlockId(); - Item item = new Item(blockId, InventoryType.BLOCK); - boolean syncFlag = false; - if (syncBlockRequested.containsKey(blockId)) { - if (!peer.getSyncFlag()) { - logger.info("Received a block {} from no need sync peer {}", blockId.getNum(), - peer.getNode().getHost()); - return; - } - peer.getSyncBlockRequested().remove(blockId); - synchronized (blockJustReceived) { - blockJustReceived.put(blkMsg, peer); - } - isHandleSyncBlockActive = true; - syncFlag = true; - if (!peer.isBusy()) { - if (peer.getUnfetchSyncNum() > 0 - && peer.getSyncBlockToFetch().size() <= NodeConstant.SYNC_FETCH_BATCH_NUM) { - syncNextBatchChainIds(peer); - } else { - isFetchSyncActive = true; - } - } - } - if (advObjWeRequested.containsKey(item)) { - advObjWeRequested.remove(item); - if (!syncFlag) { - processAdvBlock(peer, blkMsg.getBlockCapsule()); - startFetchItem(); - } - } - } - - private void processAdvBlock(PeerConnection peer, BlockCapsule block) { - synchronized (freshBlockId) { - if (!freshBlockId.contains(block.getBlockId())) { - try { - witnessProductBlockService.validWitnessProductTwoBlock(block); - LinkedList trxIds = null; - trxIds = del.handleBlock(block, false); - freshBlockId.offer(block.getBlockId()); - - trxIds.forEach(trxId -> advObjToFetch.remove(trxId)); - - getActivePeer().stream() - .filter(p -> p.getAdvObjSpreadToUs().containsKey(block.getBlockId())) - .forEach(p -> updateBlockWeBothHave(p, block)); - - broadcast(new BlockMessage(block)); - - } catch (BadBlockException e) { - logger.error("We get a bad block {}, from {}, reason is {} ", - block.getBlockId().getString(), peer.getNode().getHost(), e.getMessage()); - disconnectPeer(peer, ReasonCode.BAD_BLOCK); - } catch (UnLinkedBlockException e) { - logger.error("We get a unlinked block {}, from {}, head is {}", block.getBlockId(). - getString(), peer.getNode().getHost(), del.getHeadBlockId().getString()); - startSyncWithPeer(peer); - } catch (NonCommonBlockException e) { - logger.error( - "We get a block {} that do not have the most recent common ancestor with the main chain, from {}, reason is {} ", - block.getBlockId().getString(), peer.getNode().getHost(), e.getMessage()); - disconnectPeer(peer, ReasonCode.FORKED); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - } - } - - private boolean processSyncBlock(BlockCapsule block) { - boolean isAccept = false; - ReasonCode reason = null; - try { - try { - del.handleBlock(block, true); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - freshBlockId.offer(block.getBlockId()); - logger.info("Success handle block {}", block.getBlockId().getString()); - isAccept = true; - } catch (BadBlockException e) { - logger.error("We get a bad block {}, reason is {} ", block.getBlockId().getString(), - e.getMessage()); - reason = ReasonCode.BAD_BLOCK; - } catch (UnLinkedBlockException e) { - logger.error("We get a unlinked block {}, head is {}", block.getBlockId().getString(), - del.getHeadBlockId().getString()); - reason = ReasonCode.UNLINKABLE; - } catch (NonCommonBlockException e) { - logger.error( - "We get a block {} that do not have the most recent common ancestor with the main chain, head is {}", - block.getBlockId().getString(), - del.getHeadBlockId().getString()); - reason = ReasonCode.FORKED; - } - - if (!isAccept) { - ReasonCode finalReason = reason; - getActivePeer().stream() - .filter(peer -> peer.getBlockInProc().contains(block.getBlockId())) - .forEach(peer -> disconnectPeer(peer, finalReason)); - } - isHandleSyncBlockActive = true; - return isAccept; - } - - private void finishProcessSyncBlock(BlockCapsule block) { - getActivePeer().forEach(peer -> { - if (peer.getSyncBlockToFetch().isEmpty() - && peer.getBlockInProc().isEmpty() - && !peer.isNeedSyncFromPeer() - && !peer.isNeedSyncFromUs()) { - startSyncWithPeer(peer); - } else if (peer.getBlockInProc().remove(block.getBlockId())) { - updateBlockWeBothHave(peer, block); - if (peer.getSyncBlockToFetch().isEmpty()) { //send sync to let peer know we are sync. - syncNextBatchChainIds(peer); - } - } - }); - } - - synchronized boolean isTrxExist(TransactionMessage trxMsg) { - if (TrxCache.getIfPresent(trxMsg.getMessageId()) != null) { - return true; - } - TrxCache.put(trxMsg.getMessageId(), trxMsg); - return false; - } - - public void onHandleTransactionMessage(PeerConnection peer, TransactionMessage trxMsg) { - try { - if (isTrxExist(trxMsg)) { - logger.info("Trx {} from Peer {} already processed.", trxMsg.getMessageId(), - peer.getNode().getHost()); - return; - } - TransactionCapsule transactionCapsule = trxMsg.getTransactionCapsule(); - - if (del.handleTransaction(transactionCapsule)) { - broadcast(trxMsg); - } - } catch (BadTransactionException e) { - logger.error("Bad Trx {} from peer {}, error: {}", - trxMsg.getMessageId(), peer.getInetAddress(), e.getMessage()); - banTraitorPeer(peer, ReasonCode.BAD_TX); - } catch (Exception e){ - logger.error("Process trx {} from peer {} failed", - trxMsg.getMessageId(), peer.getInetAddress(), e); - } - } - - private boolean checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage syncMsg) { - long lastBlockNum = syncMsg.getBlockIds().get(syncMsg.getBlockIds().size() - 1).getNum(); - BlockId lastSyncBlockId = peer.getLastSyncBlockId(); - if (lastSyncBlockId != null && lastBlockNum < lastSyncBlockId.getNum()) { - logger.warn("Peer {} receive bad SyncBlockChain message, firstNum {} lastSyncNum {}.", - peer.getInetAddress(), lastBlockNum, lastSyncBlockId.getNum()); - return false; - } - return true; - } - - private void onHandleSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage syncMsg) { - peer.setTronState(TronState.SYNCING); - BlockId headBlockId = del.getHeadBlockId(); - long remainNum = 0; - LinkedList blockIds = new LinkedList<>(); - List summaryChainIds = syncMsg.getBlockIds(); - if (!checkSyncBlockChainMessage(peer, syncMsg)) { - disconnectPeer(peer, ReasonCode.BAD_PROTOCOL); - return; - } - try { - blockIds = del.getLostBlockIds(summaryChainIds); - } catch (StoreException e) { - logger.error(e.getMessage()); - } - - if (blockIds.isEmpty()) { - if (CollectionUtils.isNotEmpty(summaryChainIds) && !del - .canChainRevoke(summaryChainIds.get(0).getNum())) { - logger.info("Node sync block fail, disconnect peer {}, no block {}", peer, - summaryChainIds.get(0).getString()); - peer.disconnect(ReasonCode.SYNC_FAIL); - return; - } else { - peer.setNeedSyncFromUs(false); - } - } else if (blockIds.size() == 1 - && !summaryChainIds.isEmpty() - && (summaryChainIds.contains(blockIds.peekFirst()) - || blockIds.peek().getNum() == 0)) { - peer.setNeedSyncFromUs(false); - } else { - peer.setNeedSyncFromUs(true); - remainNum = del.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); - } - - if (!peer.isNeedSyncFromPeer() - && CollectionUtils.isNotEmpty(summaryChainIds) - && !del.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) - && del.canChainRevoke(summaryChainIds.get(0).getNum())) { - startSyncWithPeer(peer); - } - - if (blockIds.peekLast() == null) { - peer.setLastSyncBlockId(headBlockId); - } else { - peer.setLastSyncBlockId(blockIds.peekLast()); - } - peer.setRemainNum(remainNum); - peer.sendMessage(new ChainInventoryMessage(blockIds, remainNum)); - } - - private boolean checkFetchInvDataMsg(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) { - MessageTypes type = fetchInvDataMsg.getInvMessageType(); - if (type == MessageTypes.TRX) { - int elementCount = peer.getNodeStatistics().messageStatistics.tronInTrxFetchInvDataElement - .getCount(10); - int maxCount = trxCount.getCount(60); - if (elementCount > maxCount) { - logger.warn( - "Check FetchInvDataMsg failed: Peer {} request count {} in 10s gt trx count {} generate in 60s", - peer.getInetAddress(), elementCount, maxCount); - return false; - } - for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - if (!peer.getAdvObjWeSpread().containsKey(hash)) { - logger.warn("Check FetchInvDataMsg failed: Peer {} get trx {} we not spread.", - peer.getInetAddress(), hash); - return false; - } - } - } else { - boolean isAdv = true; - for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - if (!peer.getAdvObjWeSpread().containsKey(hash)) { - isAdv = false; - break; - } - } - if (isAdv) { - MessageCount tronOutAdvBlock = peer.getNodeStatistics().messageStatistics.tronOutAdvBlock; - tronOutAdvBlock.add(fetchInvDataMsg.getHashList().size()); - int outBlockCountIn1min = tronOutAdvBlock.getCount(60); - int producedBlockIn2min = 120_000 / ChainConstant.BLOCK_PRODUCED_INTERVAL; - if (outBlockCountIn1min > producedBlockIn2min) { - logger - .warn("Check FetchInvDataMsg failed: Peer {} outBlockCount {} producedBlockIn2min {}", - peer.getInetAddress(), outBlockCountIn1min, producedBlockIn2min); - return false; - } - } else { - if (!peer.isNeedSyncFromUs()) { - logger.warn("Check FetchInvDataMsg failed: Peer {} not need sync from us.", - peer.getInetAddress()); - return false; - } - for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - long blockNum = new BlockId(hash).getNum(); - long minBlockNum = - peer.getLastSyncBlockId().getNum() - 2 * NodeConstant.SYNC_FETCH_BATCH_NUM; - if (blockNum < minBlockNum) { - logger.warn("Check FetchInvDataMsg failed: Peer {} blockNum {} lt minBlockNum {}", - peer.getInetAddress(), blockNum, minBlockNum); - return false; - } - if (peer.getSyncBlockIdCache().getIfPresent(hash) != null) { - logger.warn("Check FetchInvDataMsg failed: Peer {} blockNum {} hash {} is exist", - peer.getInetAddress(), blockNum, hash); - return false; - } - peer.getSyncBlockIdCache().put(hash, 1); - } - } - } - return true; - } - - private void onHandleFetchDataMessage(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) { - - if (!checkFetchInvDataMsg(peer, fetchInvDataMsg)) { - disconnectPeer(peer, ReasonCode.BAD_PROTOCOL); - return; - } - - MessageTypes type = fetchInvDataMsg.getInvMessageType(); - BlockCapsule block = null; - List transactions = Lists.newArrayList(); - - int size = 0; - - for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - - Message msg; - - if (type == MessageTypes.BLOCK) { - msg = BlockCache.getIfPresent(hash); - } else { - msg = TrxCache.getIfPresent(hash); - } - - if (msg == null) { - try { - msg = del.getData(hash, type); - } catch (StoreException e) { - logger.error("fetch message {} {} failed.", type, hash); - peer.sendMessage(new ItemNotFound()); - //todo,should be disconnect? - return; - } - } - - if (type.equals(MessageTypes.BLOCK)) { - block = ((BlockMessage) msg).getBlockCapsule(); - peer.sendMessage(msg); - } else { - transactions.add(((TransactionMessage) msg).getTransactionCapsule().getInstance()); - size += ((TransactionMessage) msg).getTransactionCapsule().getInstance() - .getSerializedSize(); - if (transactions.size() % maxTrxsCnt == 0 || size > maxTrxsSize) { - peer.sendMessage(new TransactionsMessage(transactions)); - transactions = Lists.newArrayList(); - size = 0; - } - } - } - - if (block != null) { - updateBlockWeBothHave(peer, block); - } - if (transactions.size() > 0) { - peer.sendMessage(new TransactionsMessage(transactions)); - } - } - - private void banTraitorPeer(PeerConnection peer, ReasonCode reason) { - disconnectPeer(peer, reason); //TODO: ban it - } - - private void onHandleChainInventoryMessage(PeerConnection peer, ChainInventoryMessage msg) { - try { - if (peer.getSyncChainRequested() != null) { - Deque blockIdWeGet = new LinkedList<>(msg.getBlockIds()); - if (blockIdWeGet.size() > 0) { - peer.setNeedSyncFromPeer(true); - } - - //check if the peer is a traitor - if (!blockIdWeGet.isEmpty()) { - long num = blockIdWeGet.peek().getNum(); - for (BlockId id : blockIdWeGet) { - if (id.getNum() != num++) { - throw new TraitorPeerException("We get a not continuous block inv from " + peer); - } - } - - if (peer.getSyncChainRequested().getKey().isEmpty()) { - if (blockIdWeGet.peek().getNum() != 1) { - throw new TraitorPeerException( - "We want a block inv starting from beginning from " + peer); - } - } else { - if (!peer.getSyncChainRequested().getKey().contains(blockIdWeGet.peek())) { - throw new TraitorPeerException(String.format( - "We get a unlinked block chain from " + peer - + "\n Our head is " + peer.getSyncChainRequested().getKey().getLast() - .getString() - + "\n Peer give us is " + blockIdWeGet.peek().getString())); - } - } - - if (del.getHeadBlockId().getNum() > 0) { - long maxRemainTime = ChainConstant.CLOCK_MAX_DELAY + System.currentTimeMillis() - del - .getBlockTime(del.getSolidBlockId()); - long maxFutureNum = - maxRemainTime / BLOCK_PRODUCED_INTERVAL + del.getSolidBlockId().getNum(); - if (blockIdWeGet.peekLast().getNum() + msg.getRemainNum() > maxFutureNum) { - throw new TraitorPeerException( - "Block num " + blockIdWeGet.peekLast().getNum() + "+" + msg.getRemainNum() - + " is gt future max num " + maxFutureNum + " from " + peer - + ", maybe the local clock is not right."); - } - } - } - - peer.setSyncChainRequested(null); - if (msg.getRemainNum() == 0 - && (blockIdWeGet.isEmpty() || (blockIdWeGet.size() == 1 && del - .containBlock(blockIdWeGet.peek()))) - && peer.getSyncBlockToFetch().isEmpty() - && peer.getUnfetchSyncNum() == 0) { - peer.setNeedSyncFromPeer(false); - unSyncNum = getUnSyncNum(); - if (unSyncNum == 0) { - del.syncToCli(0); - } - return; - } - - if (!blockIdWeGet.isEmpty() && peer.getSyncBlockToFetch().isEmpty()) { - boolean isFound = false; - - for (PeerConnection peerToCheck : - getActivePeer()) { - if (!peerToCheck.equals(peer) - && !peerToCheck.getSyncBlockToFetch().isEmpty() - && peerToCheck.getSyncBlockToFetch().peekFirst() - .equals(blockIdWeGet.peekFirst())) { - isFound = true; - break; - } - } - - if (!isFound) { - while (!blockIdWeGet.isEmpty() && del.containBlock(blockIdWeGet.peek())) { - updateBlockWeBothHave(peer, blockIdWeGet.peek()); - blockIdWeGet.poll(); - } - } - } else if (!blockIdWeGet.isEmpty()) { - while (!peer.getSyncBlockToFetch().isEmpty()) { - if (!peer.getSyncBlockToFetch().peekLast().equals(blockIdWeGet.peekFirst())) { - peer.getSyncBlockToFetch().pollLast(); - } else { - break; - } - } - - if (peer.getSyncBlockToFetch().isEmpty() && del.containBlock(blockIdWeGet.peek())) { - updateBlockWeBothHave(peer, blockIdWeGet.peek()); - - } - blockIdWeGet.poll(); - } - - peer.setUnfetchSyncNum(msg.getRemainNum()); - peer.getSyncBlockToFetch().addAll(blockIdWeGet); - synchronized (freshBlockId) { - while (!peer.getSyncBlockToFetch().isEmpty() - && freshBlockId.contains(peer.getSyncBlockToFetch().peek())) { - BlockId blockId = peer.getSyncBlockToFetch().pop(); - updateBlockWeBothHave(peer, blockId); - logger.info("Block {} from {} is processed", blockId.getString(), - peer.getNode().getHost()); - } - } - - if (msg.getRemainNum() == 0 && peer.getSyncBlockToFetch().isEmpty()) { - peer.setNeedSyncFromPeer(false); - } - - long newUnSyncNum = getUnSyncNum(); - if (unSyncNum != newUnSyncNum) { - unSyncNum = newUnSyncNum; - del.syncToCli(unSyncNum); - } - - if (msg.getRemainNum() == 0) { - if (!peer.getSyncBlockToFetch().isEmpty()) { - isFetchSyncActive = true; - } else { - //let peer know we are sync. - syncNextBatchChainIds(peer); - } - } else { - if (peer.getSyncBlockToFetch().size() > NodeConstant.SYNC_FETCH_BATCH_NUM) { - isFetchSyncActive = true; - } else { - syncNextBatchChainIds(peer); - } - } - - } else { - throw new TraitorPeerException("We don't send sync request to " + peer); - } - - } catch (TraitorPeerException e) { - logger.error(e.getMessage()); - banTraitorPeer(peer, ReasonCode.BAD_PROTOCOL); - } catch (StoreException e) { - //we try update our both known block but this block is null - //because when we try to switch to this block's fork then fail. - //The reason only is we get a bad block which peer broadcast to us. - logger.error(e.getMessage()); - banTraitorPeer(peer, ReasonCode.BAD_BLOCK); - } - } - - private void startFetchItem() { - - } - - private long getUnSyncNum() { - if (getActivePeer().isEmpty()) { - return 0; - } - return getActivePeer().stream() - .mapToLong(peer -> peer.getUnfetchSyncNum() + peer.getSyncBlockToFetch().size()) - .max() - .getAsLong(); - } - - private synchronized void startFetchSyncBlock() { - HashMap> send = new HashMap<>(); - HashSet request = new HashSet<>(); - - getActivePeer().stream() - .filter(peer -> peer.isNeedSyncFromPeer() && !peer.isBusy()) - .forEach(peer -> { - if (!send.containsKey(peer)) { - send.put(peer, new LinkedList<>()); - } - for (BlockId blockId : peer.getSyncBlockToFetch()) { - if (!request.contains(blockId) - && (syncBlockIdWeRequested.getIfPresent(blockId) == null)) { - send.get(peer).add(blockId); - request.add(blockId); - if (send.get(peer).size() - > MAX_BLOCKS_SYNC_FROM_ONE_PEER) { //Max Blocks peer get one time - break; - } - } - } - }); - - send.forEach((peer, blockIds) -> { - blockIds.forEach(blockId -> { - syncBlockIdWeRequested.put(blockId, System.currentTimeMillis()); - peer.getSyncBlockRequested().put(blockId, System.currentTimeMillis()); - }); - List ids = new LinkedList<>(); - ids.addAll(blockIds); - if (!ids.isEmpty()) { - peer.sendMessage(new FetchInvDataMessage(ids, InventoryType.BLOCK)); - } - }); - - send.clear(); - } - - private void updateBlockWeBothHave(PeerConnection peer, BlockCapsule block) { - logger.info("update peer {} block both we have {}", peer.getNode().getHost(), - block.getBlockId().getString()); - peer.setHeadBlockWeBothHave(block.getBlockId()); - peer.setLastBlockUpdateTime(System.currentTimeMillis()); - } - - private void updateBlockWeBothHave(PeerConnection peer, BlockId blockId) - throws StoreException { - logger.info("update peer {} block both we have, {}", peer.getNode().getHost(), - blockId.getString()); - peer.setHeadBlockWeBothHave(blockId); - long time = ((BlockMessage) del.getData(blockId, MessageTypes.BLOCK)).getBlockCapsule() - .getTimeStamp(); - peer.setLastBlockUpdateTime(System.currentTimeMillis()); - } - - private Collection getActivePeer() { - return pool.getActivePeers(); - } - - private void startSyncWithPeer(PeerConnection peer) { - peer.setNeedSyncFromPeer(true); - peer.getSyncBlockToFetch().clear(); - peer.setUnfetchSyncNum(0); - updateBlockWeBothHave(peer, del.getGenesisBlock()); - peer.setBanned(false); - syncNextBatchChainIds(peer); - } - - private void syncNextBatchChainIds(PeerConnection peer) { - if (peer.getSyncChainRequested() != null) { - logger.info("Peer {} is in sync.", peer.getNode().getHost()); - return; - } - try { - Deque chainSummary = - del.getBlockChainSummary(peer.getHeadBlockWeBothHave(), - peer.getSyncBlockToFetch()); - peer.setSyncChainRequested( - new Pair<>(chainSummary, System.currentTimeMillis())); - peer.sendMessage(new SyncBlockChainMessage((LinkedList) chainSummary)); - } catch (TronException e) { - logger.error("Peer {} sync next batch chainIds failed, error: {}.", peer.getNode().getHost(), - e.getMessage()); - disconnectPeer(peer, ReasonCode.FORKED); - } - } - - @Override - public void onConnectPeer(PeerConnection peer) { - if (peer.getHelloMessage().getHeadBlockId().getNum() > del.getHeadBlockId().getNum()) { - peer.setTronState(TronState.SYNCING); - startSyncWithPeer(peer); - } else { - peer.setTronState(TronState.SYNC_COMPLETED); - } - } - - @Override - public void onDisconnectPeer(PeerConnection peer) { - - if (!peer.getSyncBlockRequested().isEmpty()) { - peer.getSyncBlockRequested().keySet() - .forEach(blockId -> syncBlockIdWeRequested.invalidate(blockId)); - isFetchSyncActive = true; - } - - if (!peer.getAdvObjWeRequested().isEmpty()) { - peer.getAdvObjWeRequested().keySet().forEach(item -> { - if (getActivePeer().stream() - .filter(peerConnection -> !peerConnection.equals(peer)) - .filter(peerConnection -> peerConnection.getInvToUs().contains(item.getHash())) - .findFirst() - .isPresent()) { - advObjToFetch.put(item.getHash(), new PriorItem(item, - fetchSequenceCounter.incrementAndGet())); - } - }); - } - } - - - public void shutDown() { - logExecutor.shutdown(); - trxsHandlePool.shutdown(); - disconnectInactiveExecutor.shutdown(); - cleanInventoryExecutor.shutdown(); - broadPool.shutdown(); - loopSyncBlockChain.shutdown(); - loopFetchBlocks.shutdown(); - loopAdvertiseInv.shutdown(); - fetchSyncBlocksExecutor.shutdown(); - handleSyncBlockExecutor.shutdown(); - } - - private void disconnectPeer(PeerConnection peer, ReasonCode reason) { - peer.disconnect(reason); - } - -} - diff --git a/src/main/java/org/tron/core/net/node/PeerConnectionDelegate.java b/src/main/java/org/tron/core/net/node/PeerConnectionDelegate.java deleted file mode 100644 index 4db31022169..00000000000 --- a/src/main/java/org/tron/core/net/node/PeerConnectionDelegate.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.tron.core.net.node; - -import org.tron.common.overlay.message.Message; -import org.tron.common.utils.Sha256Hash; -import org.tron.core.net.message.TronMessage; -import org.tron.core.net.peer.PeerConnection; - -public abstract class PeerConnectionDelegate { - - public abstract void onMessage(PeerConnection peer, TronMessage msg); - - public abstract Message getMessage(Sha256Hash msgId); - - public abstract void onConnectPeer(PeerConnection peer); - - public abstract void onDisconnectPeer(PeerConnection peer); - -} diff --git a/src/main/java/org/tron/core/services/WitnessService.java b/src/main/java/org/tron/core/services/WitnessService.java index 29668829f14..0ee80cb7dab 100755 --- a/src/main/java/org/tron/core/services/WitnessService.java +++ b/src/main/java/org/tron/core/services/WitnessService.java @@ -32,6 +32,7 @@ import org.tron.core.exception.UnLinkedBlockException; import org.tron.core.exception.ValidateScheduleException; import org.tron.core.exception.ValidateSignatureException; +import org.tron.core.net.TronNetClient; import org.tron.core.net.message.BlockMessage; import org.tron.core.witness.BlockProductionCondition; import org.tron.core.witness.WitnessController; @@ -62,6 +63,8 @@ public class WitnessService implements Service { private BackupServer backupServer; + private TronNetClient tronNetClient; + private AtomicInteger dupBlockCount = new AtomicInteger(0); private AtomicLong dupBlockTime = new AtomicLong(0); private long blockCycle = ChainConstant.BLOCK_PRODUCED_INTERVAL * ChainConstant.MAX_ACTIVE_WITNESS_NUM; @@ -74,6 +77,7 @@ public WitnessService(Application tronApp, TronApplicationContext context) { this.context = context; backupManager = context.getBean(BackupManager.class); backupServer = context.getBean(BackupServer.class); + tronNetClient = context.getBean(TronNetClient.class); generateThread = new Thread(scheduleProductionLoop); manager = tronApp.getDbManager(); manager.setWitnessService(this); @@ -280,7 +284,7 @@ private BlockProductionCondition tryProduceBlock() throws InterruptedException { private void broadcastBlock(BlockCapsule block) { try { - tronApp.getP2pNode().broadcast(new BlockMessage(block.getData())); + tronNetClient.broadcast(new BlockMessage(block.getData())); } catch (Exception ex) { throw new RuntimeException("BroadcastBlock error"); } diff --git a/src/test/java/org/tron/core/net/node/override/PeerClientTest.java b/src/test/java/org/tron/core/net/node/override/PeerClientTest.java index dafc3c2d9b7..3b32bf2eacf 100644 --- a/src/test/java/org/tron/core/net/node/override/PeerClientTest.java +++ b/src/test/java/org/tron/core/net/node/override/PeerClientTest.java @@ -16,7 +16,6 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import org.tron.core.config.args.Args; -import org.tron.core.net.node.NodeImpl; @Component public class PeerClientTest { diff --git a/src/test/java/org/tron/core/net/node/override/TronChannelInitializerTest.java b/src/test/java/org/tron/core/net/node/override/TronChannelInitializerTest.java index 32630b6600b..503eeca8728 100644 --- a/src/test/java/org/tron/core/net/node/override/TronChannelInitializerTest.java +++ b/src/test/java/org/tron/core/net/node/override/TronChannelInitializerTest.java @@ -13,7 +13,6 @@ import org.springframework.stereotype.Component; import org.tron.common.overlay.server.Channel; import org.tron.common.overlay.server.ChannelManager; -import org.tron.core.net.node.NodeImpl; import org.tron.core.net.peer.PeerConnection; @Component From ecd451402a1aa8bfbfc9e935b80d6c12b236e095 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 12 Nov 2018 16:05:35 +0800 Subject: [PATCH 10/41] system integration synchronization module --- src/main/java/org/tron/core/net/TronHandler.java | 8 ++++---- .../core/net/messagehandler/BlockMsgHandler.java | 1 - .../java/org/tron/core/net/peer/PeerConnection.java | 1 - .../java/org/tron/core/services/NodeInfoService.java | 12 ++++++------ 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/tron/core/net/TronHandler.java b/src/main/java/org/tron/core/net/TronHandler.java index d97f47e802e..2a7b3f75a0c 100644 --- a/src/main/java/org/tron/core/net/TronHandler.java +++ b/src/main/java/org/tron/core/net/TronHandler.java @@ -21,10 +21,10 @@ public class TronHandler extends SimpleChannelInboundHandler { private TronNetService tronNetService; - @Autowired - private TronHandler (final ApplicationContext ctx){ - tronNetService = ctx.getBean(TronNetService.class); - } +// @Autowired +// private TronHandler (final ApplicationContext ctx){ +// tronNetService = ctx.getBean(TronNetService.class); +// } @Override public void channelRead0(final ChannelHandlerContext ctx, TronMessage msg) { diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 56ea01b270c..5fe7774ef55 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -82,7 +82,6 @@ private void processBlock(PeerConnection peer, BlockCapsule block) throws Excep } tronProxy.processBlock(block); witnessProductBlockService.validWitnessProductTwoBlock(block); - //trxIds.forEach(trxId -> advObjToFetch.remove(trxId)); tronProxy.getActivePeer().forEach(p -> { if (p.getAdvInvReceive().containsKey(blockId)) { p.setBlockBothHave(blockId); diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index d937dce2227..1f83a280ce7 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -58,7 +58,6 @@ public class PeerConnection extends Channel { @Getter private Map advInvRequest = new ConcurrentHashMap<>(); - @Setter @Getter private BlockId blockBothHave = tronProxy.getGenesisBlockId(); public void setBlockBothHave (BlockId blockId) { diff --git a/src/main/java/org/tron/core/services/NodeInfoService.java b/src/main/java/org/tron/core/services/NodeInfoService.java index d59207e1d8c..c44941189ed 100644 --- a/src/main/java/org/tron/core/services/NodeInfoService.java +++ b/src/main/java/org/tron/core/services/NodeInfoService.java @@ -125,16 +125,16 @@ private void setConnectInfo(NodeInfo nodeInfo) { List peerInfoList = new ArrayList<>(); for (PeerConnection peerConnection : syncPool.getActivePeers()) { PeerInfo peerInfo = new PeerInfo(); - peerInfo.setHeadBlockWeBothHave(peerConnection.getHeadBlockWeBothHave().getString()); + peerInfo.setHeadBlockWeBothHave(peerConnection.getBlockBothHave().getString()); peerInfo.setActive(peerConnection.isActive()); peerInfo.setAvgLatency(peerConnection.getPeerStats().getAvgLatency()); - peerInfo.setBlockInPorcSize(peerConnection.getBlockInProc().size()); + peerInfo.setBlockInPorcSize(peerConnection.getSyncBlockInProcess().size()); peerInfo.setConnectTime(peerConnection.getStartTime()); peerInfo.setDisconnectTimes(peerConnection.getNodeStatistics().getDisconnectTimes()); - peerInfo.setHeadBlockTimeWeBothHave(peerConnection.getHeadBlockTimeWeBothHave()); + //peerInfo.setHeadBlockTimeWeBothHave(peerConnection.getHeadBlockTimeWeBothHave()); peerInfo.setHost(peerConnection.getNode().getHost()); peerInfo.setInFlow(peerConnection.getNodeStatistics().tcpFlow.getTotalCount()); - peerInfo.setLastBlockUpdateTime(peerConnection.getLastBlockUpdateTime()); + peerInfo.setLastBlockUpdateTime(peerConnection.getBlockBothHaveUpdateTime()); peerInfo.setLastSyncBlock(peerConnection.getLastSyncBlockId() == null ? "" : peerConnection.getLastSyncBlockId().getString()); ReasonCode reasonCode = peerConnection.getNodeStatistics() @@ -150,11 +150,11 @@ private void setConnectInfo(NodeInfo nodeInfo) { peerInfo.setRemainNum(peerConnection.getRemainNum()); peerInfo.setScore(peerConnection.getNodeStatistics().getReputation()); peerInfo.setSyncBlockRequestedSize(peerConnection.getSyncBlockRequested().size()); - peerInfo.setSyncFlag(peerConnection.getSyncFlag()); + peerInfo.setSyncFlag(peerConnection.isDisconnect()); peerInfo.setSyncToFetchSize(peerConnection.getSyncBlockToFetch().size()); peerInfo.setSyncToFetchSizePeekNum(peerConnection.getSyncBlockToFetch().size() > 0 ? peerConnection.getSyncBlockToFetch().peek().getNum() : -1); - peerInfo.setUnFetchSynNum(peerConnection.getUnfetchSyncNum()); + peerInfo.setUnFetchSynNum(peerConnection.getRemainNum()); totalFlow += peerConnection.getNodeStatistics().tcpFlow.getTotalCount(); peerInfoList.add(peerInfo); } From 4463f7f6f4ce6a81e4ee118d4738a718aba8911a Mon Sep 17 00:00:00 2001 From: wubin01 Date: Sat, 17 Nov 2018 20:32:36 +0800 Subject: [PATCH 11/41] add Peer Adv --- .../tron/common/overlay/client/PeerClient.java | 2 +- .../common/overlay/server/ChannelManager.java | 1 + .../java/org/tron/core/net/TronNetService.java | 14 ++++++++++++++ .../ChainInventoryMsgHandler.java | 17 ++++++++++------- .../messagehandler/SyncBlockChainMsgHadler.java | 14 +++++++------- .../messagehandler/TransactionsMsgHandler.java | 5 +++++ .../java/org/tron/core/net/peer/PeerAdv.java | 6 ++++++ .../java/org/tron/core/net/peer/PeerSync.java | 16 +++++++++++----- 8 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/tron/common/overlay/client/PeerClient.java b/src/main/java/org/tron/common/overlay/client/PeerClient.java index 1ca6ccf44fb..4ea3cc0030f 100644 --- a/src/main/java/org/tron/common/overlay/client/PeerClient.java +++ b/src/main/java/org/tron/common/overlay/client/PeerClient.java @@ -66,7 +66,7 @@ public ChannelFuture connectAsync(NodeHandler nodeHandler, boolean discoveryMode }); } - public ChannelFuture connectAsync(String host, int port, String remoteId, boolean discoveryMode) { + private ChannelFuture connectAsync(String host, int port, String remoteId, boolean discoveryMode) { logger.info("connect peer {} {} {}", host, port, remoteId); diff --git a/src/main/java/org/tron/common/overlay/server/ChannelManager.java b/src/main/java/org/tron/common/overlay/server/ChannelManager.java index e4782040fdb..70a9011f16b 100644 --- a/src/main/java/org/tron/common/overlay/server/ChannelManager.java +++ b/src/main/java/org/tron/common/overlay/server/ChannelManager.java @@ -167,5 +167,6 @@ public Cache getBadPeers() { public void close() { peerServer.close(); peerClient.close(); + syncPool.close(); } } diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index d8677cd5607..8368d13f5df 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.overlay.server.ChannelManager; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; import org.tron.core.net.message.TronMessage; @@ -21,6 +22,9 @@ @Component public class TronNetService { + @Autowired + private ChannelManager channelManager; + @Autowired private PeerAdv peerAdv; @@ -51,6 +55,16 @@ public void start () { transactionsMsgHandler.init(); } + public void close () { + try { + peerAdv.close(); + peerSync.close(); + transactionsMsgHandler.close(); + }catch (Exception e) { + logger.error("TronNetService closed failed.",e ); + } + } + public void onMessage(PeerConnection peer, TronMessage msg) { try { switch (msg.getType()) { diff --git a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java index 1b22817510d..8bd8752d7c2 100644 --- a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -44,7 +44,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti peer.setNeedSyncFromPeer(true); - peer.setSyncChainRequested(null); + peer.setSyncChainRequested(null); //todo thread sec Deque blockIdWeGet = new LinkedList<>(chainInventoryMessage.getBlockIds()); @@ -71,10 +71,10 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti logger.info("Block {} from {} is processed", blockId.getString(), peer.getNode().getHost()); } } - - if (chainInventoryMessage.getRemainNum() == 0 && peer.getSyncBlockToFetch().isEmpty()) { - peer.setNeedSyncFromPeer(false); - } +// +// if (chainInventoryMessage.getRemainNum() == 0 && peer.getSyncBlockToFetch().isEmpty()) { +// peer.setNeedSyncFromPeer(false); +// } if ((chainInventoryMessage.getRemainNum() == 0 && !peer.getSyncBlockToFetch().isEmpty()) || (chainInventoryMessage.getRemainNum() != 0 && peer.getSyncBlockToFetch().size() > NodeConstant.SYNC_FETCH_BATCH_NUM)) { @@ -94,9 +94,12 @@ private void check(PeerConnection peer, ChainInventoryMessage msg) throws Except throw new P2pException(TypeEnum.BAD_MESSAGE, "blockIds is empty"); } + if (blockIds.size() > NodeConstant.SYNC_FETCH_BATCH_NUM + 1) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "big blockIds size: " + blockIds.size()); + } + if (msg.getRemainNum() == 0 && blockIds.size() < NodeConstant.SYNC_FETCH_BATCH_NUM) { - throw new P2pException(TypeEnum.BAD_MESSAGE, - "remain blockNum: 0, blockIds size: " + blockIds.size()); + throw new P2pException(TypeEnum.BAD_MESSAGE, "remain blockNum: 0, blockIds size: " + blockIds.size()); } long num = blockIds.get(0).getNum(); diff --git a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java index 4e060605703..0fe35f589db 100644 --- a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java +++ b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java @@ -49,18 +49,18 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws Exceptio LinkedList blockIds = getLostBlockIds(summaryChainIds); - if (blockIds.size() == 1 && summaryChainIds.contains(blockIds.get(0))){ + if (blockIds.size() == 1){ peer.setNeedSyncFromUs(false); }else { peer.setNeedSyncFromUs(true); remainNum = tronProxy.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); } - - if (!peer.isNeedSyncFromPeer() - && !tronProxy.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) - && tronProxy.canChainRevoke(summaryChainIds.get(0).getNum())) { - //startSyncWithPeer(peer); - } +// +// if (!peer.isNeedSyncFromPeer() +// && !tronProxy.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) +// && tronProxy.canChainRevoke(summaryChainIds.get(0).getNum())) { +// //startSyncWithPeer(peer); +// } peer.setLastSyncBlockId(blockIds.peekLast()); peer.setRemainNum(remainNum); diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index fdbf425cebe..b66bb451d1f 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -67,6 +67,11 @@ public void init() { handleSmartContract(); } + public void close() { + smartContractExecutor.shutdown(); + logger.info("TransactionsMsgHandler closed."); + } + public boolean isBusy() { return queue.size() > MAX_TRX_SIZE; } diff --git a/src/main/java/org/tron/core/net/peer/PeerAdv.java b/src/main/java/org/tron/core/net/peer/PeerAdv.java index 1afed0335dd..aade680b874 100644 --- a/src/main/java/org/tron/core/net/peer/PeerAdv.java +++ b/src/main/java/org/tron/core/net/peer/PeerAdv.java @@ -79,6 +79,12 @@ public void init () { }, 100, 30, TimeUnit.MILLISECONDS); } + public void close () { + spreadExecutor.shutdown(); + fetchExecutor.shutdown(); + logger.info("PeerAdv closed."); + } + synchronized public boolean addInv (Item item) { InventoryType type = item.getType(); Sha256Hash hash = item.getHash(); diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java index 74109423da6..19094e78540 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -53,9 +53,9 @@ public class PeerSync { .expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(10000) .recordStats().build(); - private ScheduledExecutorService fetchSyncBlocksExecutor = Executors.newSingleThreadScheduledExecutor(); - - private ScheduledExecutorService syncHandleExecutor = Executors.newSingleThreadScheduledExecutor(); + private ScheduledExecutorService fetchExecutor = Executors.newSingleThreadScheduledExecutor(); + + private ScheduledExecutorService blockHandleExecutor = Executors.newSingleThreadScheduledExecutor(); private boolean syncHandleFlag = false; @@ -63,7 +63,7 @@ public class PeerSync { private boolean fetchFlag = false; public void init () { - fetchSyncBlocksExecutor.scheduleWithFixedDelay(() -> { + fetchExecutor.scheduleWithFixedDelay(() -> { try { if (fetchFlag) { startFetchSyncBlock(); @@ -74,7 +74,7 @@ public void init () { } }, 10, 1, TimeUnit.SECONDS); - syncHandleExecutor.scheduleWithFixedDelay(() -> { + blockHandleExecutor.scheduleWithFixedDelay(() -> { try { if (syncHandleFlag) { syncHandleFlag = false; @@ -86,6 +86,12 @@ public void init () { }, 10, 1, TimeUnit.SECONDS); } + public void close () { + fetchExecutor.shutdown(); + blockHandleExecutor.shutdown(); + logger.info("PeerSync closed."); + } + public void startSync(PeerConnection peer) { peer.setTronState(TronState.SYNCING); peer.setNeedSyncFromPeer(true); From cdbc256aa8a0c907cf1a135c29da0f07f3aa5698 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 20 Nov 2018 11:25:23 +0800 Subject: [PATCH 12/41] modify peer adv --- .../java/org/tron/core/config/Parameter.java | 2 +- .../FetchInvDataMsgHandler.java | 4 +- .../messagehandler/InventoryMsgHandler.java | 62 ++++++++++--------- .../TransactionsMsgHandler.java | 28 +++++---- .../java/org/tron/core/net/peer/PeerAdv.java | 52 +++++++--------- 5 files changed, 74 insertions(+), 74 deletions(-) diff --git a/src/main/java/org/tron/core/config/Parameter.java b/src/main/java/org/tron/core/config/Parameter.java index 590dadc7c89..3c3cc2dca87 100644 --- a/src/main/java/org/tron/core/config/Parameter.java +++ b/src/main/java/org/tron/core/config/Parameter.java @@ -46,7 +46,7 @@ interface NetConstants { long HEAD_NUM_CHECK_TIME = 60000L; int MAX_INVENTORY_SIZE_IN_MINUTES = 2; long NET_MAX_TRX_PER_SECOND = 700L; - long MAX_INV_FETCH_PER_PEER = 200L; + int MAX_INV_FETCH_PER_PEER = 1000; int NET_MAX_INV_SIZE_IN_MINUTES = 2; int MSG_CACHE_DURATION_IN_BLOCKS = 5; } diff --git a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index 45768cc089f..9da4039d069 100644 --- a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -51,7 +51,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti FetchInvDataMessage fetchInvDataMsg = (FetchInvDataMessage) msg; - checkFetchInvDataMsg(peer, fetchInvDataMsg); + check(peer, fetchInvDataMsg); InventoryType type = fetchInvDataMsg.getInventoryType(); List transactions = Lists.newArrayList(); @@ -92,7 +92,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti } } - private void checkFetchInvDataMsg(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) throws Exception{ + private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) throws Exception{ MessageTypes type = fetchInvDataMsg.getInvMessageType(); //todo check inv size not gt MAX_INV_FETCH_PER_PEER diff --git a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index b4facd78a43..0939470e469 100644 --- a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -4,6 +4,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.utils.Sha256Hash; +import org.tron.core.config.Parameter.NetConstants; +import org.tron.core.exception.P2pException; +import org.tron.core.exception.P2pException.TypeEnum; import org.tron.core.net.TronProxy; import org.tron.core.net.message.InventoryMessage; import org.tron.core.net.message.TronMessage; @@ -29,43 +32,46 @@ public class InventoryMsgHandler implements TronMsgHandler{ @Override public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { - InventoryMessage inventoryMessage = (InventoryMessage) msg; InventoryType type = inventoryMessage.getInventoryType(); - if (transactionsMsgHandler.isBusy() && type.equals(InventoryType.TRX)) { - logger.warn("Too many trx msg to handle, drop inventory msg from peer {}, size {}", - peer.getInetAddress(), inventoryMessage.getHashList().size()); - return; - } - - int count = peer.getNodeStatistics().messageStatistics.tronInTrxInventoryElement.getCount(10); - if (count > maxCountIn10s) { - logger.warn("Inv is overload from peer {}, size {}", peer.getInetAddress(), count); + if (!check(peer, inventoryMessage)) { return; } for (Sha256Hash id : inventoryMessage.getHashList()) { Item item = new Item(id, type); - boolean spreadFlag = false; - boolean requestFlag = false; - for (PeerConnection p: tronProxy.getActivePeer()) { - if (p.getAdvInvSpread().containsKey(item)) { - spreadFlag = true; - } - if (p.getAdvInvRequest().containsKey(item)) { - requestFlag = true; - } - } - if (!spreadFlag && !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) { - peer.getAdvInvReceive().put(item, System.currentTimeMillis()); - if (!requestFlag) { - if (!peerAdv.addInv(item)) { - logger.info("This item {} from peer {} Already exist.", item, peer.getInetAddress()); - continue; - } - } + peer.getAdvInvReceive().put(item, System.currentTimeMillis()); + if (!peerAdv.addInv(item)) { + logger.info("This item {} from peer {} Already exist.", item, peer.getInetAddress()); } } } + + private boolean check (PeerConnection peer, InventoryMessage inventoryMessage) throws Exception { + InventoryType type = inventoryMessage.getInventoryType(); + int size = inventoryMessage.getHashList().size(); + + if (size > NetConstants.MAX_INV_FETCH_PER_PEER) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "size: " + size); + } + + if (peer.isNeedSyncFromPeer() || peer.isNeedSyncFromUs()) { + logger.warn("Drop inv: {} size: {} from Peer {}, syncFromUs: {}, syncFromPeer: {}.", + type, size, peer.getInetAddress(), peer.isNeedSyncFromUs(), peer.isNeedSyncFromPeer()); + return false; + } + if (transactionsMsgHandler.isBusy() && type.equals(InventoryType.TRX)) { + logger.warn("Drop inv: {} size: {} from Peer {}, transactionsMsgHandler is busy.", + type, size, peer.getInetAddress()); + return false; + } + int count = peer.getNodeStatistics().messageStatistics.tronInTrxInventoryElement.getCount(10); + if (count > maxCountIn10s) { + logger.warn("Drop inv: {} size: {} from Peer {}, Inv count: {} is overload.", + type, size, peer.getInetAddress(), count); + return false; + } + return true; + } } diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index b66bb451d1f..4eaf1cd729d 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -19,6 +19,7 @@ import org.tron.core.net.message.TransactionsMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.Item; +import org.tron.core.net.peer.PeerAdv; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Inventory.InventoryType; import org.tron.protos.Protocol.ReasonCode; @@ -32,11 +33,14 @@ public class TransactionsMsgHandler implements TronMsgHandler { @Autowired private TronProxy tronProxy; - private static int MAX_TRX_SIZE = 10_000; + @Autowired + private PeerAdv peerAdv; + + private static int MAX_TRX_SIZE = 50_000; private static int MAX_SMART_CONTRACT_SUBMIT_SIZE = 100; - private static int TIME_OUT = 10 * 60 * 1000; +// private static int TIME_OUT = 10 * 60 * 1000; private BlockingQueue smartContractQueue = new LinkedBlockingQueue(MAX_TRX_SIZE); @@ -73,7 +77,7 @@ public void close() { } public boolean isBusy() { - return queue.size() > MAX_TRX_SIZE; + return queue.size() + smartContractQueue.size() > MAX_TRX_SIZE; } @Override @@ -107,10 +111,10 @@ private void handleSmartContract() { try { while (queue.size() < MAX_SMART_CONTRACT_SUBMIT_SIZE) { TrxEvent event = smartContractQueue.take(); - if (System.currentTimeMillis() - event.getTime() > TIME_OUT) { - logger.warn("Drop smart contract {} from peer {}."); - continue; - } +// if (System.currentTimeMillis() - event.getTime() > TIME_OUT) { +// logger.warn("Drop smart contract {} from peer {}."); +// continue; +// } trxHandlePool.submit(() -> handleTransaction(event.getPeer(), event.getMsg())); } } catch (Exception e) { @@ -119,22 +123,22 @@ private void handleSmartContract() { }, 1000, 20, TimeUnit.MILLISECONDS); } - private boolean handleTransaction (PeerConnection peer, TransactionMessage trx) { + private void handleTransaction (PeerConnection peer, TransactionMessage trx) { if (peer.isDisconnect()) { logger.warn("Peer {} is disconnect, drop trx {}", peer.getInetAddress(), trx.getMessageId()); - return false; + return; } try { tronProxy.pushTransaction(trx.getTransactionCapsule()); - return true; + peerAdv.broadcast(trx); }catch (P2pException e) { - logger.warn("Trx {} from peer {} process failed. type: {}", trx.getMessageId(), peer.getInetAddress(), e.getType(), e); + logger.warn("Trx {} from peer {} process failed. type: {}, reason: {}", + trx.getMessageId(), peer.getInetAddress(), e.getType(), e.getMessage()); if (e.getType().equals(TypeEnum.BAD_TRX)) { peer.disconnect(ReasonCode.BAD_TX); } }catch (Exception e) { logger.warn("Trx {} from peer {} process failed.", trx.getMessageId(), peer.getInetAddress(), e); } - return false; } } \ No newline at end of file diff --git a/src/main/java/org/tron/core/net/peer/PeerAdv.java b/src/main/java/org/tron/core/net/peer/PeerAdv.java index aade680b874..b5cb7ce42cf 100644 --- a/src/main/java/org/tron/core/net/peer/PeerAdv.java +++ b/src/main/java/org/tron/core/net/peer/PeerAdv.java @@ -39,9 +39,12 @@ public class PeerAdv { @Autowired private TronProxy tronProxy; - private ConcurrentHashMap advObjToFetch = new ConcurrentHashMap<>(); + private ConcurrentHashMap invToFetch = new ConcurrentHashMap<>(); - private ConcurrentHashMap advObjToSpread = new ConcurrentHashMap<>(); + private ConcurrentHashMap invToSpread = new ConcurrentHashMap<>(); + + private Cache invToFetchCache = CacheBuilder.newBuilder() + .maximumSize(500_000).expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); private Cache messageCache = CacheBuilder.newBuilder() .maximumSize(100_000).expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); @@ -86,31 +89,18 @@ public void close () { } synchronized public boolean addInv (Item item) { - InventoryType type = item.getType(); - Sha256Hash hash = item.getHash(); - if (messageCache.getIfPresent(item) != null) { + if (invToFetchCache.getIfPresent(item) != null) { return false; } -// if (type.equals(InventoryType.TRX) && trxCache.getIfPresent(hash) != null) { -// return false; -// } -// if (type.equals(InventoryType.BLOCK) && blockCache.getIfPresent(hash) != null) { -// return false; -// } - if (advObjToFetch.get(item) != null) { + if (messageCache.getIfPresent(item) != null) { return false; } - advObjToFetch.put(item, System.currentTimeMillis()); + invToFetchCache.put(item, System.currentTimeMillis()); + invToFetch.put(item, System.currentTimeMillis()); return true; } public Message getMessage (Item item) { -// if (item.getType().equals(InventoryType.TRX)) { -// return trxCache.getIfPresent(item.getHash()); -// } -// if (item.getType().equals(InventoryType.BLOCK)) { -// return blockCache.getIfPresent(item.getHash()); -// } return messageCache.getIfPresent(item); } @@ -122,7 +112,7 @@ public void broadcast(Message msg) { messageCache.put(new Item(blockMsg.getMessageId(), InventoryType.BLOCK), blockMsg); type = InventoryType.BLOCK; blockMsg.getBlockCapsule().getTransactions().forEach(transactionCapsule -> { - advObjToSpread.remove(transactionCapsule.getTransactionId()); + invToSpread.remove(transactionCapsule.getTransactionId()); }); } else if (msg instanceof TransactionMessage) { TransactionMessage trxMsg = (TransactionMessage) msg; @@ -133,8 +123,8 @@ public void broadcast(Message msg) { logger.error("Adv item is neither block nor trx."); return; } - synchronized (advObjToSpread) { - advObjToSpread.put(new Item(msg.getMessageId(), type), System.currentTimeMillis()); + synchronized (invToSpread) { + invToSpread.put(new Item(msg.getMessageId(), type), System.currentTimeMillis()); } } @@ -146,7 +136,7 @@ public void onDisconnect (PeerConnection peer) { .filter(peerConnection -> peerConnection.getAdvInvReceive().containsKey(item)) .findFirst() .isPresent()) { - advObjToFetch.put(item, System.currentTimeMillis()); + invToFetch.put(item, System.currentTimeMillis()); } }); } @@ -157,17 +147,17 @@ private void consumerAdvObjToFetch() { .filter(peer -> peer.isIdle()) .collect(Collectors.toList()); - if (advObjToFetch.isEmpty() || peers.isEmpty()) { + if (invToFetch.isEmpty() || peers.isEmpty()) { return; } InvSender invSender = new InvSender(); long now = Time.getCurrentMillis(); - advObjToFetch.forEach((item, time) -> { + invToFetch.forEach((item, time) -> { Sha256Hash hash = item.getHash(); if (time < now - MSG_CACHE_DURATION_IN_BLOCKS * BLOCK_PRODUCED_INTERVAL) { logger.info("This obj is too late to fetch, type: {} hash: {}.", item.getType(), item.getHash()); - advObjToFetch.remove(item); + invToFetch.remove(item); return; } peers.stream() @@ -176,7 +166,7 @@ private void consumerAdvObjToFetch() { .findFirst().ifPresent(peer -> { invSender.add(item, peer); peer.getAdvInvRequest().put(item, now); - advObjToFetch.remove(item); + invToFetch.remove(item); }); }); @@ -184,15 +174,15 @@ private void consumerAdvObjToFetch() { } private void consumerAdvObjToSpread() { - if (advObjToSpread.isEmpty()) { + if (invToSpread.isEmpty()) { return; } InvSender invSender = new InvSender(); HashMap spread = new HashMap<>(); - synchronized (advObjToSpread) { - spread.putAll(advObjToSpread); - advObjToSpread.clear(); + synchronized (invToSpread) { + spread.putAll(invToSpread); + invToSpread.clear(); } tronProxy.getActivePeer().stream() From 77bb646fe6ce735e92ac6faee6080674331a91f0 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Wed, 21 Nov 2018 14:21:00 +0800 Subject: [PATCH 13/41] modify sync bolock handle --- .../net/messagehandler/BlockMsgHandler.java | 19 ++++++++++++------- .../java/org/tron/core/net/peer/PeerSync.java | 3 --- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 5fe7774ef55..6177f176fe1 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -49,20 +49,25 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti BlockId blockId = blockMessage.getBlockId(); Item item = new Item(blockId, InventoryType.BLOCK); - boolean syncFlag = false; +// boolean syncFlag = false; if (peer.getSyncBlockRequested().containsKey(blockId)) { + peer.getSyncBlockRequested().remove(blockId); peerSync.processBlock(peer, blockMessage); - syncFlag = true; - } - if (peer.getAdvInvRequest().containsKey(item)) { +// syncFlag = true; + } else { peer.getAdvInvRequest().remove(item); - if (!syncFlag) { - processBlock(peer, blockMessage.getBlockCapsule()); - } + processBlock(peer, blockMessage.getBlockCapsule()); +// if (!syncFlag) { +// processBlock(peer, blockMessage.getBlockCapsule()); +// } } } private void check (PeerConnection peer, BlockMessage msg) throws Exception { + Item item = new Item(msg.getBlockId(), InventoryType.BLOCK); + if (!peer.getSyncBlockRequested().containsKey(item) && !peer.getAdvInvRequest().containsKey(item)) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "no request"); + } BlockCapsule blockCapsule = msg.getBlockCapsule(); if (blockCapsule.getInstance().getSerializedSize() > BLOCK_SIZE + 100) { throw new P2pException(TypeEnum.BAD_MESSAGE, "block size over limit"); diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java index 19094e78540..3ca78657c75 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -117,9 +117,6 @@ public void syncNext(PeerConnection peer) { } public void processBlock(PeerConnection peer, BlockMessage blockMessage) { - BlockCapsule block = blockMessage.getBlockCapsule(); - BlockId blockId = block.getBlockId(); - peer.getSyncBlockRequested().remove(blockId); synchronized (blockJustReceived) { blockJustReceived.put(blockMessage, peer); } From 310b4cb327e48d544ca409ad59659448b20fd78e Mon Sep 17 00:00:00 2001 From: wubin01 Date: Wed, 21 Nov 2018 16:48:14 +0800 Subject: [PATCH 14/41] modify peer sync --- .../common/application/ApplicationImpl.java | 6 ++++ .../common/overlay/server/ChannelManager.java | 7 ++-- .../java/org/tron/core/net/TronHandler.java | 1 + .../org/tron/core/net/TronNetService.java | 34 ++++++++++--------- .../java/org/tron/core/net/TronProxy.java | 4 +-- .../net/messagehandler/BlockMsgHandler.java | 2 +- .../tron/core/net/peer/PeerConnection.java | 7 +++- .../java/org/tron/core/net/peer/PeerSync.java | 5 ++- 8 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/tron/common/application/ApplicationImpl.java b/src/main/java/org/tron/common/application/ApplicationImpl.java index eff5a4d9584..d9b6fbd748b 100644 --- a/src/main/java/org/tron/common/application/ApplicationImpl.java +++ b/src/main/java/org/tron/common/application/ApplicationImpl.java @@ -6,6 +6,7 @@ import org.tron.core.config.args.Args; import org.tron.core.db.BlockStore; import org.tron.core.db.Manager; +import org.tron.core.net.TronNetService; @Slf4j @Component @@ -14,6 +15,9 @@ public class ApplicationImpl implements Application { private BlockStore blockStoreDb; private ServiceContainer services; + @Autowired + private TronNetService tronNetService; + @Autowired private Manager dbManager; @@ -45,11 +49,13 @@ public void initServices(Args args) { * start up the app. */ public void startup() { + tronNetService.start(); } @Override public void shutdown() { logger.info("******** begin to shutdown ********"); + tronNetService.close(); synchronized (dbManager.getRevokingStore()) { closeRevokingStore(); closeAllStore(); diff --git a/src/main/java/org/tron/common/overlay/server/ChannelManager.java b/src/main/java/org/tron/common/overlay/server/ChannelManager.java index 70a9011f16b..6eec712ba0e 100644 --- a/src/main/java/org/tron/common/overlay/server/ChannelManager.java +++ b/src/main/java/org/tron/common/overlay/server/ChannelManager.java @@ -47,17 +47,16 @@ public class ChannelManager { private int getMaxActivePeersWithSameIp = args.getNodeMaxActiveNodesWithSameIp(); + @Autowired private PeerServer peerServer; + @Autowired private PeerClient peerClient; @Autowired private SyncPool syncPool; - @Autowired - private ChannelManager(final PeerServer peerServer, final PeerClient peerClient) { - this.peerServer = peerServer; - this.peerClient = peerClient; + public void init () { if (this.args.getNodeListenPort() > 0) { new Thread(() -> peerServer.start(Args.getInstance().getNodeListenPort()), diff --git a/src/main/java/org/tron/core/net/TronHandler.java b/src/main/java/org/tron/core/net/TronHandler.java index 2a7b3f75a0c..8e3f65e0b8f 100644 --- a/src/main/java/org/tron/core/net/TronHandler.java +++ b/src/main/java/org/tron/core/net/TronHandler.java @@ -19,6 +19,7 @@ public class TronHandler extends SimpleChannelInboundHandler { private MessageQueue msgQueue; + @Autowired private TronNetService tronNetService; // @Autowired diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index 8368d13f5df..0ad35deca05 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -1,6 +1,5 @@ package org.tron.core.net; -import io.netty.channel.ChannelInboundHandler; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -9,6 +8,7 @@ import org.tron.core.exception.P2pException.TypeEnum; import org.tron.core.net.message.TronMessage; import org.tron.core.net.messagehandler.BlockMsgHandler; +import org.tron.core.net.messagehandler.ChainInventoryMsgHandler; import org.tron.core.net.messagehandler.FetchInvDataMsgHandler; import org.tron.core.net.messagehandler.InventoryMsgHandler; import org.tron.core.net.messagehandler.SyncBlockChainMsgHadler; @@ -32,24 +32,26 @@ public class TronNetService { private PeerSync peerSync; @Autowired - private BlockMsgHandler blockMsgHandler; + private SyncBlockChainMsgHadler syncBlockChainMsgHadler; @Autowired - private ChannelInboundHandler channelInboundHandler; + private ChainInventoryMsgHandler chainInventoryMsgHandler; @Autowired - private FetchInvDataMsgHandler fetchInvDataMsgHandler; + private InventoryMsgHandler inventoryMsgHandler; + @Autowired - private InventoryMsgHandler inventoryMsgHandler; + private FetchInvDataMsgHandler fetchInvDataMsgHandler; @Autowired - private SyncBlockChainMsgHadler syncBlockChainMsgHadler; + private BlockMsgHandler blockMsgHandler; @Autowired private TransactionsMsgHandler transactionsMsgHandler; public void start () { + channelManager.init(); peerAdv.init(); peerSync.init(); transactionsMsgHandler.init(); @@ -68,24 +70,24 @@ public void close () { public void onMessage(PeerConnection peer, TronMessage msg) { try { switch (msg.getType()) { - case BLOCK: - blockMsgHandler.processMessage(peer, msg); - break; - case TRXS: - transactionsMsgHandler.processMessage(peer, msg); - break; case SYNC_BLOCK_CHAIN: syncBlockChainMsgHadler.processMessage(peer, msg); break; - case FETCH_INV_DATA: - fetchInvDataMsgHandler.processMessage(peer, msg); - break; case BLOCK_CHAIN_INVENTORY: - syncBlockChainMsgHadler.processMessage(peer, msg); + chainInventoryMsgHandler.processMessage(peer, msg); break; case INVENTORY: inventoryMsgHandler.processMessage(peer, msg); break; + case FETCH_INV_DATA: + fetchInvDataMsgHandler.processMessage(peer, msg); + break; + case BLOCK: + blockMsgHandler.processMessage(peer, msg); + break; + case TRXS: + transactionsMsgHandler.processMessage(peer, msg); + break; default: throw new P2pException(TypeEnum.NO_SUCH_MESSAGE, "No such message"); } diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronProxy.java index 7aa6f39c0fa..d6d1b4b6bb3 100644 --- a/src/main/java/org/tron/core/net/TronProxy.java +++ b/src/main/java/org/tron/core/net/TronProxy.java @@ -54,7 +54,7 @@ public class TronProxy { private Manager dbManager; @Getter - private Object blockLock; + private Object blockLock = new Object(); private Queue freshBlockId = new ConcurrentLinkedQueue() { @Override @@ -149,7 +149,7 @@ public Message getData(Sha256Hash hash, InventoryType type) throws StoreExceptio public void processBlock(BlockCapsule block) throws Exception { synchronized (blockLock) { try { - if (freshBlockId.contains(block.getBlockId())) { + if (!freshBlockId.contains(block.getBlockId())) { dbManager.preValidateTransactionSign(block); dbManager.pushBlock(block); freshBlockId.add(block.getBlockId()); diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 6177f176fe1..508fbfc871a 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -65,7 +65,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti private void check (PeerConnection peer, BlockMessage msg) throws Exception { Item item = new Item(msg.getBlockId(), InventoryType.BLOCK); - if (!peer.getSyncBlockRequested().containsKey(item) && !peer.getAdvInvRequest().containsKey(item)) { + if (!peer.getSyncBlockRequested().containsKey(msg.getBlockId()) && !peer.getAdvInvRequest().containsKey(item)) { throw new P2pException(TypeEnum.BAD_MESSAGE, "no request"); } BlockCapsule blockCapsule = msg.getBlockCapsule(); diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index 1f83a280ce7..2ff250d5a1e 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -59,7 +59,7 @@ public class PeerConnection extends Channel { private Map advInvRequest = new ConcurrentHashMap<>(); @Getter - private BlockId blockBothHave = tronProxy.getGenesisBlockId(); + private BlockId blockBothHave = new BlockId(); public void setBlockBothHave (BlockId blockId) { this.blockBothHave = blockId; this.blockBothHaveUpdateTime = System.currentTimeMillis(); @@ -150,6 +150,11 @@ public void onDisconnectPeer() { } public String logSyncStats() { + + } + + @Override + public String toString () { return String.format( "Peer %s: [ %18s, ping %6s ms]-----------\n" + "connect time: %s\n" diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java index 3ca78657c75..3e518eba037 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -229,6 +229,7 @@ private synchronized void startFetchSyncBlock() { } private void processSyncBlock (BlockCapsule block) { + logger.info("Start process sync block: {}.", block.getBlockId().getNum()); boolean flag = true; BlockId blockId = block.getBlockId(); try { @@ -253,6 +254,8 @@ private void processSyncBlock (BlockCapsule block) { private synchronized void handleSyncBlock() { + logger.info("HHHHHHHHHHHHHH");logger.info("HHHHHHHHHHHHHH");logger.info("HHHHHHHHHHHHHH"); + synchronized (blockJustReceived) { blockWaitToProc.putAll(blockJustReceived); blockJustReceived.clear(); @@ -266,7 +269,7 @@ private synchronized void handleSyncBlock() { blockWaitToProc.forEach((msg, peerConnection) -> { if (peerConnection.isDisconnect()) { - logger.error("Peer {} is disconnect, drop block {}", peerConnection.getInetAddress(), msg.getBlockId().getString()); + logger.warn("Peer {} is disconnect, drop block {}", peerConnection.getInetAddress(), msg.getBlockId().getString()); blockWaitToProc.remove(msg); invalid(msg.getBlockId()); return; From 95c0bca699899a9e6318f75d1bd7964a5d471769 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Thu, 22 Nov 2018 14:52:47 +0800 Subject: [PATCH 15/41] modify peer sync and adv --- .../common/overlay/server/ChannelManager.java | 22 +++++++++---------- .../tron/common/overlay/server/SyncPool.java | 2 +- .../org/tron/core/net/TronNetService.java | 15 ++++++------- .../java/org/tron/core/net/peer/PeerAdv.java | 4 ++-- .../tron/core/net/peer/PeerConnection.java | 17 +++++++------- .../java/org/tron/core/net/peer/PeerSync.java | 4 +--- 6 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/tron/common/overlay/server/ChannelManager.java b/src/main/java/org/tron/common/overlay/server/ChannelManager.java index 6eec712ba0e..0978cb9ee95 100644 --- a/src/main/java/org/tron/common/overlay/server/ChannelManager.java +++ b/src/main/java/org/tron/common/overlay/server/ChannelManager.java @@ -28,6 +28,17 @@ @Component public class ChannelManager { + @Autowired + private PeerServer peerServer; + + @Autowired + private PeerClient peerClient; + + @Autowired + private SyncPool syncPool; + + private Args args = Args.getInstance(); + private static final Logger logger = LoggerFactory.getLogger("ChannelManager"); private final Map activePeers = new ConcurrentHashMap<>(); @@ -41,21 +52,10 @@ public class ChannelManager { @Getter private Map trustPeers = new ConcurrentHashMap(); - private Args args = Args.getInstance(); - private int maxActivePeers = args.getNodeMaxActiveNodes(); private int getMaxActivePeersWithSameIp = args.getNodeMaxActiveNodesWithSameIp(); - @Autowired - private PeerServer peerServer; - - @Autowired - private PeerClient peerClient; - - @Autowired - private SyncPool syncPool; - public void init () { if (this.args.getNodeListenPort() > 0) { diff --git a/src/main/java/org/tron/common/overlay/server/SyncPool.java b/src/main/java/org/tron/common/overlay/server/SyncPool.java index f6f4b133c4d..298743885a7 100644 --- a/src/main/java/org/tron/common/overlay/server/SyncPool.java +++ b/src/main/java/org/tron/common/overlay/server/SyncPool.java @@ -146,7 +146,7 @@ synchronized void logActivePeers() { sb.append("============\n"); Set activeSet = new HashSet<>(); for (PeerConnection peer : new ArrayList<>(activePeers)) { - sb.append(peer.logSyncStats()).append('\n'); + sb.append(peer).append('\n'); activeSet.add(peer.getNode()); } sb.append("Other connected peers\n"); diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index 0ad35deca05..0cde1739ab7 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -55,16 +55,15 @@ public void start () { peerAdv.init(); peerSync.init(); transactionsMsgHandler.init(); + logger.info("TronNetService start."); } public void close () { - try { - peerAdv.close(); - peerSync.close(); - transactionsMsgHandler.close(); - }catch (Exception e) { - logger.error("TronNetService closed failed.",e ); - } + channelManager.close(); + peerAdv.close(); + peerSync.close(); + transactionsMsgHandler.close(); + logger.info("TronNetService closed."); } public void onMessage(PeerConnection peer, TronMessage msg) { @@ -120,7 +119,7 @@ private void processException (PeerConnection peer, TronMessage msg, Exception e code = ReasonCode.UNLINKABLE; break; case DEFAULT: - code = ReasonCode.UNLINKABLE; + code = ReasonCode.UNKNOWN; break; } logger.error("Process {} from peer {} failed, reason: ", peer.getInetAddress(), msg.getType(), type.getDesc(), ex); diff --git a/src/main/java/org/tron/core/net/peer/PeerAdv.java b/src/main/java/org/tron/core/net/peer/PeerAdv.java index b5cb7ce42cf..a6a90270517 100644 --- a/src/main/java/org/tron/core/net/peer/PeerAdv.java +++ b/src/main/java/org/tron/core/net/peer/PeerAdv.java @@ -144,7 +144,7 @@ public void onDisconnect (PeerConnection peer) { private void consumerAdvObjToFetch() { Collection peers = tronProxy.getActivePeer().stream() - .filter(peer -> peer.isIdle()) + .filter(peer -> peer.isIdle() && !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) .collect(Collectors.toList()); if (invToFetch.isEmpty() || peers.isEmpty()) { @@ -186,7 +186,7 @@ private void consumerAdvObjToSpread() { } tronProxy.getActivePeer().stream() - .filter(peer -> !peer.isNeedSyncFromUs()) + .filter(peer -> !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) .forEach(peer -> spread.entrySet().stream() .filter(entry -> !peer.getAdvInvReceive().containsKey(entry.getKey()) && !peer.getAdvInvSpread().containsKey(entry.getKey())) .forEach(entry -> { diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index 2ff250d5a1e..c4df681bde1 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -42,6 +42,10 @@ public class PeerConnection extends Channel { @Autowired private PeerAdv peerAdv; + @Setter + @Getter + private BlockId signUpErrorBlockId; + @Setter @Getter private HelloMessage helloMessage; @@ -149,15 +153,12 @@ public void onDisconnectPeer() { peerAdv.onDisconnect(this); } - public String logSyncStats() { - - } - @Override public String toString () { + long now = System.currentTimeMillis(); return String.format( "Peer %s: [ %18s, ping %6s ms]-----------\n" - + "connect time: %s\n" + + "connect time: %d\n" + "last know block num: %s\n" + "needSyncFromPeer:%b\n" + "needSyncFromUs:%b\n" @@ -165,12 +166,12 @@ public String toString () { + "syncToFetchSizePeekNum:%d\n" + "syncBlockRequestedSize:%d\n" + "remainNum:%d\n" - + "syncChainRequested:%s\n" + + "syncChainRequested:%d\n" + "blockInProcess:%d\n", this.getNode().getHost() + ":" + this.getNode().getPort(), this.getNode().getHexIdShort(), (int) this.getPeerStats().getAvgLatency(), - Time.getTimeString(super.getStartTime()), + (now - super.getStartTime()) / 1000, blockBothHave.getNum(), isNeedSyncFromPeer(), isNeedSyncFromUs(), @@ -178,7 +179,7 @@ public String toString () { syncBlockToFetch.size() > 0 ? syncBlockToFetch.peek().getNum() : -1, syncBlockRequested.size(), remainNum, - syncChainRequested == null ? "NULL" : Time.getTimeString(syncChainRequested.getValue()), + syncChainRequested == null ? 0 : (now - syncChainRequested.getValue()) / 1000, syncBlockInProcess.size()) + nodeStatistics.toString() + "\n"; } diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java index 3e518eba037..423b24db785 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -133,6 +133,7 @@ public void processBlock(PeerConnection peer, BlockMessage blockMessage) { public void onDisconnect (PeerConnection peer) { if (!peer.getSyncBlockRequested().isEmpty()) { peer.getSyncBlockRequested().keySet().forEach(blockId -> invalid(blockId)); + fetchFlag = true; } } @@ -229,7 +230,6 @@ private synchronized void startFetchSyncBlock() { } private void processSyncBlock (BlockCapsule block) { - logger.info("Start process sync block: {}.", block.getBlockId().getNum()); boolean flag = true; BlockId blockId = block.getBlockId(); try { @@ -254,8 +254,6 @@ private void processSyncBlock (BlockCapsule block) { private synchronized void handleSyncBlock() { - logger.info("HHHHHHHHHHHHHH");logger.info("HHHHHHHHHHHHHH");logger.info("HHHHHHHHHHHHHH"); - synchronized (blockJustReceived) { blockWaitToProc.putAll(blockJustReceived); blockJustReceived.clear(); From 14a76bc2abf1a9dd4708ae85dd765a753e36023f Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 26 Nov 2018 11:35:04 +0800 Subject: [PATCH 16/41] perfect message processing code --- .../tron/common/overlay/server/SyncPool.java | 2 +- .../java/org/tron/core/config/Parameter.java | 3 +- .../org/tron/core/net/TronNetService.java | 2 +- .../FetchInvDataMsgHandler.java | 2 -- .../messagehandler/InventoryMsgHandler.java | 6 ++-- .../java/org/tron/core/net/peer/PeerAdv.java | 33 +++++++++---------- .../tron/core/net/peer/PeerConnection.java | 29 ++++++++++++++-- .../java/org/tron/core/net/peer/PeerSync.java | 14 ++++---- 8 files changed, 57 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/tron/common/overlay/server/SyncPool.java b/src/main/java/org/tron/common/overlay/server/SyncPool.java index 298743885a7..b855b6ca02b 100644 --- a/src/main/java/org/tron/common/overlay/server/SyncPool.java +++ b/src/main/java/org/tron/common/overlay/server/SyncPool.java @@ -146,7 +146,7 @@ synchronized void logActivePeers() { sb.append("============\n"); Set activeSet = new HashSet<>(); for (PeerConnection peer : new ArrayList<>(activePeers)) { - sb.append(peer).append('\n'); + sb.append(peer.log()).append('\n'); activeSet.add(peer.getNode()); } sb.append("Other connected peers\n"); diff --git a/src/main/java/org/tron/core/config/Parameter.java b/src/main/java/org/tron/core/config/Parameter.java index 3c3cc2dca87..099cc6b71f5 100644 --- a/src/main/java/org/tron/core/config/Parameter.java +++ b/src/main/java/org/tron/core/config/Parameter.java @@ -46,7 +46,8 @@ interface NetConstants { long HEAD_NUM_CHECK_TIME = 60000L; int MAX_INVENTORY_SIZE_IN_MINUTES = 2; long NET_MAX_TRX_PER_SECOND = 700L; - int MAX_INV_FETCH_PER_PEER = 1000; + int MAX_BLOCK_FETCH_PER_PEER = 100; + int MAX_TRX_FETCH_PER_PEER = 1000; int NET_MAX_INV_SIZE_IN_MINUTES = 2; int MSG_CACHE_DURATION_IN_BLOCKS = 5; } diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index 0cde1739ab7..be4ac634c4a 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -88,7 +88,7 @@ public void onMessage(PeerConnection peer, TronMessage msg) { transactionsMsgHandler.processMessage(peer, msg); break; default: - throw new P2pException(TypeEnum.NO_SUCH_MESSAGE, "No such message"); + throw new P2pException(TypeEnum.NO_SUCH_MESSAGE, "No such message: " + msg.getType()); } }catch (Exception e) { processException(peer, msg, e); diff --git a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index 9da4039d069..9f810fddb94 100644 --- a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -44,8 +44,6 @@ public class FetchInvDataMsgHandler implements TronMsgHandler { private int MAX_SIZE = 1_000_000; - private int MAX_COUNT = 200; - @Override public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { diff --git a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index 0939470e469..094aef44bdf 100644 --- a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -52,9 +52,9 @@ private boolean check (PeerConnection peer, InventoryMessage inventoryMessage) t InventoryType type = inventoryMessage.getInventoryType(); int size = inventoryMessage.getHashList().size(); - if (size > NetConstants.MAX_INV_FETCH_PER_PEER) { - throw new P2pException(TypeEnum.BAD_MESSAGE, "size: " + size); - } +// if (size > NetConstants.MAX_INV_FETCH_PER_PEER) { +// throw new P2pException(TypeEnum.BAD_MESSAGE, "size: " + size); +// } if (peer.isNeedSyncFromPeer() || peer.isNeedSyncFromUs()) { logger.warn("Drop inv: {} size: {} from Peer {}, syncFromUs: {}, syncFromPeer: {}.", diff --git a/src/main/java/org/tron/core/net/peer/PeerAdv.java b/src/main/java/org/tron/core/net/peer/PeerAdv.java index a6a90270517..b5a45398c2d 100644 --- a/src/main/java/org/tron/core/net/peer/PeerAdv.java +++ b/src/main/java/org/tron/core/net/peer/PeerAdv.java @@ -1,7 +1,7 @@ package org.tron.core.net.peer; import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; -import static org.tron.core.config.Parameter.NetConstants.MAX_INV_FETCH_PER_PEER; +import static org.tron.core.config.Parameter.NetConstants.MAX_TRX_FETCH_PER_PEER; import static org.tron.core.config.Parameter.NetConstants.MSG_CACHE_DURATION_IN_BLOCKS; import com.google.common.cache.Cache; @@ -67,7 +67,7 @@ public class PeerAdv { public void init () { spreadExecutor.scheduleWithFixedDelay(() -> { try { - consumerAdvObjToSpread(); + consumerInvToSpread(); } catch (Throwable t) { logger.error("Spread thread error.", t); } @@ -75,9 +75,9 @@ public void init () { fetchExecutor.scheduleWithFixedDelay(() -> { try { - consumerAdvObjToFetch(); + consumerInvToFetch(); } catch (Throwable t) { - logger.error("fetch thread error.", t); + logger.error("Fetch thread error.", t); } }, 100, 30, TimeUnit.MILLISECONDS); } @@ -105,26 +105,25 @@ public Message getMessage (Item item) { } public void broadcast(Message msg) { - InventoryType type; + Item item; if (msg instanceof BlockMessage) { BlockMessage blockMsg = (BlockMessage) msg; + item = new Item(blockMsg.getMessageId(), InventoryType.BLOCK); logger.info("Ready to broadcast block {}", blockMsg.getBlockId().getString()); - messageCache.put(new Item(blockMsg.getMessageId(), InventoryType.BLOCK), blockMsg); - type = InventoryType.BLOCK; - blockMsg.getBlockCapsule().getTransactions().forEach(transactionCapsule -> { - invToSpread.remove(transactionCapsule.getTransactionId()); - }); + blockMsg.getBlockCapsule().getTransactions().forEach(transactionCapsule -> + invToSpread.remove(transactionCapsule.getTransactionId()) + ); } else if (msg instanceof TransactionMessage) { TransactionMessage trxMsg = (TransactionMessage) msg; - messageCache.put(new Item(trxMsg.getMessageId(), InventoryType.BLOCK), trxMsg); - type = InventoryType.TRX; + item = new Item(trxMsg.getMessageId(), InventoryType.TRX); trxCount.add(); } else { - logger.error("Adv item is neither block nor trx."); + logger.error("Adv item is neither block nor trx, type: {}", msg.getType()); return; } + messageCache.put(item, msg); synchronized (invToSpread) { - invToSpread.put(new Item(msg.getMessageId(), type), System.currentTimeMillis()); + invToSpread.put(item, System.currentTimeMillis()); } } @@ -142,7 +141,7 @@ public void onDisconnect (PeerConnection peer) { } } - private void consumerAdvObjToFetch() { + private void consumerInvToFetch() { Collection peers = tronProxy.getActivePeer().stream() .filter(peer -> peer.isIdle() && !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) .collect(Collectors.toList()); @@ -161,7 +160,7 @@ private void consumerAdvObjToFetch() { return; } peers.stream() - .filter(peer -> peer.getAdvInvReceive().containsKey(hash) && invSender.getSize(peer) < MAX_INV_FETCH_PER_PEER) + .filter(peer -> peer.getAdvInvReceive().containsKey(hash) && invSender.getSize(peer) < MAX_TRX_FETCH_PER_PEER) .sorted(Comparator.comparingInt(peer -> invSender.getSize(peer))) .findFirst().ifPresent(peer -> { invSender.add(item, peer); @@ -173,7 +172,7 @@ private void consumerAdvObjToFetch() { invSender.sendFetch(); } - private void consumerAdvObjToSpread() { + private void consumerInvToSpread() { if (invToSpread.isEmpty()) { return; } diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index c4df681bde1..be06a949bcc 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -153,9 +153,34 @@ public void onDisconnectPeer() { peerAdv.onDisconnect(this); } - @Override - public String toString () { + public String log () { long now = System.currentTimeMillis(); +// logger.info("Peer {}:{} [ {}, ping {} ms]-----------\n" +// + "connect time: {}\n" +// + "last know block num: {}\n" +// + "needSyncFromPeer:{}\n" +// + "needSyncFromUs:{}\n" +// + "syncToFetchSize:{}\n" +// + "syncToFetchSizePeekNum:{}\n" +// + "syncBlockRequestedSize:{}\n" +// + "remainNum:{}\n" +// + "syncChainRequested:{}\n" +// + "blockInProcess:{}\n" +// + "{}", +// this.getNode().getHost(), this.getNode().getPort(), this.getNode().getHexIdShort(), +// (int) this.getPeerStats().getAvgLatency(), +// (now - super.getStartTime()) / 1000, +// blockBothHave.getNum(), +// isNeedSyncFromPeer(), +// isNeedSyncFromUs(), +// syncBlockToFetch.size(), +// syncBlockToFetch.size() > 0 ? syncBlockToFetch.peek().getNum() : -1, +// syncBlockRequested.size(), +// remainNum, +// syncChainRequested == null ? 0 : (now - syncChainRequested.getValue()) / 1000, +// syncBlockInProcess.size(), +// nodeStatistics.toString()); +//// return String.format( "Peer %s: [ %18s, ping %6s ms]-----------\n" + "connect time: %d\n" diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java index 423b24db785..7f7bf268cd8 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -1,6 +1,6 @@ package org.tron.core.net.peer; -import static org.tron.core.config.Parameter.NetConstants.MAX_INV_FETCH_PER_PEER; +import static org.tron.core.config.Parameter.NetConstants.MAX_BLOCK_FETCH_PER_PEER; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; @@ -45,7 +45,7 @@ public class PeerSync { @Autowired private TronNetClient tronManager; - private Map blockWaitToProc = new ConcurrentHashMap<>(); + private Map blockWaitToProcess = new ConcurrentHashMap<>(); private Map blockJustReceived = new ConcurrentHashMap<>(); @@ -207,7 +207,7 @@ private synchronized void startFetchSyncBlock() { if (!request.contains(blockId) && (requestBlockIds.getIfPresent(blockId) == null)) { send.get(peer).add(blockId); request.add(blockId); - if (send.get(peer).size() >= MAX_INV_FETCH_PER_PEER) { + if (send.get(peer).size() >= MAX_BLOCK_FETCH_PER_PEER) { break; } } @@ -255,7 +255,7 @@ private void processSyncBlock (BlockCapsule block) { private synchronized void handleSyncBlock() { synchronized (blockJustReceived) { - blockWaitToProc.putAll(blockJustReceived); + blockWaitToProcess.putAll(blockJustReceived); blockJustReceived.clear(); } @@ -265,10 +265,10 @@ private synchronized void handleSyncBlock() { isProcessed[0] = false; - blockWaitToProc.forEach((msg, peerConnection) -> { + blockWaitToProcess.forEach((msg, peerConnection) -> { if (peerConnection.isDisconnect()) { logger.warn("Peer {} is disconnect, drop block {}", peerConnection.getInetAddress(), msg.getBlockId().getString()); - blockWaitToProc.remove(msg); + blockWaitToProcess.remove(msg); invalid(msg.getBlockId()); return; } @@ -281,7 +281,7 @@ private synchronized void handleSyncBlock() { isFound[0] = true; }); if (isFound[0]) { - blockWaitToProc.remove(msg); + blockWaitToProcess.remove(msg); isProcessed[0] = true; processSyncBlock(msg.getBlockCapsule()); } From 91ae1989d77314d83d87f4f6c90f54587db56899 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 26 Nov 2018 15:43:10 +0800 Subject: [PATCH 17/41] modify FetchInvData msg handler --- src/main/java/org/tron/core/net/TronNetClient.java | 4 ++-- .../core/net/messagehandler/ChainInventoryMsgHandler.java | 5 +++-- .../core/net/messagehandler/FetchInvDataMsgHandler.java | 6 +++--- src/main/java/org/tron/core/net/peer/PeerAdv.java | 5 ++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/tron/core/net/TronNetClient.java b/src/main/java/org/tron/core/net/TronNetClient.java index 14b383ddd2a..823938d877d 100644 --- a/src/main/java/org/tron/core/net/TronNetClient.java +++ b/src/main/java/org/tron/core/net/TronNetClient.java @@ -1,6 +1,6 @@ package org.tron.core.net; -import lombok.Getter; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.overlay.message.Message; import org.tron.core.net.peer.PeerAdv; @@ -8,7 +8,7 @@ @Component public class TronNetClient { - @Getter + @Autowired private PeerAdv peerAdv; public void broadcast(Message msg) { diff --git a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java index 8bd8752d7c2..3b1e0049bed 100644 --- a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -98,8 +98,9 @@ private void check(PeerConnection peer, ChainInventoryMessage msg) throws Except throw new P2pException(TypeEnum.BAD_MESSAGE, "big blockIds size: " + blockIds.size()); } - if (msg.getRemainNum() == 0 && blockIds.size() < NodeConstant.SYNC_FETCH_BATCH_NUM) { - throw new P2pException(TypeEnum.BAD_MESSAGE, "remain blockNum: 0, blockIds size: " + blockIds.size()); + if (msg.getRemainNum() != 0 && blockIds.size() < NodeConstant.SYNC_FETCH_BATCH_NUM) { + throw new P2pException(TypeEnum.BAD_MESSAGE, + "remain: " + msg.getRemainNum() +", blockIds size: " + blockIds.size()); } long num = blockIds.get(0).getNum(); diff --git a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index 9f810fddb94..ded8d18e5a2 100644 --- a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -39,7 +39,7 @@ public class FetchInvDataMsgHandler implements TronMsgHandler { @Autowired private PeerSync peerSync; - @Setter + @Autowired private PeerAdv peerAdv; private int MAX_SIZE = 1_000_000; @@ -103,14 +103,14 @@ private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) thr throw new P2pException(TypeEnum.BAD_MESSAGE, "maxCount: " + maxCount + ", fetchCount: " + fetchCount); } for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - if (!peer.getAdvInvSpread().containsKey(hash)) { + if (!peer.getAdvInvSpread().containsKey(new Item(hash, InventoryType.TRX))) { throw new P2pException(TypeEnum.BAD_MESSAGE, "not spread inv: {}" + hash); } } } else { boolean isAdv = true; for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - if (!peer.getAdvInvSpread().containsKey(hash)) { + if (!peer.getAdvInvSpread().containsKey(new Item(hash, InventoryType.BLOCK))) { isAdv = false; break; } diff --git a/src/main/java/org/tron/core/net/peer/PeerAdv.java b/src/main/java/org/tron/core/net/peer/PeerAdv.java index b5a45398c2d..665ff9ad5e8 100644 --- a/src/main/java/org/tron/core/net/peer/PeerAdv.java +++ b/src/main/java/org/tron/core/net/peer/PeerAdv.java @@ -151,16 +151,15 @@ private void consumerInvToFetch() { } InvSender invSender = new InvSender(); - long now = Time.getCurrentMillis(); + long now = System.currentTimeMillis(); invToFetch.forEach((item, time) -> { - Sha256Hash hash = item.getHash(); if (time < now - MSG_CACHE_DURATION_IN_BLOCKS * BLOCK_PRODUCED_INTERVAL) { logger.info("This obj is too late to fetch, type: {} hash: {}.", item.getType(), item.getHash()); invToFetch.remove(item); return; } peers.stream() - .filter(peer -> peer.getAdvInvReceive().containsKey(hash) && invSender.getSize(peer) < MAX_TRX_FETCH_PER_PEER) + .filter(peer -> peer.getAdvInvReceive().containsKey(item) && invSender.getSize(peer) < MAX_TRX_FETCH_PER_PEER) .sorted(Comparator.comparingInt(peer -> invSender.getSize(peer))) .findFirst().ifPresent(peer -> { invSender.add(item, peer); From 2b522f5e68834fd0c15ad98108720de8fae4bf9e Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 27 Nov 2018 15:45:54 +0800 Subject: [PATCH 18/41] add peer status check --- .../org/tron/core/net/TronNetService.java | 10 ++- .../net/messagehandler/BlockMsgHandler.java | 9 +-- .../TransactionsMsgHandler.java | 1 - .../java/org/tron/core/net/peer/PeerAdv.java | 4 +- .../tron/core/net/peer/PeerStatusCheck.java | 73 +++++++++++++++++++ .../java/org/tron/core/net/peer/PeerSync.java | 1 - 6 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/tron/core/net/peer/PeerStatusCheck.java diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index be4ac634c4a..848ae8c922c 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -15,6 +15,7 @@ import org.tron.core.net.messagehandler.TransactionsMsgHandler; import org.tron.core.net.peer.PeerAdv; import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerStatusCheck; import org.tron.core.net.peer.PeerSync; import org.tron.protos.Protocol.ReasonCode; @@ -31,6 +32,9 @@ public class TronNetService { @Autowired private PeerSync peerSync; + @Autowired + private PeerStatusCheck peerStatusCheck; + @Autowired private SyncBlockChainMsgHadler syncBlockChainMsgHadler; @@ -54,16 +58,18 @@ public void start () { channelManager.init(); peerAdv.init(); peerSync.init(); + peerStatusCheck.init(); transactionsMsgHandler.init(); - logger.info("TronNetService start."); + logger.info("TronNetService start successfully."); } public void close () { channelManager.close(); peerAdv.close(); peerSync.close(); + peerStatusCheck.close(); transactionsMsgHandler.close(); - logger.info("TronNetService closed."); + logger.info("TronNetService closed successfully."); } public void onMessage(PeerConnection peer, TronMessage msg) { diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 508fbfc871a..6e7a200f19c 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -40,6 +40,8 @@ public class BlockMsgHandler implements TronMsgHandler { @Autowired private WitnessProductBlockService witnessProductBlockService; + private int maxBlockSize = BLOCK_SIZE + 1000; + @Override public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { @@ -49,17 +51,12 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti BlockId blockId = blockMessage.getBlockId(); Item item = new Item(blockId, InventoryType.BLOCK); -// boolean syncFlag = false; if (peer.getSyncBlockRequested().containsKey(blockId)) { peer.getSyncBlockRequested().remove(blockId); peerSync.processBlock(peer, blockMessage); -// syncFlag = true; } else { peer.getAdvInvRequest().remove(item); processBlock(peer, blockMessage.getBlockCapsule()); -// if (!syncFlag) { -// processBlock(peer, blockMessage.getBlockCapsule()); -// } } } @@ -69,7 +66,7 @@ private void check (PeerConnection peer, BlockMessage msg) throws Exception { throw new P2pException(TypeEnum.BAD_MESSAGE, "no request"); } BlockCapsule blockCapsule = msg.getBlockCapsule(); - if (blockCapsule.getInstance().getSerializedSize() > BLOCK_SIZE + 100) { + if (blockCapsule.getInstance().getSerializedSize() > maxBlockSize) { throw new P2pException(TypeEnum.BAD_MESSAGE, "block size over limit"); } long gap = blockCapsule.getTimeStamp() - System.currentTimeMillis(); diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index 4eaf1cd729d..144c74660af 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -73,7 +73,6 @@ public void init() { public void close() { smartContractExecutor.shutdown(); - logger.info("TransactionsMsgHandler closed."); } public boolean isBusy() { diff --git a/src/main/java/org/tron/core/net/peer/PeerAdv.java b/src/main/java/org/tron/core/net/peer/PeerAdv.java index 665ff9ad5e8..31bcbd906b8 100644 --- a/src/main/java/org/tron/core/net/peer/PeerAdv.java +++ b/src/main/java/org/tron/core/net/peer/PeerAdv.java @@ -85,7 +85,6 @@ public void init () { public void close () { spreadExecutor.shutdown(); fetchExecutor.shutdown(); - logger.info("PeerAdv closed."); } synchronized public boolean addInv (Item item) { @@ -131,8 +130,7 @@ public void onDisconnect (PeerConnection peer) { if (!peer.getAdvInvRequest().isEmpty()) { peer.getAdvInvRequest().keySet().forEach(item -> { if (tronProxy.getActivePeer().stream() - .filter(peerConnection -> !peerConnection.equals(peer)) - .filter(peerConnection -> peerConnection.getAdvInvReceive().containsKey(item)) + .filter(p -> !p.equals(peer) && p.getAdvInvReceive().containsKey(item)) .findFirst() .isPresent()) { invToFetch.put(item, System.currentTimeMillis()); diff --git a/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java b/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java new file mode 100644 index 00000000000..cfd137fcaeb --- /dev/null +++ b/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java @@ -0,0 +1,73 @@ +package org.tron.core.net.peer; + +import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.core.config.Parameter.NetConstants; +import org.tron.core.net.TronProxy; +import org.tron.protos.Protocol.ReasonCode; + +@Slf4j +@Component +public class PeerStatusCheck { + + @Autowired + private TronProxy tronProxy; + + private ScheduledExecutorService peerStatusCheckExecutor = Executors.newSingleThreadScheduledExecutor(); + + private int blockUpdateTimeout = 20_000; + + public void init () { + peerStatusCheckExecutor.scheduleWithFixedDelay(() -> { + try { + statusCheck(); + } catch (Throwable t) { + logger.error("Unhandled exception", t); + } + }, 5, 2, TimeUnit.SECONDS); + } + + public void close () { + peerStatusCheckExecutor.shutdown(); + } + + public void statusCheck() { + + long now = System.currentTimeMillis(); + + tronProxy.getActivePeer().forEach(peer -> { + + final boolean[] isDisconnected = {false}; + + if (peer.isNeedSyncFromPeer() && peer.getBlockBothHaveUpdateTime() < now - blockUpdateTimeout){ + logger.warn("Peer {} not sync for a long time.", peer.getInetAddress()); + isDisconnected[0] = true; + } + + if (!isDisconnected[0]) { + peer.getAdvInvSpread().values().stream() + .filter(time -> time < now - NetConstants.ADV_TIME_OUT) + .findFirst() + .ifPresent(time -> isDisconnected[0] = true); + } + + if (!isDisconnected[0]) { + peer.getSyncBlockRequested().values().stream() + .filter(time -> time < now - NetConstants.SYNC_TIME_OUT) + .findFirst() + .ifPresent(time -> isDisconnected[0] = true); + } + + if (isDisconnected[0]) { + peer.disconnect(ReasonCode.TIME_OUT); + } + }); + } + +} diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java index 7f7bf268cd8..a652d98d908 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -89,7 +89,6 @@ public void init () { public void close () { fetchExecutor.shutdown(); blockHandleExecutor.shutdown(); - logger.info("PeerSync closed."); } public void startSync(PeerConnection peer) { From c87983775ff7aaba9a62f0caf936b69df1d9cf5e Mon Sep 17 00:00:00 2001 From: wubin01 Date: Wed, 28 Nov 2018 17:04:48 +0800 Subject: [PATCH 19/41] update peer sync --- .../java/org/tron/core/net/peer/PeerSync.java | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/peer/PeerSync.java index a652d98d908..64ae67620fc 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/peer/PeerSync.java @@ -49,8 +49,8 @@ public class PeerSync { private Map blockJustReceived = new ConcurrentHashMap<>(); - private Cache requestBlockIds = CacheBuilder.newBuilder().maximumSize(10000) - .expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(10000) + private Cache requestBlockIds = CacheBuilder.newBuilder().maximumSize(10_000) + .expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(10_000) .recordStats().build(); private ScheduledExecutorService fetchExecutor = Executors.newSingleThreadScheduledExecutor(); @@ -81,7 +81,7 @@ public void init () { handleSyncBlock(); } } catch (Throwable t) { - logger.error("Unhandled exception", t); + logger.error("Handle sync block error.", t); } }, 10, 1, TimeUnit.SECONDS); } @@ -132,7 +132,6 @@ public void processBlock(PeerConnection peer, BlockMessage blockMessage) { public void onDisconnect (PeerConnection peer) { if (!peer.getSyncBlockRequested().isEmpty()) { peer.getSyncBlockRequested().keySet().forEach(blockId -> invalid(blockId)); - fetchFlag = true; } } @@ -192,9 +191,9 @@ private LinkedList getBlockChainSummary(PeerConnection peer) throws Exc return summary; } - private synchronized void startFetchSyncBlock() { + private void startFetchSyncBlock() { HashMap> send = new HashMap<>(); - HashSet request = new HashSet<>(); +// HashSet request = new HashSet<>(); tronProxy.getActivePeer().stream() .filter(peer -> peer.isNeedSyncFromPeer() && peer.isIdle()) @@ -203,9 +202,11 @@ private synchronized void startFetchSyncBlock() { send.put(peer, new LinkedList<>()); } for (BlockId blockId : peer.getSyncBlockToFetch()) { - if (!request.contains(blockId) && (requestBlockIds.getIfPresent(blockId) == null)) { + if (requestBlockIds.getIfPresent(blockId) == null) { + requestBlockIds.put(blockId, System.currentTimeMillis()); + peer.getSyncBlockRequested().put(blockId, System.currentTimeMillis()); send.get(peer).add(blockId); - request.add(blockId); +// request.add(blockId); if (send.get(peer).size() >= MAX_BLOCK_FETCH_PER_PEER) { break; } @@ -214,41 +215,16 @@ private synchronized void startFetchSyncBlock() { }); send.forEach((peer, blockIds) -> { - blockIds.forEach(blockId -> { - requestBlockIds.put(blockId, System.currentTimeMillis()); - peer.getSyncBlockRequested().put(blockId, System.currentTimeMillis()); - }); - List ids = new LinkedList<>(); - ids.addAll(blockIds); - if (!ids.isEmpty()) { - peer.sendMessage(new FetchInvDataMessage(ids, InventoryType.BLOCK)); +// blockIds.forEach(blockId -> { +// requestBlockIds.put(blockId, System.currentTimeMillis()); +// peer.getSyncBlockRequested().put(blockId, System.currentTimeMillis()); +// }); + if (!blockIds.isEmpty()) { + peer.sendMessage(new FetchInvDataMessage(new LinkedList<>(blockIds), InventoryType.BLOCK)); } }); - send.clear(); - } - - private void processSyncBlock (BlockCapsule block) { - boolean flag = true; - BlockId blockId = block.getBlockId(); - try { - tronProxy.processBlock(block); - } catch (Exception e) { - logger.error("Process sync block {} failed.", blockId.getString(), e); - flag = false; - } - for (PeerConnection peer: tronProxy.getActivePeer()) { - if (peer.getSyncBlockInProcess().remove(blockId)) { - if (flag){ - peer.setBlockBothHave(blockId); - if (peer.getSyncBlockToFetch().isEmpty()) { - syncNext(peer); - } - }else { - peer.disconnect(ReasonCode.BAD_BLOCK); - } - } - } +// send.clear(); } private synchronized void handleSyncBlock() { @@ -273,7 +249,7 @@ private synchronized void handleSyncBlock() { } final boolean[] isFound = {false}; tronProxy.getActivePeer().stream() - .filter(peer -> !peer.getSyncBlockToFetch().isEmpty() && peer.getSyncBlockToFetch().peek().equals(msg.getBlockId())) + .filter(peer -> msg.getBlockId().equals(peer.getSyncBlockToFetch().peek())) .forEach(peer -> { peer.getSyncBlockToFetch().pop(); peer.getSyncBlockInProcess().add(msg.getBlockId()); @@ -288,4 +264,27 @@ private synchronized void handleSyncBlock() { } } + private void processSyncBlock (BlockCapsule block) { + boolean flag = true; + BlockId blockId = block.getBlockId(); + try { + tronProxy.processBlock(block); + } catch (Exception e) { + logger.error("Process sync block {} failed.", blockId.getString(), e); + flag = false; + } + for (PeerConnection peer: tronProxy.getActivePeer()) { + if (peer.getSyncBlockInProcess().remove(blockId)) { + if (flag){ + peer.setBlockBothHave(blockId); + if (peer.getSyncBlockToFetch().isEmpty()) { + syncNext(peer); + } + }else { + peer.disconnect(ReasonCode.BAD_BLOCK); + } + } + } + } + } From 71e0151783c2e8311a0783bfd05ea2b39944d905 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 10 Dec 2018 14:57:27 +0800 Subject: [PATCH 20/41] add advBlockCacheSize limitation --- src/main/java/org/tron/program/SolidityNode.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/tron/program/SolidityNode.java b/src/main/java/org/tron/program/SolidityNode.java index 85866517de7..3862c31ee01 100644 --- a/src/main/java/org/tron/program/SolidityNode.java +++ b/src/main/java/org/tron/program/SolidityNode.java @@ -49,7 +49,7 @@ public class SolidityNode { private volatile long lastSolidityBlockNum; - private long startTime = System.currentTimeMillis(); + private long maxBlockCacheSize = 10_000; private volatile boolean syncFlag = true; @@ -89,7 +89,7 @@ private void getSyncBlock() { if (blockNum == 0) { break; } - if (blockMap.size() > 10000) { + if (blockMap.size() > maxBlockCacheSize) { sleep(1000); continue; } @@ -137,7 +137,7 @@ private void getAdvBlock() { long blockNum = ID.incrementAndGet(); while (flag) { try { - if (blockNum > remoteLastSolidityBlockNum) { + if (blockNum > remoteLastSolidityBlockNum || blockMap.size() > maxBlockCacheSize) { sleep(3000); remoteLastSolidityBlockNum = getLastSolidityBlockNum(); continue; @@ -198,12 +198,11 @@ private void processBlock() { loopProcessBlock(block); blockBakQueue.put(block); logger.info( - "Success to process block: {}, blockMapSize: {}, blockQueueSize: {}, blockBakQueue: {}, cost {}.", + "Success to process block: {}, blockMapSize: {}, blockQueueSize: {}, blockBakQueue: {}", block.getBlockHeader().getRawData().getNumber(), blockMap.size(), blockQueue.size(), - blockBakQueue.size(), - (System.currentTimeMillis() - startTime)); + blockBakQueue.size()); } catch (Exception e) { logger.error(e.getMessage()); sleep(100); From c6e2075cf56f05cda78daefe3e9ea22f9b8e7575 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 17 Dec 2018 15:37:48 +0800 Subject: [PATCH 21/41] modify peer connection --- .../java/org/tron/core/net/TronNetClient.java | 6 +-- .../org/tron/core/net/TronNetService.java | 16 +++---- .../java/org/tron/core/net/TronProxy.java | 4 +- .../net/messagehandler/BlockMsgHandler.java | 16 +++---- .../ChainInventoryMsgHandler.java | 8 ++-- .../FetchInvDataMsgHandler.java | 17 ++++--- .../messagehandler/InventoryMsgHandler.java | 9 ++-- .../TransactionsMsgHandler.java | 6 +-- .../tron/core/net/peer/PeerConnection.java | 45 +++++++++---------- .../tron/core/net/peer/PeerStatusCheck.java | 2 +- .../PeerAdv.java => service/AdvService.java} | 14 +++--- .../SyncService.java} | 5 ++- 12 files changed, 73 insertions(+), 75 deletions(-) rename src/main/java/org/tron/core/net/{peer/PeerAdv.java => service/AdvService.java} (94%) rename src/main/java/org/tron/core/net/{peer/PeerSync.java => service/SyncService.java} (98%) diff --git a/src/main/java/org/tron/core/net/TronNetClient.java b/src/main/java/org/tron/core/net/TronNetClient.java index 823938d877d..f05098b6843 100644 --- a/src/main/java/org/tron/core/net/TronNetClient.java +++ b/src/main/java/org/tron/core/net/TronNetClient.java @@ -3,16 +3,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.overlay.message.Message; -import org.tron.core.net.peer.PeerAdv; +import org.tron.core.net.service.AdvService; @Component public class TronNetClient { @Autowired - private PeerAdv peerAdv; + private AdvService advService; public void broadcast(Message msg) { - peerAdv.broadcast(msg); + advService.broadcast(msg); } } diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index 848ae8c922c..aafbb20d8e6 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -13,10 +13,10 @@ import org.tron.core.net.messagehandler.InventoryMsgHandler; import org.tron.core.net.messagehandler.SyncBlockChainMsgHadler; import org.tron.core.net.messagehandler.TransactionsMsgHandler; -import org.tron.core.net.peer.PeerAdv; +import org.tron.core.net.service.AdvService; import org.tron.core.net.peer.PeerConnection; import org.tron.core.net.peer.PeerStatusCheck; -import org.tron.core.net.peer.PeerSync; +import org.tron.core.net.service.SyncService; import org.tron.protos.Protocol.ReasonCode; @Slf4j @@ -27,10 +27,10 @@ public class TronNetService { private ChannelManager channelManager; @Autowired - private PeerAdv peerAdv; + private AdvService advService; @Autowired - private PeerSync peerSync; + private SyncService syncService; @Autowired private PeerStatusCheck peerStatusCheck; @@ -56,8 +56,8 @@ public class TronNetService { public void start () { channelManager.init(); - peerAdv.init(); - peerSync.init(); + advService.init(); + syncService.init(); peerStatusCheck.init(); transactionsMsgHandler.init(); logger.info("TronNetService start successfully."); @@ -65,8 +65,8 @@ public void start () { public void close () { channelManager.close(); - peerAdv.close(); - peerSync.close(); + advService.close(); + syncService.close(); peerStatusCheck.close(); transactionsMsgHandler.close(); logger.info("TronNetService closed successfully."); diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronProxy.java index d6d1b4b6bb3..89242679cda 100644 --- a/src/main/java/org/tron/core/net/TronProxy.java +++ b/src/main/java/org/tron/core/net/TronProxy.java @@ -56,10 +56,12 @@ public class TronProxy { @Getter private Object blockLock = new Object(); + private int blockIdCacheSize = 100; + private Queue freshBlockId = new ConcurrentLinkedQueue() { @Override public boolean offer(BlockId blockId) { - if (size() > 200) { + if (size() > blockIdCacheSize) { super.poll(); } return super.offer(blockId); diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 6e7a200f19c..21bef5b9348 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -15,9 +15,9 @@ import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.Item; -import org.tron.core.net.peer.PeerAdv; import org.tron.core.net.peer.PeerConnection; -import org.tron.core.net.peer.PeerSync; +import org.tron.core.net.service.AdvService; +import org.tron.core.net.service.SyncService; import org.tron.core.services.WitnessProductBlockService; import org.tron.protos.Protocol.Inventory.InventoryType; @@ -32,10 +32,10 @@ public class BlockMsgHandler implements TronMsgHandler { private TronNetClient tronManager; @Autowired - private PeerAdv peerAdv; + private AdvService advService; @Autowired - private PeerSync peerSync; + private SyncService syncService; @Autowired private WitnessProductBlockService witnessProductBlockService; @@ -53,7 +53,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti Item item = new Item(blockId, InventoryType.BLOCK); if (peer.getSyncBlockRequested().containsKey(blockId)) { peer.getSyncBlockRequested().remove(blockId); - peerSync.processBlock(peer, blockMessage); + syncService.processBlock(peer, blockMessage); } else { peer.getAdvInvRequest().remove(item); processBlock(peer, blockMessage.getBlockCapsule()); @@ -79,17 +79,17 @@ private void processBlock(PeerConnection peer, BlockCapsule block) throws Excep BlockId blockId = block.getBlockId(); if (!tronProxy.containBlock(block.getParentBlockId())) { logger.warn("Get unlink block {} from {}, head is {}.", blockId.getString(), peer.getInetAddress(), tronProxy.getHeadBlockId().getString()); - peerSync.startSync(peer); + syncService.startSync(peer); return; } tronProxy.processBlock(block); witnessProductBlockService.validWitnessProductTwoBlock(block); tronProxy.getActivePeer().forEach(p -> { - if (p.getAdvInvReceive().containsKey(blockId)) { + if (p.getAdvInvReceive().getIfPresent(blockId) != null) { p.setBlockBothHave(blockId); } }); - peerAdv.broadcast(new BlockMessage(block)); + advService.broadcast(new BlockMessage(block)); } } diff --git a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java index 3b1e0049bed..4a24ec7e163 100644 --- a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -20,7 +20,7 @@ import org.tron.core.net.message.ChainInventoryMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.PeerConnection; -import org.tron.core.net.peer.PeerSync; +import org.tron.core.net.service.SyncService; @Slf4j @Component @@ -30,7 +30,7 @@ public class ChainInventoryMsgHandler implements TronMsgHandler { private TronProxy tronProxy; @Autowired - private PeerSync peerSync; + private SyncService syncService; @Setter private TronNetClient tronManager; @@ -78,9 +78,9 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti if ((chainInventoryMessage.getRemainNum() == 0 && !peer.getSyncBlockToFetch().isEmpty()) || (chainInventoryMessage.getRemainNum() != 0 && peer.getSyncBlockToFetch().size() > NodeConstant.SYNC_FETCH_BATCH_NUM)) { - peerSync.setFetchFlag(true); + syncService.setFetchFlag(true); }else { - peerSync.syncNext(peer); + syncService.syncNext(peer); } } diff --git a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index ded8d18e5a2..983b7aab28a 100644 --- a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -2,7 +2,6 @@ import com.google.common.collect.Lists; import java.util.List; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -22,9 +21,9 @@ import org.tron.core.net.message.TransactionsMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.Item; -import org.tron.core.net.peer.PeerAdv; import org.tron.core.net.peer.PeerConnection; -import org.tron.core.net.peer.PeerSync; +import org.tron.core.net.service.AdvService; +import org.tron.core.net.service.SyncService; import org.tron.protos.Protocol.Inventory.InventoryType; import org.tron.protos.Protocol.ReasonCode; import org.tron.protos.Protocol.Transaction; @@ -37,10 +36,10 @@ public class FetchInvDataMsgHandler implements TronMsgHandler { private TronProxy tronProxy; @Autowired - private PeerSync peerSync; + private SyncService syncService; @Autowired - private PeerAdv peerAdv; + private AdvService advService; private int MAX_SIZE = 1_000_000; @@ -58,7 +57,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { Item item = new Item(hash, type); - Message message = peerAdv.getMessage(item); + Message message = advService.getMessage(item); if (message == null) { try { message = tronProxy.getData(hash, type); @@ -98,19 +97,19 @@ private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) thr if (type == MessageTypes.TRX) { int fetchCount = peer.getNodeStatistics().messageStatistics.tronInTrxFetchInvDataElement .getCount(10); - int maxCount = peerAdv.getTrxCount().getCount(60); + int maxCount = advService.getTrxCount().getCount(60); if (fetchCount > maxCount) { throw new P2pException(TypeEnum.BAD_MESSAGE, "maxCount: " + maxCount + ", fetchCount: " + fetchCount); } for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - if (!peer.getAdvInvSpread().containsKey(new Item(hash, InventoryType.TRX))) { + if (peer.getAdvInvSpread().getIfPresent(new Item(hash, InventoryType.TRX)) == null) { throw new P2pException(TypeEnum.BAD_MESSAGE, "not spread inv: {}" + hash); } } } else { boolean isAdv = true; for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - if (!peer.getAdvInvSpread().containsKey(new Item(hash, InventoryType.BLOCK))) { + if (peer.getAdvInvSpread().getIfPresent(new Item(hash, InventoryType.BLOCK)) == null) { isAdv = false; break; } diff --git a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index 094aef44bdf..789d55cb307 100644 --- a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -4,14 +4,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.utils.Sha256Hash; -import org.tron.core.config.Parameter.NetConstants; -import org.tron.core.exception.P2pException; -import org.tron.core.exception.P2pException.TypeEnum; import org.tron.core.net.TronProxy; import org.tron.core.net.message.InventoryMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.Item; -import org.tron.core.net.peer.PeerAdv; +import org.tron.core.net.service.AdvService; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Inventory.InventoryType; @@ -23,7 +20,7 @@ public class InventoryMsgHandler implements TronMsgHandler{ private TronProxy tronProxy; @Autowired - private PeerAdv peerAdv; + private AdvService advService; @Autowired private TransactionsMsgHandler transactionsMsgHandler; @@ -42,7 +39,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti for (Sha256Hash id : inventoryMessage.getHashList()) { Item item = new Item(id, type); peer.getAdvInvReceive().put(item, System.currentTimeMillis()); - if (!peerAdv.addInv(item)) { + if (!advService.addInv(item)) { logger.info("This item {} from peer {} Already exist.", item, peer.getInetAddress()); } } diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index 79cd9f38318..67b97af16ce 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -19,7 +19,7 @@ import org.tron.core.net.message.TransactionsMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.Item; -import org.tron.core.net.peer.PeerAdv; +import org.tron.core.net.service.AdvService; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Inventory.InventoryType; import org.tron.protos.Protocol.ReasonCode; @@ -34,7 +34,7 @@ public class TransactionsMsgHandler implements TronMsgHandler { private TronProxy tronProxy; @Autowired - private PeerAdv peerAdv; + private AdvService advService; private static int MAX_TRX_SIZE = 50_000; @@ -130,7 +130,7 @@ private void handleTransaction (PeerConnection peer, TransactionMessage trx) { } try { tronProxy.pushTransaction(trx.getTransactionCapsule()); - peerAdv.broadcast(trx); + advService.broadcast(trx); }catch (P2pException e) { logger.warn("Trx {} from peer {} process failed. type: {}, reason: {}", trx.getMessageId(), peer.getInetAddress(), e.getType(), e.getMessage()); diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index be06a949bcc..e05edb85bb3 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -1,7 +1,5 @@ package org.tron.core.net.peer; -import static org.tron.core.config.Parameter.NetConstants.MAX_INVENTORY_SIZE_IN_MINUTES; - import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import java.util.Deque; @@ -12,6 +10,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.TimeUnit; import javafx.util.Pair; import lombok.Getter; import lombok.Setter; @@ -23,10 +22,11 @@ import org.tron.common.overlay.message.Message; import org.tron.common.overlay.server.Channel; import org.tron.common.utils.Sha256Hash; -import org.tron.common.utils.Time; import org.tron.core.capsule.BlockCapsule.BlockId; import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.net.TronProxy; +import org.tron.core.net.service.AdvService; +import org.tron.core.net.service.SyncService; @Slf4j @Component @@ -37,10 +37,12 @@ public class PeerConnection extends Channel { private TronProxy tronProxy; @Autowired - private PeerSync peerSync; + private SyncService syncService; @Autowired - private PeerAdv peerAdv; + private AdvService advService; + + private int invCacheSize = 500_000; @Setter @Getter @@ -52,11 +54,13 @@ public class PeerConnection extends Channel { @Setter @Getter - private Map advInvReceive = new ConcurrentHashMap<>(); + private Cache advInvReceive = CacheBuilder.newBuilder().maximumSize(invCacheSize) + .expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); @Setter @Getter - private Map advInvSpread = new ConcurrentHashMap<>(); + private Cache advInvSpread = CacheBuilder.newBuilder().maximumSize(invCacheSize) + .expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); @Setter @Getter @@ -108,19 +112,6 @@ public void setBlockBothHave (BlockId blockId) { @Getter private boolean needSyncFromUs; - public void cleanInvGarbage() { - - long time = Time.getCurrentMillis() - MAX_INVENTORY_SIZE_IN_MINUTES * 60 * 1000; - - Iterator> iterator = this.advInvReceive.entrySet().iterator(); - - removeIterator(iterator, time); - - iterator = this.advInvSpread.entrySet().iterator(); - - removeIterator(iterator, time); - } - private void removeIterator(Iterator> iterator, long oldestTimestamp) { while (iterator.hasNext()) { Map.Entry entry = iterator.next(); @@ -142,15 +133,23 @@ public void sendMessage(Message message) { public void onConnectPeer() { if (getHelloMessage().getHeadBlockId().getNum() > tronProxy.getHeadBlockId().getNum()) { setTronState(TronState.SYNCING); - peerSync.startSync(this); + syncService.startSync(this); } else { setTronState(TronState.SYNC_COMPLETED); } } public void onDisconnectPeer() { - peerSync.onDisconnect(this); - peerAdv.onDisconnect(this); + syncService.onDisconnect(this); + advService.onDisconnect(this); + advInvReceive.cleanUp(); + advInvSpread.cleanUp(); + advInvRequest.clear(); + syncBlockIdCache.cleanUp(); + syncBlockToFetch.clear(); + syncBlockRequested.clear(); + syncBlockInProcess.clear(); + syncBlockInProcess.clear(); } public String log () { diff --git a/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java b/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java index cfd137fcaeb..6bf047338b0 100644 --- a/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java +++ b/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java @@ -51,7 +51,7 @@ public void statusCheck() { } if (!isDisconnected[0]) { - peer.getAdvInvSpread().values().stream() + peer.getAdvInvRequest().values().stream() .filter(time -> time < now - NetConstants.ADV_TIME_OUT) .findFirst() .ifPresent(time -> isDisconnected[0] = true); diff --git a/src/main/java/org/tron/core/net/peer/PeerAdv.java b/src/main/java/org/tron/core/net/service/AdvService.java similarity index 94% rename from src/main/java/org/tron/core/net/peer/PeerAdv.java rename to src/main/java/org/tron/core/net/service/AdvService.java index 31bcbd906b8..b0864bfe4a5 100644 --- a/src/main/java/org/tron/core/net/peer/PeerAdv.java +++ b/src/main/java/org/tron/core/net/service/AdvService.java @@ -1,4 +1,4 @@ -package org.tron.core.net.peer; +package org.tron.core.net.service; import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import static org.tron.core.config.Parameter.NetConstants.MAX_TRX_FETCH_PER_PEER; @@ -30,11 +30,13 @@ import org.tron.core.net.message.FetchInvDataMessage; import org.tron.core.net.message.InventoryMessage; import org.tron.core.net.message.TransactionMessage; +import org.tron.core.net.peer.Item; +import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Inventory.InventoryType; @Slf4j @Component -public class PeerAdv { +public class AdvService { @Autowired private TronProxy tronProxy; @@ -130,9 +132,7 @@ public void onDisconnect (PeerConnection peer) { if (!peer.getAdvInvRequest().isEmpty()) { peer.getAdvInvRequest().keySet().forEach(item -> { if (tronProxy.getActivePeer().stream() - .filter(p -> !p.equals(peer) && p.getAdvInvReceive().containsKey(item)) - .findFirst() - .isPresent()) { + .anyMatch(p -> !p.equals(peer) && p.getAdvInvReceive().getIfPresent(item) != null)){ invToFetch.put(item, System.currentTimeMillis()); } }); @@ -157,7 +157,7 @@ private void consumerInvToFetch() { return; } peers.stream() - .filter(peer -> peer.getAdvInvReceive().containsKey(item) && invSender.getSize(peer) < MAX_TRX_FETCH_PER_PEER) + .filter(peer -> peer.getAdvInvReceive().getIfPresent(item) != null && invSender.getSize(peer) < MAX_TRX_FETCH_PER_PEER) .sorted(Comparator.comparingInt(peer -> invSender.getSize(peer))) .findFirst().ifPresent(peer -> { invSender.add(item, peer); @@ -184,7 +184,7 @@ private void consumerInvToSpread() { tronProxy.getActivePeer().stream() .filter(peer -> !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) .forEach(peer -> spread.entrySet().stream() - .filter(entry -> !peer.getAdvInvReceive().containsKey(entry.getKey()) && !peer.getAdvInvSpread().containsKey(entry.getKey())) + .filter(entry -> peer.getAdvInvReceive().getIfPresent(entry.getKey()) == null && peer.getAdvInvSpread().getIfPresent(entry.getKey()) == null) .forEach(entry -> { peer.getAdvInvSpread().put(entry.getKey(), Time.getCurrentMillis()); invSender.add(entry.getKey(), peer); diff --git a/src/main/java/org/tron/core/net/peer/PeerSync.java b/src/main/java/org/tron/core/net/service/SyncService.java similarity index 98% rename from src/main/java/org/tron/core/net/peer/PeerSync.java rename to src/main/java/org/tron/core/net/service/SyncService.java index 64ae67620fc..5ac315651f7 100644 --- a/src/main/java/org/tron/core/net/peer/PeerSync.java +++ b/src/main/java/org/tron/core/net/service/SyncService.java @@ -1,4 +1,4 @@ -package org.tron.core.net.peer; +package org.tron.core.net.service; import static org.tron.core.config.Parameter.NetConstants.MAX_BLOCK_FETCH_PER_PEER; @@ -32,12 +32,13 @@ import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.FetchInvDataMessage; import org.tron.core.net.message.SyncBlockChainMessage; +import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Inventory.InventoryType; import org.tron.protos.Protocol.ReasonCode; @Slf4j @Component -public class PeerSync { +public class SyncService { @Autowired private TronProxy tronProxy; From 3bf77842f8df347010d0b7b0879b28142332cae2 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 14 Jan 2019 15:51:02 +0800 Subject: [PATCH 22/41] modify p2p excepiton --- .../org/tron/core/exception/P2pException.java | 2 + .../java/org/tron/core/net/TronProxy.java | 60 ++++++++++++------- .../net/messagehandler/BlockMsgHandler.java | 6 +- .../ChainInventoryMsgHandler.java | 4 +- .../FetchInvDataMsgHandler.java | 4 +- .../messagehandler/InventoryMsgHandler.java | 6 +- .../SyncBlockChainMsgHadler.java | 6 +- .../TransactionsMsgHandler.java | 4 +- .../net/messagehandler/TronMsgHandler.java | 3 +- 9 files changed, 56 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/tron/core/exception/P2pException.java b/src/main/java/org/tron/core/exception/P2pException.java index 31d1f0df921..246c8e807e1 100644 --- a/src/main/java/org/tron/core/exception/P2pException.java +++ b/src/main/java/org/tron/core/exception/P2pException.java @@ -36,6 +36,8 @@ public enum TypeEnum { BAD_BLOCK (10, "bad block"), BAD_TRX (11, "bad trx"), TRX_EXE_FAILED (12, "trx exe failed"), + DB_ITEM_NOT_FOUND (13, "DB item not found"), + DEFAULT (100, "default exception"); private Integer value; diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronProxy.java index 89242679cda..e5854acbb72 100644 --- a/src/main/java/org/tron/core/net/TronProxy.java +++ b/src/main/java/org/tron/core/net/TronProxy.java @@ -76,13 +76,11 @@ public long getSyncBeginNumber() { return dbManager.getSyncBeginNumber(); } - public long getBlockTime(BlockId id) { + public long getBlockTime(BlockId id) throws P2pException { try { return dbManager.getBlockById(id).getTimeStamp(); - } catch (BadItemException e) { - return dbManager.getGenesisBlock().getTimeStamp(); - } catch (ItemNotFoundException e) { - return dbManager.getGenesisBlock().getTimeStamp(); + } catch (BadItemException | ItemNotFoundException e) { + throw new P2pException(TypeEnum.DB_ITEM_NOT_FOUND, id.getString()); } } @@ -98,7 +96,13 @@ public BlockId getGenesisBlockId() { return dbManager.getGenesisBlockId(); } - public BlockId getBlockIdByNum(long num) throws Exception {return dbManager.getBlockIdByNum(num);} + public BlockId getBlockIdByNum(long num) throws P2pException { + try { + return dbManager.getBlockIdByNum(num); + }catch (ItemNotFoundException e) { + throw new P2pException(TypeEnum.DB_ITEM_NOT_FOUND, "num: " + num); + } + } public BlockCapsule getGenesisBlock() { return dbManager.getGenesisBlock(); @@ -116,8 +120,12 @@ public boolean containBlockInMainChain(BlockId id) { return dbManager.containBlockInMainChain(id); } - public LinkedList getBlockChainHashesOnFork(BlockId forkBlockHash) throws Exception { - return dbManager.getBlockChainHashesOnFork(forkBlockHash); + public LinkedList getBlockChainHashesOnFork(BlockId forkBlockHash) throws P2pException { + try { + return dbManager.getBlockChainHashesOnFork(forkBlockHash); + }catch (NonCommonBlockException e){ + throw new P2pException(TypeEnum.HARD_FORKED, forkBlockHash.getString()); + } } public boolean canChainRevoke(long num) { @@ -133,22 +141,27 @@ public boolean contain(Sha256Hash hash, MessageTypes type) { return false; } - public Message getData(Sha256Hash hash, InventoryType type) throws StoreException { - switch (type) { - case BLOCK: - return new BlockMessage(dbManager.getBlockById(hash)); - case TRX: - TransactionCapsule tx = dbManager.getTransactionStore().get(hash.getBytes()); - if (tx != null) { - return new TransactionMessage(tx.getData()); - } - throw new ItemNotFoundException("transaction is not found"); - default: - throw new BadItemException("message type not block or trx."); + public Message getData(Sha256Hash hash, InventoryType type) throws P2pException { + try { + switch (type) { + case BLOCK: + return new BlockMessage(dbManager.getBlockById(hash)); + case TRX: + TransactionCapsule tx = dbManager.getTransactionStore().get(hash.getBytes()); + if (tx != null) { + return new TransactionMessage(tx.getData()); + } + throw new StoreException(); + default: + throw new StoreException(); + } + }catch (StoreException e) { + throw new P2pException(TypeEnum.DB_ITEM_NOT_FOUND, + "type: " + type + ", hash: " + hash.getByteString()); } } - public void processBlock(BlockCapsule block) throws Exception { + public void processBlock(BlockCapsule block) throws P2pException { synchronized (blockLock) { try { if (!freshBlockId.contains(block.getBlockId())) { @@ -157,7 +170,8 @@ public void processBlock(BlockCapsule block) throws Exception { freshBlockId.add(block.getBlockId()); logger.info("Success process block {}.", block.getBlockId().getString()); } - } catch (ValidateSignatureException + } catch (InterruptedException + | ValidateSignatureException | ContractValidateException | ContractExeException | UnLinkedBlockException @@ -178,7 +192,7 @@ public void processBlock(BlockCapsule block) throws Exception { } } - public void pushTransaction (TransactionCapsule trx) throws Exception { + public void pushTransaction (TransactionCapsule trx) throws P2pException { try { dbManager.pushTransaction(trx); } catch (ContractSizeNotEqualToOneException diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 21bef5b9348..f7a9c91ccff 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -43,7 +43,7 @@ public class BlockMsgHandler implements TronMsgHandler { private int maxBlockSize = BLOCK_SIZE + 1000; @Override - public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { + public void processMessage (PeerConnection peer, TronMessage msg) throws P2pException { BlockMessage blockMessage = (BlockMessage) msg; @@ -60,7 +60,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti } } - private void check (PeerConnection peer, BlockMessage msg) throws Exception { + private void check (PeerConnection peer, BlockMessage msg) throws P2pException { Item item = new Item(msg.getBlockId(), InventoryType.BLOCK); if (!peer.getSyncBlockRequested().containsKey(msg.getBlockId()) && !peer.getAdvInvRequest().containsKey(item)) { throw new P2pException(TypeEnum.BAD_MESSAGE, "no request"); @@ -75,7 +75,7 @@ private void check (PeerConnection peer, BlockMessage msg) throws Exception { } } - private void processBlock(PeerConnection peer, BlockCapsule block) throws Exception { + private void processBlock(PeerConnection peer, BlockCapsule block) throws P2pException { BlockId blockId = block.getBlockId(); if (!tronProxy.containBlock(block.getParentBlockId())) { logger.warn("Get unlink block {} from {}, head is {}.", blockId.getString(), peer.getInetAddress(), tronProxy.getHeadBlockId().getString()); diff --git a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java index 4a24ec7e163..40aa1203194 100644 --- a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -36,7 +36,7 @@ public class ChainInventoryMsgHandler implements TronMsgHandler { private TronNetClient tronManager; @Override - public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { + public void processMessage (PeerConnection peer, TronMessage msg) throws P2pException { ChainInventoryMessage chainInventoryMessage = (ChainInventoryMessage) msg; @@ -84,7 +84,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti } } - private void check(PeerConnection peer, ChainInventoryMessage msg) throws Exception { + private void check(PeerConnection peer, ChainInventoryMessage msg) throws P2pException { if (peer.getSyncChainRequested() == null) { throw new P2pException(TypeEnum.BAD_MESSAGE, "not send syncBlockChainMsg"); } diff --git a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index 983b7aab28a..28a2bf20719 100644 --- a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -44,7 +44,7 @@ public class FetchInvDataMsgHandler implements TronMsgHandler { private int MAX_SIZE = 1_000_000; @Override - public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { + public void processMessage (PeerConnection peer, TronMessage msg) throws P2pException { FetchInvDataMessage fetchInvDataMsg = (FetchInvDataMessage) msg; @@ -89,7 +89,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti } } - private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) throws Exception{ + private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) throws P2pException{ MessageTypes type = fetchInvDataMsg.getInvMessageType(); //todo check inv size not gt MAX_INV_FETCH_PER_PEER diff --git a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index 789d55cb307..5071ea618ac 100644 --- a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -8,8 +8,8 @@ import org.tron.core.net.message.InventoryMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.Item; -import org.tron.core.net.service.AdvService; import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.service.AdvService; import org.tron.protos.Protocol.Inventory.InventoryType; @Slf4j @@ -28,7 +28,7 @@ public class InventoryMsgHandler implements TronMsgHandler{ private int maxCountIn10s = 10_000; @Override - public void processMessage (PeerConnection peer, TronMessage msg) throws Exception { + public void processMessage (PeerConnection peer, TronMessage msg) { InventoryMessage inventoryMessage = (InventoryMessage) msg; InventoryType type = inventoryMessage.getInventoryType(); @@ -45,7 +45,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws Excepti } } - private boolean check (PeerConnection peer, InventoryMessage inventoryMessage) throws Exception { + private boolean check (PeerConnection peer, InventoryMessage inventoryMessage) { InventoryType type = inventoryMessage.getInventoryType(); int size = inventoryMessage.getHashList().size(); diff --git a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java index 0fe35f589db..c892c7d2daa 100644 --- a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java +++ b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java @@ -37,7 +37,7 @@ public class SyncBlockChainMsgHadler implements TronMsgHandler { private TronProxy tronProxy; @Override - public void processMessage(PeerConnection peer, TronMessage msg) throws Exception { + public void processMessage(PeerConnection peer, TronMessage msg) throws P2pException { SyncBlockChainMessage syncBlockChainMessage = (SyncBlockChainMessage) msg; @@ -67,7 +67,7 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws Exceptio peer.sendMessage(new ChainInventoryMessage(blockIds, remainNum)); } - private void check(PeerConnection peer, SyncBlockChainMessage msg) throws Exception{ + private void check(PeerConnection peer, SyncBlockChainMessage msg) throws P2pException { List blockIds = msg.getBlockIds(); if (CollectionUtils.isEmpty(blockIds)){ throw new P2pException(TypeEnum.BAD_MESSAGE, "SyncBlockChain blockIds is empty"); @@ -90,7 +90,7 @@ private void check(PeerConnection peer, SyncBlockChainMessage msg) throws Except } } - private LinkedList getLostBlockIds(List blockIds) throws Exception{ + private LinkedList getLostBlockIds(List blockIds) throws P2pException { BlockId unForkId = null; for (int i = blockIds.size() - 1; i >= 0; i--){ diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index eb0939aee56..8c8a04171bc 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -80,7 +80,7 @@ public boolean isBusy() { } @Override - public void processMessage(PeerConnection peer, TronMessage msg) throws Exception { + public void processMessage(PeerConnection peer, TronMessage msg) throws P2pException { TransactionsMessage transactionsMessage = (TransactionsMessage) msg; check (peer, transactionsMessage); for (Transaction trx : transactionsMessage.getTransactions().getTransactionsList()) { @@ -95,7 +95,7 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws Exceptio } } - private void check(PeerConnection peer, TransactionsMessage msg) throws Exception { + private void check(PeerConnection peer, TransactionsMessage msg) throws P2pException { for (Transaction trx : msg.getTransactions().getTransactionsList()) { Item item = new Item(new TransactionMessage(trx).getMessageId(), InventoryType.TRX); if (!peer.getAdvInvRequest().containsKey(item)) { diff --git a/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java index 0508ccdd19a..e6052f49597 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TronMsgHandler.java @@ -1,10 +1,11 @@ package org.tron.core.net.messagehandler; +import org.tron.core.exception.P2pException; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.PeerConnection; public interface TronMsgHandler { - void processMessage(PeerConnection peer, TronMessage msg) throws Exception; + void processMessage(PeerConnection peer, TronMessage msg) throws P2pException; } From add9e073bf03cbb1471455916f504587652352f8 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Thu, 17 Jan 2019 11:43:02 +0800 Subject: [PATCH 23/41] modify test --- .../{node/BaseNetTest.java => BaseNet.java} | 84 +---- .../java/org/tron/core/net/BaseNetTest.java | 16 + .../{node/TcpNetTest.java => TcpTest.java} | 100 ++--- src/test/java/org/tron/core/net/UdpTest.java | 47 +-- .../ChainInventoryMsgHandlerTest.java | 65 ++++ .../org/tron/core/net/node/BroadTest.java | 305 --------------- .../net/node/FinishProcessSyncBlockTest.java | 222 ----------- .../net/node/GetBlockChainSummaryTest.java | 350 ------------------ .../core/net/node/GetLostBlockIdsTest.java | 332 ----------------- .../core/net/node/HandleBlockMessageTest.java | 246 ------------ .../core/net/node/HandleSyncBlockTest.java | 271 -------------- .../core/net/node/HandleTransactionTest.java | 234 ------------ .../org/tron/core/net/node/NodeImplTest.java | 205 ---------- .../net/node/StartFetchSyncBlockTest.java | 257 ------------- .../node/override/HandshakeHandlerTest.java | 38 -- .../net/node/override/PeerClientTest.java | 86 ----- .../override/TronChannelInitializerTest.java | 85 ----- .../core/services/NodeInfoServiceTest.java | 22 +- .../tron/core/services/RpcApiServiceTest.java | 5 - 19 files changed, 156 insertions(+), 2814 deletions(-) rename src/test/java/org/tron/core/net/{node/BaseNetTest.java => BaseNet.java} (66%) create mode 100644 src/test/java/org/tron/core/net/BaseNetTest.java rename src/test/java/org/tron/core/net/{node/TcpNetTest.java => TcpTest.java} (77%) create mode 100644 src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java delete mode 100644 src/test/java/org/tron/core/net/node/BroadTest.java delete mode 100644 src/test/java/org/tron/core/net/node/FinishProcessSyncBlockTest.java delete mode 100644 src/test/java/org/tron/core/net/node/GetBlockChainSummaryTest.java delete mode 100644 src/test/java/org/tron/core/net/node/GetLostBlockIdsTest.java delete mode 100644 src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java delete mode 100644 src/test/java/org/tron/core/net/node/HandleSyncBlockTest.java delete mode 100644 src/test/java/org/tron/core/net/node/HandleTransactionTest.java delete mode 100644 src/test/java/org/tron/core/net/node/NodeImplTest.java delete mode 100644 src/test/java/org/tron/core/net/node/StartFetchSyncBlockTest.java delete mode 100644 src/test/java/org/tron/core/net/node/override/HandshakeHandlerTest.java delete mode 100644 src/test/java/org/tron/core/net/node/override/PeerClientTest.java delete mode 100644 src/test/java/org/tron/core/net/node/override/TronChannelInitializerTest.java delete mode 100644 src/test/java/org/tron/core/services/RpcApiServiceTest.java diff --git a/src/test/java/org/tron/core/net/node/BaseNetTest.java b/src/test/java/org/tron/core/net/BaseNet.java similarity index 66% rename from src/test/java/org/tron/core/net/node/BaseNetTest.java rename to src/test/java/org/tron/core/net/BaseNet.java index 4bf680d22ff..d09fdbcff18 100644 --- a/src/test/java/org/tron/core/net/node/BaseNetTest.java +++ b/src/test/java/org/tron/core/net/BaseNet.java @@ -1,4 +1,4 @@ -package org.tron.core.net.node; +package org.tron.core.net; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; @@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Before; +import org.junit.BeforeClass; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; @@ -32,39 +33,29 @@ import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; import org.tron.core.db.Manager; +import org.tron.core.net.TronProxy; import org.tron.core.net.peer.PeerConnection; import org.tron.core.services.RpcApiService; import org.tron.core.services.WitnessService; @Slf4j -public abstract class BaseNetTest { +public abstract class BaseNet { - protected TronApplicationContext context; - protected NodeImpl node; - protected RpcApiService rpcApiService; - protected PeerClient peerClient; - protected ChannelManager channelManager; - protected SyncPool pool; - protected Manager manager; - private Application appT; + private static String dbPath = "output-net"; + private static String dbDirectory = "net-database"; + private static String indexDirectory = "net-index"; + private static int port = 10000; - private String dbPath; - private String dbDirectory; - private String indexDirectory; + protected TronApplicationContext context; - private int port; + private RpcApiService rpcApiService; + private Application appT; + private TronProxy tronProxy; private ExecutorService executorService = Executors.newFixedThreadPool(1); - public BaseNetTest(String dbPath, String dbDirectory, String indexDirectory, int port) { - this.dbPath = dbPath; - this.dbDirectory = dbDirectory; - this.indexDirectory = indexDirectory; - this.port = port; - } - @Before - public void init() { + public void init() throws Exception { executorService.execute(new Runnable() { @Override public void run() { @@ -79,62 +70,32 @@ public void run() { ); Args cfgArgs = Args.getInstance(); cfgArgs.setNodeListenPort(port); - cfgArgs.setNodeDiscoveryEnable(false); cfgArgs.getSeedNode().getIpList().clear(); - cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new TronApplicationContext(DefaultConfig.class); - - if (cfgArgs.isHelp()) { - logger.info("Here is the help message"); - return; - } appT = ApplicationFactory.create(context); rpcApiService = context.getBean(RpcApiService.class); appT.addService(rpcApiService); - if (cfgArgs.isWitness()) { - appT.addService(new WitnessService(appT, context)); - } appT.initServices(cfgArgs); appT.startServices(); - - node = context.getBean(NodeImpl.class); - peerClient = context.getBean(PeerClient.class); - channelManager = context.getBean(ChannelManager.class); - pool = context.getBean(SyncPool.class); - manager = context.getBean(Manager.class); - NodeDelegate nodeDelegate = new NodeDelegateImpl(manager); - node.setNodeDelegate(nodeDelegate); - appT.startup(); + tronProxy = context.getBean(TronProxy.class); rpcApiService.blockUntilShutdown(); } }); - int tryTimes = 1; - while (tryTimes <= 30 && (node == null || peerClient == null - || channelManager == null || pool == null)) { - try { - logger.info("node:{},peerClient:{},channelManager:{},pool:{}", node, peerClient, - channelManager, pool); - Thread.sleep(1000 * tryTimes); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - ++tryTimes; - } + int tryTimes = 0; + while (++tryTimes < 100 && tronProxy == null) { + Thread.sleep(3000); } } - protected Channel createClient(ByteToMessageDecoder decoder) - throws InterruptedException { + public static Channel connect(ByteToMessageDecoder decoder) throws InterruptedException { NioEventLoopGroup group = new NioEventLoopGroup(1); Bootstrap b = new Bootstrap(); b.group(group).channel(NioSocketChannel.class) .handler(new ChannelInitializer() { @Override protected void initChannel(Channel ch) throws Exception { - // limit the size of receiving buffer to 1024 ch.config().setRecvByteBufAllocator(new FixedRecvByteBufAllocator(256 * 1024)); ch.config().setOption(ChannelOption.SO_RCVBUF, 256 * 1024); ch.config().setOption(ChannelOption.SO_BACKLOG, 1024); @@ -144,8 +105,6 @@ protected void initChannel(Channel ch) throws Exception { ch.pipeline().addLast("protoPender", new ProtobufVarint32LengthFieldPrepender()); ch.pipeline().addLast("lengthDecode", new ProtobufVarint32FrameDecoder()); ch.pipeline().addLast("handshakeHandler", decoder); - - // be aware of channel closing ch.closeFuture(); } }).option(ChannelOption.SO_KEEPALIVE, true) @@ -156,16 +115,11 @@ protected void initChannel(Channel ch) throws Exception { @After public void destroy() { - executorService.shutdownNow(); - Args.clearParam(); - Collection peerConnections = ReflectUtils.invokeMethod(node, "getActivePeer"); + Collection peerConnections = ReflectUtils.invokeMethod(tronProxy, "getActivePeer"); for (PeerConnection peer : peerConnections) { peer.close(); } context.destroy(); - node.shutDown(); - appT.shutdownServices(); - appT.shutdown(); FileUtil.deleteDir(new File(dbPath)); } } diff --git a/src/test/java/org/tron/core/net/BaseNetTest.java b/src/test/java/org/tron/core/net/BaseNetTest.java new file mode 100644 index 00000000000..41bd1fad027 --- /dev/null +++ b/src/test/java/org/tron/core/net/BaseNetTest.java @@ -0,0 +1,16 @@ +package org.tron.core.net; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import org.tron.core.services.NodeInfoServiceTest; + +@Slf4j +public class BaseNetTest extends BaseNet { + + @Test + public void test() throws Exception { + new NodeInfoServiceTest(context).test(); + new UdpTest(context).test(); + new TcpTest(context).test(); + } +} diff --git a/src/test/java/org/tron/core/net/node/TcpNetTest.java b/src/test/java/org/tron/core/net/TcpTest.java similarity index 77% rename from src/test/java/org/tron/core/net/node/TcpNetTest.java rename to src/test/java/org/tron/core/net/TcpTest.java index b4dcbf7d9fb..50aa9ae17a4 100644 --- a/src/test/java/org/tron/core/net/node/TcpNetTest.java +++ b/src/test/java/org/tron/core/net/TcpTest.java @@ -1,4 +1,4 @@ -package org.tron.core.net.node; +package org.tron.core.net; import static org.tron.core.net.message.MessageTypes.P2P_DISCONNECT; import static org.tron.core.net.message.MessageTypes.P2P_HELLO; @@ -14,51 +14,52 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; - -import java.io.File; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; -import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; -import org.junit.Test; +import org.tron.common.application.TronApplicationContext; import org.tron.common.overlay.discover.node.Node; import org.tron.common.overlay.message.DisconnectMessage; import org.tron.common.overlay.message.HelloMessage; import org.tron.common.overlay.message.Message; import org.tron.common.overlay.message.P2pMessage; import org.tron.common.overlay.message.P2pMessageFactory; -import org.tron.common.utils.FileUtil; +import org.tron.common.overlay.server.ChannelManager; +import org.tron.common.overlay.server.SyncPool; import org.tron.common.utils.ReflectUtils; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BlockCapsule.BlockId; import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; import org.tron.core.net.message.BlockMessage; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.Block; @Slf4j -public class TcpNetTest extends BaseNetTest { +public class TcpTest { - private static final String dbPath = "output-nodeImplTest-tcpNet"; - private static final String dbDirectory = "db_tcp_test"; - private static final String indexDirectory = "index_tcp_test"; - public static final int sleepTime = 1000; - private boolean finish = false; - private final static int tryTimes = 10; - private final static int port = 17899; + private ChannelManager channelManager; + private Manager manager; + private SyncPool pool; + private TronProxy tronProxy; - Node node = new Node( - "enode://e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c@127.0.0.1:17889"); + private int tryTimes = 10; + private int sleepTime = 1000; + private boolean finish = false; + Node node = Node.instanceOf("127.0.0.1:" + Args.getInstance().getNodeListenPort()); - public TcpNetTest() { - super(dbPath, dbDirectory, indexDirectory, port); + public TcpTest(TronApplicationContext context) { + channelManager = context.getBean(ChannelManager.class); + manager = context.getBean(Manager.class); + pool = context.getBean(SyncPool.class); + tronProxy = context.getBean(TronProxy.class); } private enum TestType { @@ -81,19 +82,6 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List ou byte[] encoded = new byte[buffer.readableBytes()]; buffer.readBytes(encoded); P2pMessage msg = messageFactory.create(encoded); - - logger.info("Handshake Receive from {}, {}", ctx.channel().remoteAddress(), msg); - switch (msg.getType()) { - case P2P_HELLO: - logger.info("HandshakeHandler success"); - break; - case P2P_DISCONNECT: - logger.info("getReasonCode : {}", ((DisconnectMessage) msg).getReasonCode()); - break; - default: - return; - } - switch (testType) { case normal: Assert.assertEquals(msg.getType(), P2P_HELLO); @@ -122,67 +110,57 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List ou } } - //Unpooled.wrappedBuffer(ArrayUtils.add("nihao".getBytes(), 0, (byte) 1)) - - // @Test public void normalTest() throws InterruptedException { - Channel channel = createClient(new HandshakeHandler(TestType.normal)); + Channel channel = BaseNet.connect(new HandshakeHandler(TestType.normal)); HelloMessage message = new HelloMessage(node, System.currentTimeMillis(), manager.getGenesisBlockId(), manager.getSolidBlockId(), manager.getHeadBlockId()); sendMessage(channel, message); validResultCloseConnect(channel); } - // @Test public void errorGenesisBlockIdTest() throws InterruptedException { - Channel channel = createClient(new HandshakeHandler(TestType.errorGenesisBlock)); + Channel channel = BaseNet.connect(new HandshakeHandler(TestType.errorGenesisBlock)); BlockId genesisBlockId = new BlockId(); HelloMessage message = new HelloMessage(node, System.currentTimeMillis(), genesisBlockId, manager.getSolidBlockId(), manager.getHeadBlockId()); sendMessage(channel, message); - validResultCloseConnect(channel); } - // @Test public void errorVersionTest() throws InterruptedException { - Channel channel = createClient(new HandshakeHandler(TestType.errorVersion)); + Channel channel = BaseNet.connect(new HandshakeHandler(TestType.errorVersion)); Args.getInstance().setNodeP2pVersion(1); HelloMessage message = new HelloMessage(node, System.currentTimeMillis(), manager.getGenesisBlockId(), manager.getSolidBlockId(), manager.getHeadBlockId()); Args.getInstance().setNodeP2pVersion(2); sendMessage(channel, message); - validResultCloseConnect(channel); } - // @Test public void errorSolidBlockIdTest() throws InterruptedException { - Channel channel = createClient(new HandshakeHandler(TestType.errorSolid)); + Channel channel = BaseNet.connect(new HandshakeHandler(TestType.errorSolid)); HelloMessage message = new HelloMessage(node, System.currentTimeMillis(), manager.getGenesisBlockId(), new BlockId(), manager.getHeadBlockId()); sendMessage(channel, message); validResultCloseConnect(channel); } - // @Test public void repeatConnectTest() throws InterruptedException { - Channel channel = createClient(new HandshakeHandler(TestType.normal)); + Channel channel = BaseNet.connect(new HandshakeHandler(TestType.normal)); HelloMessage message = new HelloMessage(node, System.currentTimeMillis(), manager.getGenesisBlockId(), manager.getSolidBlockId(), manager.getHeadBlockId()); sendMessage(channel, message); validResultUnCloseConnect(); - Channel repeatChannel = createClient(new HandshakeHandler(TestType.repeatConnect)); + Channel repeatChannel = BaseNet.connect(new HandshakeHandler(TestType.repeatConnect)); sendMessage(repeatChannel, message); validResultCloseConnect(repeatChannel); clearConnect(channel); } - // @Test public void unHandshakeTest() throws InterruptedException { List beforeActivePeers = ReflectUtils.getFieldValue(pool, "activePeers"); int beforeSize = beforeActivePeers.size(); - Channel channel = createClient(new HandshakeHandler(TestType.normal)); + Channel channel = BaseNet.connect(new HandshakeHandler(TestType.normal)); BlockMessage message = new BlockMessage(new BlockCapsule(Block.getDefaultInstance())); sendMessage(channel, message); List afterActivePeers = ReflectUtils.getFieldValue(pool, "activePeers"); @@ -191,9 +169,8 @@ public void unHandshakeTest() throws InterruptedException { clearConnect(channel); } - // @Test public void errorMsgTest() throws InterruptedException { - Channel channel = createClient(new HandshakeHandler(TestType.normal)); + Channel channel = BaseNet.connect(new HandshakeHandler(TestType.normal)); HelloMessage message = new HelloMessage(node, System.currentTimeMillis(), manager.getGenesisBlockId(), manager.getSolidBlockId(), manager.getHeadBlockId()); sendMessage(channel, message); @@ -237,16 +214,17 @@ private void validResultCloseConnect(Channel channel) throws InterruptedExceptio finish = false; channel.close(); Thread.sleep(sleepTime); + Collection peerConnections = ReflectUtils.invokeMethod(tronProxy, "getActivePeer"); + for (PeerConnection peer : peerConnections) { + peer.close(); + } ReflectUtils.setFieldValue(channelManager, "recentlyDisconnected", CacheBuilder.newBuilder().maximumSize(1000) .expireAfterWrite(30, TimeUnit.SECONDS).recordStats().build()); - ReflectUtils.setFieldValue(pool, "activePeers", - Collections.synchronizedList(new ArrayList())); - ReflectUtils.setFieldValue(channelManager, "activePeers", new ConcurrentHashMap<>()); } private void validResultUnCloseConnect() throws InterruptedException { - int trys = 0; - while (!finish && ++trys < tryTimes) { + int n = 0; + while (!finish && ++n < tryTimes) { Thread.sleep(sleepTime); } Assert.assertEquals(finish, true); @@ -256,15 +234,15 @@ private void validResultUnCloseConnect() throws InterruptedException { private void clearConnect(Channel channel) throws InterruptedException { channel.close(); Thread.sleep(sleepTime); + Collection peerConnections = ReflectUtils.invokeMethod(tronProxy, "getActivePeer"); + for (PeerConnection peer : peerConnections) { + peer.close(); + } ReflectUtils.setFieldValue(channelManager, "recentlyDisconnected", CacheBuilder.newBuilder().maximumSize(1000) .expireAfterWrite(30, TimeUnit.SECONDS).recordStats().build()); - ReflectUtils.setFieldValue(pool, "activePeers", - Collections.synchronizedList(new ArrayList())); - ReflectUtils.setFieldValue(channelManager, "activePeers", new ConcurrentHashMap<>()); } - @Test - public void testAll() throws InterruptedException { + public void test() throws InterruptedException { logger.info("begin normal test "); normalTest(); logger.info("begin errorGenesisBlockId test "); diff --git a/src/test/java/org/tron/core/net/UdpTest.java b/src/test/java/org/tron/core/net/UdpTest.java index 35fdf75b080..bc7b78f81ea 100644 --- a/src/test/java/org/tron/core/net/UdpTest.java +++ b/src/test/java/org/tron/core/net/UdpTest.java @@ -30,34 +30,14 @@ @Slf4j public class UdpTest { - ApplicationContext context; - - NodeManager nodeManager; - - //@Before - public void before(){ - new Thread(() -> { - Args.setParam( - new String[]{ "--output-directory", "udp_test", "--storage-db-directory", "database", - "--storage-index-directory", "index"},"config.conf" - ); - Args cfgArgs = Args.getInstance(); - cfgArgs.getSeedNode().setIpList(Lists.newArrayList()); - cfgArgs.setNodeP2pVersion(100); - cfgArgs.setNodeListenPort(10001); - context = new TronApplicationContext(DefaultConfig.class); - }).start(); - } - - @Test - public void test() {} - - //@Test - public void udpTest() throws Exception { - - Thread.sleep(10000); + private NodeManager nodeManager; + private int port = Args.getInstance().getNodeListenPort(); + public UdpTest(TronApplicationContext context) { nodeManager = context.getBean(NodeManager.class); + } + + public void test() throws Exception { InetAddress server = InetAddress.getByName("127.0.0.1"); @@ -81,16 +61,16 @@ public void udpTest() throws Exception { DatagramSocket socket = new DatagramSocket(); DatagramPacket pingPacket = new DatagramPacket(pingMessage.getSendData(), - pingMessage.getSendData().length, server, 10001); + pingMessage.getSendData().length, server, port); DatagramPacket pongPacket = new DatagramPacket(pongMessage.getSendData(), - pongMessage.getSendData().length, server, 10001); + pongMessage.getSendData().length, server, port); DatagramPacket findNodePacket = new DatagramPacket(findNodeMessage.getSendData(), - findNodeMessage.getSendData().length, server, 10001); + findNodeMessage.getSendData().length, server, port); DatagramPacket neighborsPacket = new DatagramPacket(neighborsMessage.getSendData(), - neighborsMessage.getSendData().length, server, 10001); + neighborsMessage.getSendData().length, server, port); // send ping msg socket.send(pingPacket); @@ -102,7 +82,9 @@ public void udpTest() throws Exception { boolean findNodeFlag = false; boolean neighborsFlag = false; while (true) { + System.out.println("pingFlag:" + pingFlag + "pongFlag:" + pongFlag + "findNodeFlag:" + findNodeFlag + "neighborsFlag:" + neighborsFlag ); socket.receive(packet); + System.out.println("wwww"); byte[] bytes = Arrays.copyOfRange(data, 0, packet.getLength()); Message msg = Message.parse(bytes); Assert.assertTrue(Arrays.equals(msg.getFrom().getId(), nodeManager.getPublicHomeNode().getId())); @@ -131,10 +113,5 @@ public void udpTest() throws Exception { socket.close(); } - - //@After - public void after() { - FileUtil.deleteDir(new File("udp_test")); - } } diff --git a/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java b/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java new file mode 100644 index 00000000000..135f49749d6 --- /dev/null +++ b/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java @@ -0,0 +1,65 @@ +package org.tron.core.net.messagehandler; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import javafx.util.Pair; +import org.junit.Assert; +import org.junit.Test; +import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.config.Parameter.NodeConstant; +import org.tron.core.exception.P2pException; +import org.tron.core.net.message.ChainInventoryMessage; +import org.tron.core.net.peer.PeerConnection; + +public class ChainInventoryMsgHandlerTest { + + ChainInventoryMsgHandler handler = new ChainInventoryMsgHandler(); + ChainInventoryMessage msg = new ChainInventoryMessage(new ArrayList<>(), 0l); + List blockIds = new ArrayList<>(); + PeerConnection peer = new PeerConnection(); + + @Test + public void test() { + try { + handler.processMessage(peer, msg); + }catch (P2pException e) { + Assert.assertTrue(e.getMessage().equals("not send syncBlockChainMsg")); + } + + peer.setSyncChainRequested(new Pair<>(new LinkedList<>(), System.currentTimeMillis())); + + try { + handler.processMessage(peer, msg); + }catch (P2pException e) { + Assert.assertTrue(e.getMessage().equals("blockIds is empty")); + } + + + long size = NodeConstant.SYNC_FETCH_BATCH_NUM + 2; + for (int i = 0; i < size; i++) { + blockIds.add(new BlockId()); + } + msg = new ChainInventoryMessage(blockIds, 0l); + + try { + handler.processMessage(peer, msg); + }catch (P2pException e) { + Assert.assertTrue(e.getMessage().equals("big blockIds size: " + size)); + } + + blockIds.clear(); + size = NodeConstant.SYNC_FETCH_BATCH_NUM / 100; + for (int i = 0; i < size; i++) { + blockIds.add(new BlockId()); + } + msg = new ChainInventoryMessage(blockIds, 100l); + + try { + handler.processMessage(peer, msg); + }catch (P2pException e) { + Assert.assertTrue(e.getMessage().equals("remain: 100, blockIds size: " + size)); + } + } + +} diff --git a/src/test/java/org/tron/core/net/node/BroadTest.java b/src/test/java/org/tron/core/net/node/BroadTest.java deleted file mode 100644 index 71d7bf82524..00000000000 --- a/src/test/java/org/tron/core/net/node/BroadTest.java +++ /dev/null @@ -1,305 +0,0 @@ -package org.tron.core.net.node; - -import com.google.common.cache.Cache; -import java.io.File; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.MapUtils; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.TronApplicationContext; -import org.tron.common.overlay.discover.node.Node; -import org.tron.common.overlay.message.Message; -import org.tron.common.overlay.server.Channel; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.common.overlay.server.MessageQueue; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.ReflectUtils; -import org.tron.common.utils.Sha256Hash; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.config.DefaultConfig; -import org.tron.core.config.args.Args; -import org.tron.core.db.ByteArrayWrapper; -import org.tron.core.db.Manager; -import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.message.MessageTypes; -import org.tron.core.net.message.TransactionMessage; -import org.tron.core.net.node.NodeImpl.PriorItem; -import org.tron.core.net.node.override.HandshakeHandlerTest; -import org.tron.core.net.node.override.PeerClientTest; -import org.tron.core.net.node.override.TronChannelInitializerTest; -import org.tron.core.net.peer.Item; -import org.tron.core.net.peer.PeerConnection; -import org.tron.core.services.RpcApiService; -import org.tron.core.services.WitnessService; -import org.tron.protos.Protocol.Block; -import org.tron.protos.Protocol.Inventory.InventoryType; -import org.tron.protos.Protocol.Transaction; - -@Slf4j -public class BroadTest { - - private TronApplicationContext context; - private NodeImpl nodeImpl; - private RpcApiService rpcApiService; - private PeerClientTest peerClient; - private ChannelManager channelManager; - private SyncPool pool; - private Application appT; - private static final String dbPath = "output-nodeImplTest-broad"; - private static final String dbDirectory = "db_Broad_test"; - private static final String indexDirectory = "index_Broad_test"; - - private HandshakeHandlerTest handshakeHandlerTest; - private Node node; - - private class Condition { - - private Sha256Hash blockId; - private Sha256Hash transactionId; - - public Condition(Sha256Hash blockId, Sha256Hash transactionId) { - this.blockId = blockId; - this.transactionId = transactionId; - } - - public Sha256Hash getBlockId() { - return blockId; - } - - public Sha256Hash getTransactionId() { - return transactionId; - } - - } - - private Sha256Hash testBlockBroad() { - Block block = Block.getDefaultInstance(); - BlockMessage blockMessage = new BlockMessage(new BlockCapsule(block)); - nodeImpl.broadcast(blockMessage); - ConcurrentHashMap advObjToSpread = ReflectUtils - .getFieldValue(nodeImpl, "advObjToSpread"); - Assert.assertEquals(advObjToSpread.get(blockMessage.getMessageId()), InventoryType.BLOCK); - return blockMessage.getMessageId(); - } - - private Sha256Hash testTransactionBroad() { - Transaction transaction = Transaction.getDefaultInstance(); - TransactionMessage transactionMessage = new TransactionMessage(transaction); - nodeImpl.broadcast(transactionMessage); - ConcurrentHashMap advObjToSpread = ReflectUtils - .getFieldValue(nodeImpl, "advObjToSpread"); - Assert.assertEquals(advObjToSpread.get(transactionMessage.getMessageId()), InventoryType.TRX); - return transactionMessage.getMessageId(); - } - - private Condition testConsumerAdvObjToSpread() { - Sha256Hash blockId = testBlockBroad(); - Sha256Hash transactionId = testTransactionBroad(); - //remove the tx and block - removeTheTxAndBlock(blockId, transactionId); - - ReflectUtils.invokeMethod(nodeImpl, "consumerAdvObjToSpread"); - Collection activePeers = ReflectUtils.invokeMethod(nodeImpl, "getActivePeer"); - - boolean result = true; - for (PeerConnection peerConnection : activePeers) { - if (!peerConnection.getAdvObjWeSpread().containsKey(blockId)) { - result &= false; - } - if (!peerConnection.getAdvObjWeSpread().containsKey(transactionId)) { - result &= false; - } - } - for (PeerConnection peerConnection : activePeers) { - peerConnection.getAdvObjWeSpread().clear(); - } - Assert.assertTrue(result); - return new Condition(blockId, transactionId); - } - - private void removeTheTxAndBlock(Sha256Hash blockId, Sha256Hash transactionId) { - Cache trxCache = ReflectUtils - .getFieldValue(nodeImpl, "TrxCache"); - Cache blockCache = ReflectUtils.getFieldValue(nodeImpl, "BlockCache"); - trxCache.invalidate(transactionId); - blockCache.invalidate(blockId); - } - - @Test - public void testConsumerAdvObjToFetch() throws InterruptedException { - Condition condition = testConsumerAdvObjToSpread(); - Thread.sleep(1000); - // - Map advObjToFetch = ReflectUtils - .getFieldValue(nodeImpl, "advObjToFetch"); - logger.info("advObjToFetch:{}", advObjToFetch); - logger.info("advObjToFetchSize:{}", advObjToFetch.size()); - //Assert.assertEquals(advObjToFetch.get(condition.getBlockId()), InventoryType.BLOCK); - //Assert.assertEquals(advObjToFetch.get(condition.getTransactionId()), InventoryType.TRX); - //To avoid writing the database, manually stop the sending of messages. - Collection activePeers = ReflectUtils.invokeMethod(nodeImpl, "getActivePeer"); - Thread.sleep(1000); - if(activePeers.size() < 1){ - return; - } - for (PeerConnection peerConnection : activePeers) { - MessageQueue messageQueue = ReflectUtils.getFieldValue(peerConnection, "msgQueue"); - ReflectUtils.setFieldValue(messageQueue, "sendMsgFlag", false); - } - // - ReflectUtils.invokeMethod(nodeImpl, "consumerAdvObjToFetch"); - Thread.sleep(1000); - boolean result = true; - int count = 0; - for (PeerConnection peerConnection : activePeers) { - if (peerConnection.getAdvObjWeRequested() - .containsKey(new Item(condition.getTransactionId(), InventoryType.TRX))) { - ++count; - } - if (peerConnection.getAdvObjWeRequested() - .containsKey(new Item(condition.getBlockId(), InventoryType.BLOCK))) { - ++count; - } - MessageQueue messageQueue = ReflectUtils.getFieldValue(peerConnection, "msgQueue"); - BlockingQueue msgQueue = ReflectUtils.getFieldValue(messageQueue, "msgQueue"); - for (Message message : msgQueue) { - if (message.getType() == MessageTypes.BLOCK) { - Assert.assertEquals(message.getMessageId(), condition.getBlockId()); - } - if (message.getType() == MessageTypes.TRX) { - Assert.assertEquals(message.getMessageId(), condition.getTransactionId()); - } - } - } - Assert.assertTrue(count >= 1); - } - - private static boolean go = false; - - @Before - public void init() { - node = new Node( - "enode://e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c@127.0.0.1:17889"); - - new Thread(new Runnable() { - @Override - public void run() { - logger.info("Full node running."); - Args.setParam( - new String[]{ - "--output-directory", dbPath, - "--storage-db-directory", dbDirectory, - "--storage-index-directory", indexDirectory - }, - "config.conf" - ); - Args cfgArgs = Args.getInstance(); - cfgArgs.setNodeListenPort(17889); - cfgArgs.setNodeDiscoveryEnable(false); - cfgArgs.getSeedNode().getIpList().clear(); - cfgArgs.setNeedSyncCheck(false); - cfgArgs.setNodeExternalIp("127.0.0.1"); - - context = new TronApplicationContext(DefaultConfig.class); - - if (cfgArgs.isHelp()) { - logger.info("Here is the help message."); - return; - } - appT = ApplicationFactory.create(context); - rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); - if (cfgArgs.isWitness()) { - appT.addService(new WitnessService(appT, context)); - } -// appT.initServices(cfgArgs); -// appT.startServices(); -// appT.startup(); - nodeImpl = context.getBean(NodeImpl.class); - peerClient = context.getBean(PeerClientTest.class); - channelManager = context.getBean(ChannelManager.class); - pool = context.getBean(SyncPool.class); - Manager dbManager = context.getBean(Manager.class); - handshakeHandlerTest = context.getBean(HandshakeHandlerTest.class); - handshakeHandlerTest.setNode(node); - NodeDelegate nodeDelegate = new NodeDelegateImpl(dbManager); - nodeImpl.setNodeDelegate(nodeDelegate); - pool.init(nodeImpl); - prepare(); - rpcApiService.blockUntilShutdown(); - } - }).start(); - int tryTimes = 1; - while (tryTimes <= 30 && (nodeImpl == null || peerClient == null - || channelManager == null || pool == null || !go)) { - try { - logger.info("nodeImpl:{},peerClient:{},channelManager:{},pool:{},{}", nodeImpl, peerClient, - channelManager, pool, go); - Thread.sleep(1000 * tryTimes); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - ++tryTimes; - } - } - } - - private void prepare() { - try { - ExecutorService advertiseLoopThread = ReflectUtils.getFieldValue(nodeImpl, "broadPool"); - advertiseLoopThread.shutdownNow(); - - peerClient.prepare(node.getHexId()); - - ReflectUtils.setFieldValue(nodeImpl, "isAdvertiseActive", false); - ReflectUtils.setFieldValue(nodeImpl, "isFetchActive", false); - TronChannelInitializerTest tronChannelInitializer = ReflectUtils - .getFieldValue(peerClient, "tronChannelInitializer"); - tronChannelInitializer.prepare(); - Channel channel = ReflectUtils.getFieldValue(tronChannelInitializer, "channel"); - ReflectUtils.setFieldValue(channel, "handshakeHandler", handshakeHandlerTest); - new Thread(new Runnable() { - @Override - public void run() { - peerClient.connect(node.getHost(), node.getPort(), node.getHexId()); - } - }).start(); - Thread.sleep(2000); - Map activePeers = ReflectUtils - .getFieldValue(channelManager, "activePeers"); - int tryTimes = 0; - while (MapUtils.isEmpty(activePeers) && ++tryTimes < 10) { - Thread.sleep(1000); - } - go = true; - } catch (Exception e) { - e.printStackTrace(); - } - } - - @After - public void destroy() { - Args.clearParam(); - Collection peerConnections = ReflectUtils - .invokeMethod(nodeImpl, "getActivePeer"); - for (PeerConnection peer : peerConnections) { - peer.close(); - } - context.destroy(); - handshakeHandlerTest.close(); - appT.shutdownServices(); - appT.shutdown(); - FileUtil.deleteDir(new File(dbPath)); - } - -} diff --git a/src/test/java/org/tron/core/net/node/FinishProcessSyncBlockTest.java b/src/test/java/org/tron/core/net/node/FinishProcessSyncBlockTest.java deleted file mode 100644 index 76b4e934d13..00000000000 --- a/src/test/java/org/tron/core/net/node/FinishProcessSyncBlockTest.java +++ /dev/null @@ -1,222 +0,0 @@ -package org.tron.core.net.node; - -import com.google.protobuf.ByteString; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.MapUtils; -import org.junit.*; -import org.tron.common.application.TronApplicationContext; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.crypto.ECKey; -import org.tron.common.overlay.client.PeerClient; -import org.tron.common.overlay.discover.node.Node; -import org.tron.common.overlay.server.Channel; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.ReflectUtils; -import org.tron.core.Constant; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.config.DefaultConfig; -import org.tron.core.config.args.Args; -import org.tron.core.db.ByteArrayWrapper; -import org.tron.core.db.Manager; -import org.tron.core.net.node.override.HandshakeHandlerTest; -import org.tron.core.net.node.override.PeerClientTest; -import org.tron.core.net.node.override.TronChannelInitializerTest; -import org.tron.core.net.peer.PeerConnection; -import org.tron.core.services.RpcApiService; -import org.tron.core.services.WitnessService; -import org.tron.protos.Protocol.Block; -import org.tron.protos.Protocol.BlockHeader; - -import java.io.File; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ExecutorService; - -@Slf4j -public class FinishProcessSyncBlockTest { - - private static TronApplicationContext context; - private static NodeImpl node; - private RpcApiService rpcApiService; - private static PeerClientTest peerClient; - private ChannelManager channelManager; - private SyncPool pool; - private static Application appT; - private Manager dbManager; - private Node nodeEntity; - private static HandshakeHandlerTest handshakeHandlerTest; - - private static final String dbPath = "output-FinishProcessSyncBlockTest"; - private static final String dbDirectory = "db_FinishProcessSyncBlock_test"; - private static final String indexDirectory = "index_FinishProcessSyncBlock_test"; - - @Test - public void testFinishProcessSyncBlock() throws Exception { - Collection activePeers = ReflectUtils.invokeMethod(node, "getActivePeer"); - Thread.sleep(5000); - if (activePeers.size() < 1) { - return; - } - PeerConnection peer = (PeerConnection) activePeers.toArray()[1]; - BlockCapsule headBlockCapsule = dbManager.getHead(); - BlockCapsule blockCapsule = generateOneBlockCapsule(headBlockCapsule); - Class[] cls = {BlockCapsule.class}; - Object[] params = {blockCapsule}; - peer.getBlockInProc().add(blockCapsule.getBlockId()); - ReflectUtils.invokeMethod(node, "finishProcessSyncBlock", cls, params); - Assert.assertEquals(peer.getBlockInProc().isEmpty(), true); - } - - // generate ong block by parent block - private BlockCapsule generateOneBlockCapsule(BlockCapsule parentCapsule) { - ByteString witnessAddress = ByteString.copyFrom( - ECKey.fromPrivate( - ByteArray.fromHexString( - Args.getInstance().getLocalWitnesses().getPrivateKey())) - .getAddress()); - BlockHeader.raw raw = BlockHeader.raw.newBuilder() - .setTimestamp(System.currentTimeMillis()) - .setParentHash(parentCapsule.getBlockId().getByteString()) - .setNumber(parentCapsule.getNum() + 1) - .setWitnessAddress(witnessAddress) - .setWitnessId(1).build(); - BlockHeader blockHeader = BlockHeader.newBuilder() - .setRawData(raw) - .build(); - - Block block = Block.newBuilder().setBlockHeader(blockHeader).build(); - - BlockCapsule blockCapsule = new BlockCapsule(block); - blockCapsule.setMerkleRoot(); - blockCapsule.sign( - ByteArray.fromHexString(Args.getInstance().getLocalWitnesses().getPrivateKey())); - blockCapsule.setMerkleRoot(); - blockCapsule.sign( - ByteArray.fromHexString(Args.getInstance().getLocalWitnesses().getPrivateKey())); - - return blockCapsule; - } - - private static boolean go = false; - - @Before - public void init() { - nodeEntity = new Node( - "enode://e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c@127.0.0.1:17895"); - - new Thread(new Runnable() { - @Override - public void run() { - logger.info("Full node running."); - Args.setParam( - new String[]{ - "--output-directory", dbPath, - "--storage-db-directory", dbDirectory, - "--storage-index-directory", indexDirectory - }, - Constant.TEST_CONF - ); - Args cfgArgs = Args.getInstance(); - cfgArgs.setNodeListenPort(17895); - cfgArgs.setNodeDiscoveryEnable(false); - cfgArgs.getSeedNode().getIpList().clear(); - cfgArgs.setNeedSyncCheck(false); - cfgArgs.setNodeExternalIp("127.0.0.1"); - - context = new TronApplicationContext(DefaultConfig.class); - - if (cfgArgs.isHelp()) { - logger.info("Here is the help message."); - return; - } - appT = ApplicationFactory.create(context); - rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); - if (cfgArgs.isWitness()) { - appT.addService(new WitnessService(appT, context)); - } -// appT.initServices(cfgArgs); -// appT.startServices(); -// appT.startup(); - node = context.getBean(NodeImpl.class); - peerClient = context.getBean(PeerClientTest.class); - channelManager = context.getBean(ChannelManager.class); - pool = context.getBean(SyncPool.class); - dbManager = context.getBean(Manager.class); - handshakeHandlerTest = context.getBean(HandshakeHandlerTest.class); - handshakeHandlerTest.setNode(nodeEntity); - NodeDelegate nodeDelegate = new NodeDelegateImpl(dbManager); - node.setNodeDelegate(nodeDelegate); - pool.init(node); - prepare(); - rpcApiService.blockUntilShutdown(); - } - }).start(); - int tryTimes = 0; - while (tryTimes < 10 && (node == null || peerClient == null - || channelManager == null || pool == null || !go)) { - try { - logger.info("node:{},peerClient:{},channelManager:{},pool:{},{}", node, peerClient, - channelManager, pool, go); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - ++tryTimes; - } - } - } - - private void prepare() { - try { - ExecutorService advertiseLoopThread = ReflectUtils.getFieldValue(node, "broadPool"); - advertiseLoopThread.shutdownNow(); - - peerClient.prepare(nodeEntity.getHexId()); - - ReflectUtils.setFieldValue(node, "isAdvertiseActive", false); - ReflectUtils.setFieldValue(node, "isFetchActive", false); - - TronChannelInitializerTest tronChannelInitializer = ReflectUtils - .getFieldValue(peerClient, "tronChannelInitializer"); - tronChannelInitializer.prepare(); - Channel channel = ReflectUtils.getFieldValue(tronChannelInitializer, "channel"); - ReflectUtils.setFieldValue(channel, "handshakeHandler", handshakeHandlerTest); - - new Thread(new Runnable() { - @Override - public void run() { - peerClient.connect(nodeEntity.getHost(), nodeEntity.getPort(), nodeEntity.getHexId()); - } - }).start(); - Thread.sleep(1000); - Map activePeers = ReflectUtils - .getFieldValue(channelManager, "activePeers"); - int tryTimes = 0; - while (MapUtils.isEmpty(activePeers) && ++tryTimes < 10) { - Thread.sleep(1000); - } - go = true; - } catch (Exception e) { - e.printStackTrace(); - } - } - - @AfterClass - public static void destroy() { - Args.clearParam(); - Collection peerConnections = ReflectUtils.invokeMethod(node, "getActivePeer"); - for (PeerConnection peer : peerConnections) { - peer.close(); - } - handshakeHandlerTest.close(); - appT.shutdownServices(); - appT.shutdown(); - context.destroy(); - FileUtil.deleteDir(new File(dbPath)); - } -} diff --git a/src/test/java/org/tron/core/net/node/GetBlockChainSummaryTest.java b/src/test/java/org/tron/core/net/node/GetBlockChainSummaryTest.java deleted file mode 100644 index 74e53bed873..00000000000 --- a/src/test/java/org/tron/core/net/node/GetBlockChainSummaryTest.java +++ /dev/null @@ -1,350 +0,0 @@ -package org.tron.core.net.node; - -import com.google.common.collect.Maps; -import com.google.protobuf.ByteString; -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Deque; -import java.util.Map; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.ExecutorService; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.MapUtils; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.TronApplicationContext; -import org.tron.common.crypto.ECKey; -import org.tron.common.overlay.discover.node.Node; -import org.tron.common.overlay.server.Channel; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.ReflectUtils; -import org.tron.common.utils.Sha256Hash; -import org.tron.common.utils.Utils; -import org.tron.core.capsule.AccountCapsule; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.capsule.WitnessCapsule; -import org.tron.core.config.DefaultConfig; -import org.tron.core.config.args.Args; -import org.tron.core.db.BlockStore; -import org.tron.core.db.ByteArrayWrapper; -import org.tron.core.db.Manager; -import org.tron.core.net.node.override.HandshakeHandlerTest; -import org.tron.core.net.node.override.PeerClientTest; -import org.tron.core.net.node.override.TronChannelInitializerTest; -import org.tron.core.net.peer.PeerConnection; -import org.tron.core.services.RpcApiService; -import org.tron.core.services.WitnessService; -import org.tron.core.witness.WitnessController; -import org.tron.protos.Protocol; - -@Slf4j -public class GetBlockChainSummaryTest { - - private static TronApplicationContext context; - private static NodeImpl node; - private RpcApiService rpcApiService; - private static PeerClientTest peerClient; - private ChannelManager channelManager; - private SyncPool pool; - private static Application appT; - private Manager dbManager; - private Node nodeEntity; - private static HandshakeHandlerTest handshakeHandlerTest; - - private static final String dbPath = "output-GetBlockChainSummary"; - private static final String dbDirectory = "db_GetBlockChainSummary_test"; - private static final String indexDirectory = "index_GetBlockChainSummary_test"; - - @Test - public void testGetBlockChainSummary() { - NodeDelegate del = ReflectUtils.getFieldValue(node, "del"); - Collection activePeers = ReflectUtils.invokeMethod(node, "getActivePeer"); - BlockStore blkstore = dbManager.getBlockStore(); - - Object[] peers = activePeers.toArray(); - if (peers == null || peers.length <= 0) { - return; - } - PeerConnection peer_he = (PeerConnection) peers[0]; - Deque toFetch = new ConcurrentLinkedDeque<>(); - - ArrayList scenes = new ArrayList<>(); - scenes.add("genesis"); - scenes.add("genesis_fetch"); - scenes.add("nongenesis_fetch"); - - long number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - Map addressToProvateKeys = addTestWitnessAndAccount(); - BlockCapsule capsule = createTestBlockCapsule(1533529947843L, number, - dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), - addressToProvateKeys); - try { - dbManager.pushBlock(capsule); - } catch (Exception e) { - e.printStackTrace(); - } - for (int i = 1; i < 5; i++) { - number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - capsule = createTestBlockCapsule(1533529947843L + 3000L * i, number, - dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), - addressToProvateKeys); - try { - dbManager.pushBlock(capsule); - } catch (Exception e) { - e.printStackTrace(); - } - } - - BlockCapsule.BlockId commonBlockId = null; - - //the common block is genesisblock,syncBlockToFetch is empty。 - try { - commonBlockId = del.getGenesisBlock().getBlockId(); - peer_he.getSyncBlockToFetch().clear(); - ReflectUtils.setFieldValue(peer_he, "headBlockWeBothHave", commonBlockId); - ReflectUtils.setFieldValue(peer_he, "headBlockTimeWeBothHave", System.currentTimeMillis()); - Deque retSummary = del - .getBlockChainSummary(peer_he.getHeadBlockWeBothHave(), peer_he.getSyncBlockToFetch()); - Assert.assertTrue(retSummary.size() == 3); - } catch (Exception e) { - System.out.println("exception!"); - } - - //the common block is genesisblock,syncBlockToFetch is not empty。 - peer_he.getSyncBlockToFetch().addAll(toFetch); - try { - toFetch.clear(); - peer_he.getSyncBlockToFetch().clear(); - for (int i = 0; i < 4; i++) { - number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - capsule = createTestBlockCapsule(1533529947843L + 3000L * i, number, - dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), - addressToProvateKeys); - toFetch.add(capsule.getBlockId()); - } - - commonBlockId = del.getGenesisBlock().getBlockId(); - peer_he.getSyncBlockToFetch().addAll(toFetch); - ReflectUtils.setFieldValue(peer_he, "headBlockWeBothHave", commonBlockId); - ReflectUtils.setFieldValue(peer_he, "headBlockTimeWeBothHave", System.currentTimeMillis()); - Deque retSummary = del - .getBlockChainSummary(peer_he.getHeadBlockWeBothHave(), peer_he.getSyncBlockToFetch()); - Assert.assertTrue(retSummary.size() == 4); - } catch (Exception e) { - System.out.println("exception!"); - } - - //the common block is a normal block(not genesisblock),syncBlockToFetc is not empty. - try { - toFetch.clear(); - peer_he.getSyncBlockToFetch().clear(); - number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - BlockCapsule capsule1 = createTestBlockCapsule(1533529947843L + 3000L * 6, number, - dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), - addressToProvateKeys); - dbManager.pushBlock(capsule1); - - number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - BlockCapsule capsule2 = createTestBlockCapsule(1533529947843L + 3000L * 7, number, - dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), - addressToProvateKeys); - dbManager.pushBlock(capsule2); - - for (int i = 0; i < 2; i++) { - number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - capsule = createTestBlockCapsule(1533529947843L + 3000L * 8 + 3000L * i, number, - dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), - addressToProvateKeys); - toFetch.add(capsule.getBlockId()); - } - commonBlockId = capsule2.getBlockId(); - peer_he.getSyncBlockToFetch().addAll(toFetch); - toFetch.forEach(block -> blkstore.delete(block.getBytes())); - ReflectUtils.setFieldValue(peer_he, "headBlockWeBothHave", commonBlockId); - ReflectUtils.setFieldValue(peer_he, "headBlockTimeWeBothHave", System.currentTimeMillis()); - Deque retSummary = del - .getBlockChainSummary(peer_he.getHeadBlockWeBothHave(), peer_he.getSyncBlockToFetch()); - Assert.assertTrue(retSummary.size() == 4); - } catch (Exception e) { - System.out.println("exception!"); - } - logger.info("finish1"); - } - - - private static boolean go = false; - - private Map addTestWitnessAndAccount() { - dbManager.getWitnesses().clear(); - return IntStream.range(0, 2) - .mapToObj( - i -> { - ECKey ecKey = new ECKey(Utils.getRandom()); - String privateKey = ByteArray.toHexString(ecKey.getPrivKey().toByteArray()); - ByteString address = ByteString.copyFrom(ecKey.getAddress()); - - WitnessCapsule witnessCapsule = new WitnessCapsule(address); - dbManager.getWitnessStore().put(address.toByteArray(), witnessCapsule); - dbManager.getWitnessController().addWitness(address); - - AccountCapsule accountCapsule = - new AccountCapsule(Protocol.Account.newBuilder().setAddress(address).build()); - dbManager.getAccountStore().put(address.toByteArray(), accountCapsule); - - return Maps.immutableEntry(address, privateKey); - }) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - private BlockCapsule createTestBlockCapsule( - long number, ByteString hash, Map addressToProvateKeys) { - long time = System.currentTimeMillis(); - return createTestBlockCapsule(time, number, hash, addressToProvateKeys); - } - - private BlockCapsule createTestBlockCapsule(long time, - long number, ByteString hash, Map addressToProvateKeys) { - WitnessController witnessController = dbManager.getWitnessController(); - ByteString witnessAddress = - witnessController.getScheduledWitness(witnessController.getSlotAtTime(time)); - BlockCapsule blockCapsule = new BlockCapsule(number, Sha256Hash.wrap(hash), time, - witnessAddress); - blockCapsule.generatedByMyself = true; - blockCapsule.setMerkleRoot(); - blockCapsule.sign(ByteArray.fromHexString(addressToProvateKeys.get(witnessAddress))); - return blockCapsule; - } - - @Before - public void init() { - nodeEntity = new Node( - "enode://e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c@127.0.0.1:17896"); - - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - logger.info("Full node running."); - Args.setParam( - new String[]{ - "--output-directory", dbPath, - "--storage-db-directory", dbDirectory, - "--storage-index-directory", indexDirectory - }, - "config.conf" - ); - Args cfgArgs = Args.getInstance(); - cfgArgs.setNodeListenPort(17896); - cfgArgs.setNodeDiscoveryEnable(false); - cfgArgs.getSeedNode().getIpList().clear(); - cfgArgs.setNeedSyncCheck(false); - cfgArgs.setNodeExternalIp("127.0.0.1"); - - context = new TronApplicationContext(DefaultConfig.class); - - if (cfgArgs.isHelp()) { - logger.info("Here is the help message."); - return; - } - appT = ApplicationFactory.create(context); - rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); - if (cfgArgs.isWitness()) { - appT.addService(new WitnessService(appT, context)); - } -// appT.initServices(cfgArgs); -// appT.startServices(); -// appT.startup(); - node = context.getBean(NodeImpl.class); - peerClient = context.getBean(PeerClientTest.class); - channelManager = context.getBean(ChannelManager.class); - pool = context.getBean(SyncPool.class); - dbManager = context.getBean(Manager.class); - handshakeHandlerTest = context.getBean(HandshakeHandlerTest.class); - handshakeHandlerTest.setNode(nodeEntity); - NodeDelegate nodeDelegate = new NodeDelegateImpl(dbManager); - node.setNodeDelegate(nodeDelegate); - pool.init(node); - prepare(); - rpcApiService.blockUntilShutdown(); - } - }); - thread.start(); - try { - thread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - int tryTimes = 0; - while (tryTimes < 10 && (node == null || peerClient == null - || channelManager == null || pool == null || !go)) { - try { - logger.info("node:{},peerClient:{},channelManager:{},pool:{},{}", node, peerClient, - channelManager, pool, go); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - ++tryTimes; - } - } - } - - private void prepare() { - try { - ExecutorService advertiseLoopThread = ReflectUtils.getFieldValue(node, "broadPool"); - advertiseLoopThread.shutdownNow(); - - peerClient.prepare(nodeEntity.getHexId()); - - ReflectUtils.setFieldValue(node, "isAdvertiseActive", false); - ReflectUtils.setFieldValue(node, "isFetchActive", false); - - TronChannelInitializerTest tronChannelInitializer = ReflectUtils - .getFieldValue(peerClient, "tronChannelInitializer"); - tronChannelInitializer.prepare(); - Channel channel = ReflectUtils.getFieldValue(tronChannelInitializer, "channel"); - ReflectUtils.setFieldValue(channel, "handshakeHandler", handshakeHandlerTest); - - new Thread(new Runnable() { - @Override - public void run() { - peerClient.connect(nodeEntity.getHost(), nodeEntity.getPort(), nodeEntity.getHexId()); - } - }).start(); - Thread.sleep(1000); - Map activePeers = ReflectUtils - .getFieldValue(channelManager, "activePeers"); - int tryTimes = 0; - while (MapUtils.isEmpty(activePeers) && ++tryTimes < 10) { - Thread.sleep(1000); - } - go = true; - } catch (Exception e) { - e.printStackTrace(); - } - } - - @AfterClass - public static void destroy() { - Args.clearParam(); - Collection peerConnections = ReflectUtils.invokeMethod(node, "getActivePeer"); - for (PeerConnection peer : peerConnections) { - peer.close(); - } - handshakeHandlerTest.close(); - appT.shutdownServices(); - appT.shutdown(); - context.destroy(); - FileUtil.deleteDir(new File(dbPath)); - } -} diff --git a/src/test/java/org/tron/core/net/node/GetLostBlockIdsTest.java b/src/test/java/org/tron/core/net/node/GetLostBlockIdsTest.java deleted file mode 100644 index 94dd6bdb186..00000000000 --- a/src/test/java/org/tron/core/net/node/GetLostBlockIdsTest.java +++ /dev/null @@ -1,332 +0,0 @@ -package org.tron.core.net.node; - -import com.google.common.collect.Maps; -import com.google.protobuf.ByteString; -import io.grpc.Channel; -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.MapUtils; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.TronApplicationContext; -import org.tron.common.crypto.ECKey; -import org.tron.common.overlay.discover.node.Node; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.ReflectUtils; -import org.tron.common.utils.Sha256Hash; -import org.tron.common.utils.Utils; -import org.tron.core.capsule.AccountCapsule; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.capsule.BlockCapsule.BlockId; -import org.tron.core.capsule.WitnessCapsule; -import org.tron.core.config.DefaultConfig; -import org.tron.core.config.args.Args; -import org.tron.core.db.ByteArrayWrapper; -import org.tron.core.db.Manager; -import org.tron.core.exception.StoreException; -import org.tron.core.net.node.override.HandshakeHandlerTest; -import org.tron.core.net.node.override.PeerClientTest; -import org.tron.core.net.node.override.TronChannelInitializerTest; -import org.tron.core.net.peer.PeerConnection; -import org.tron.core.services.RpcApiService; -import org.tron.core.services.WitnessService; -import org.tron.core.witness.WitnessController; -import org.tron.protos.Protocol; - -@Slf4j -public class GetLostBlockIdsTest { - - private static TronApplicationContext context; - private static NodeImpl node; - private RpcApiService rpcApiService; - private static PeerClientTest peerClient; - private ChannelManager channelManager; - private SyncPool pool; - private static Application appT; - private Manager dbManager; - private Node nodeEntity; - private static HandshakeHandlerTest handshakeHandlerTest; - - private static final String dbPath = "output-GetLostBlockIdsTest"; - private static final String dbDirectory = "db_GetLostBlockIds_test"; - private static final String indexDirectory = "index_GetLostBlockIds_test"; - - @Test - public void testGetLostBlockIds() { - NodeDelegate del = ReflectUtils.getFieldValue(node, "del"); - List blockChainSummary; - LinkedList blockIds = null; - - long number; - Map addressToProvateKeys = addTestWitnessAndAccount(); - BlockCapsule capsule; - for (int i = 0; i < 5; i++) { - number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - capsule = createTestBlockCapsule(1533529947843L + 3000L * i, number, - dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), - addressToProvateKeys); - try { - dbManager.pushBlock(capsule); - } catch (Exception e) { - e.printStackTrace(); - } - } - - //blockChainSummary is empty - try { - blockChainSummary = new ArrayList(); - blockIds = del.getLostBlockIds(blockChainSummary); - } catch (StoreException e) { - e.printStackTrace(); - } - Assert.assertTrue(blockIds.size() == 6); - - //blockChainSummary only have a genesis block - try { - blockChainSummary = new ArrayList(); - blockChainSummary.add(dbManager.getGenesisBlockId()); - blockIds = del.getLostBlockIds(blockChainSummary); - } catch (StoreException e) { - e.printStackTrace(); - } - Assert.assertTrue(blockIds.size() == 6); - - //blockChainSummary have genesis block、2nd block、3rd block - BlockId except_first_block = null; - try { - blockChainSummary = new ArrayList(); - blockChainSummary.add(dbManager.getGenesisBlockId()); - blockChainSummary.add(dbManager.getBlockIdByNum(2)); - blockChainSummary.add(dbManager.getBlockIdByNum(3)); - except_first_block = dbManager.getBlockIdByNum(3); - blockIds = del.getLostBlockIds(blockChainSummary); - } catch (StoreException e) { - e.printStackTrace(); - } - Assert.assertTrue(blockIds.size() == 3 && Arrays - .equals(blockIds.peekFirst().getBytes(), except_first_block.getBytes())); - - //blockChainSummary have 2nd block、4th block,and they are on fork chain - try { - BlockCapsule capsule2 = new BlockCapsule(2, - Sha256Hash.wrap(ByteString.copyFrom( - ByteArray.fromHexString( - "0000000000000002498b464ac0292229938a342238077182498b464ac0292222"))), - 1234, ByteString.copyFrom("1234567".getBytes())); - BlockCapsule capsule4 = new BlockCapsule(4, - Sha256Hash.wrap(ByteString.copyFrom( - ByteArray.fromHexString( - "00000000000000042498b464ac0292229938a342238077182498b464ac029222"))), - 1234, ByteString.copyFrom("abcdefg".getBytes())); - blockChainSummary = new ArrayList(); - blockChainSummary.add(capsule2.getBlockId()); - blockChainSummary.add(capsule4.getBlockId()); - blockIds = del.getLostBlockIds(blockChainSummary); - } catch (StoreException e) { - e.printStackTrace(); - } - Assert.assertTrue(blockIds.size() == 0); - - //blockChainSummary have 2nd block(main chain)、4th block(fork chain) - try { - BlockCapsule capsule4 = new BlockCapsule(4, - Sha256Hash.wrap(ByteString.copyFrom( - ByteArray.fromHexString( - "00000000000000042498b464ac0292229938a342238077182498b464ac029222"))), - 1234, ByteString.copyFrom("abcdefg".getBytes())); - blockChainSummary = new ArrayList(); - blockChainSummary.add(dbManager.getBlockIdByNum(2)); - blockChainSummary.add(capsule4.getBlockId()); - except_first_block = dbManager.getBlockIdByNum(2); - blockIds = del.getLostBlockIds(blockChainSummary); - } catch (StoreException e) { - e.printStackTrace(); - } - Assert.assertTrue(blockIds.size() == 4 && Arrays - .equals(blockIds.peekFirst().getBytes(), except_first_block.getBytes())); - logger.info("finish2"); - } - - private boolean go = false; - - private Map addTestWitnessAndAccount() { - dbManager.getWitnesses().clear(); - return IntStream.range(0, 2) - .mapToObj( - i -> { - ECKey ecKey = new ECKey(Utils.getRandom()); - String privateKey = ByteArray.toHexString(ecKey.getPrivKey().toByteArray()); - ByteString address = ByteString.copyFrom(ecKey.getAddress()); - - WitnessCapsule witnessCapsule = new WitnessCapsule(address); - dbManager.getWitnessStore().put(address.toByteArray(), witnessCapsule); - dbManager.getWitnessController().addWitness(address); - - AccountCapsule accountCapsule = - new AccountCapsule(Protocol.Account.newBuilder().setAddress(address).build()); - dbManager.getAccountStore().put(address.toByteArray(), accountCapsule); - - return Maps.immutableEntry(address, privateKey); - }) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - private BlockCapsule createTestBlockCapsule( - long number, ByteString hash, Map addressToProvateKeys) { - long time = System.currentTimeMillis(); - return createTestBlockCapsule(time, number, hash, addressToProvateKeys); - } - - private BlockCapsule createTestBlockCapsule(long time, - long number, ByteString hash, Map addressToProvateKeys) { - WitnessController witnessController = dbManager.getWitnessController(); - ByteString witnessAddress = - witnessController.getScheduledWitness(witnessController.getSlotAtTime(time)); - BlockCapsule blockCapsule = new BlockCapsule(number, Sha256Hash.wrap(hash), time, - witnessAddress); - blockCapsule.generatedByMyself = true; - blockCapsule.setMerkleRoot(); - blockCapsule.sign(ByteArray.fromHexString(addressToProvateKeys.get(witnessAddress))); - return blockCapsule; - } - - @Before - public void init() { - nodeEntity = new Node( - "enode://e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c@127.0.0.1:17892"); - - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - logger.info("Full node running."); - Args.setParam( - new String[]{ - "--output-directory", dbPath, - "--storage-db-directory", dbDirectory, - "--storage-index-directory", indexDirectory - }, - "config.conf" - ); - Args cfgArgs = Args.getInstance(); - cfgArgs.setNodeListenPort(17892); - cfgArgs.setNodeDiscoveryEnable(false); - cfgArgs.getSeedNode().getIpList().clear(); - cfgArgs.setNeedSyncCheck(false); - cfgArgs.setNodeExternalIp("127.0.0.1"); - - context = new TronApplicationContext(DefaultConfig.class); - - if (cfgArgs.isHelp()) { - logger.info("Here is the help message."); - return; - } - appT = ApplicationFactory.create(context); - rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); - if (cfgArgs.isWitness()) { - appT.addService(new WitnessService(appT, context)); - } -// appT.initServices(cfgArgs); -// appT.startServices(); -// appT.startup(); - node = context.getBean(NodeImpl.class); - peerClient = context.getBean(PeerClientTest.class); - channelManager = context.getBean(ChannelManager.class); - pool = context.getBean(SyncPool.class); - dbManager = context.getBean(Manager.class); - handshakeHandlerTest = context.getBean(HandshakeHandlerTest.class); - handshakeHandlerTest.setNode(nodeEntity); - NodeDelegate nodeDelegate = new NodeDelegateImpl(dbManager); - node.setNodeDelegate(nodeDelegate); - pool.init(node); - prepare(); - rpcApiService.blockUntilShutdown(); - } - }); - thread.start(); - try { - thread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - int tryTimes = 0; - while (tryTimes < 10 && (node == null || peerClient == null - || channelManager == null || pool == null || !go)) { - try { - logger.info("node:{},peerClient:{},channelManager:{},pool:{},{}", node, peerClient, - channelManager, pool, go); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - ++tryTimes; - } - } - } - - private void prepare() { - try { - ExecutorService advertiseLoopThread = ReflectUtils.getFieldValue(node, "broadPool"); - advertiseLoopThread.shutdownNow(); - - peerClient.prepare(nodeEntity.getHexId()); - - ReflectUtils.setFieldValue(node, "isAdvertiseActive", false); - ReflectUtils.setFieldValue(node, "isFetchActive", false); - - TronChannelInitializerTest tronChannelInitializer = ReflectUtils - .getFieldValue(peerClient, "tronChannelInitializer"); - tronChannelInitializer.prepare(); - org.tron.common.overlay.server.Channel channel = ReflectUtils - .getFieldValue(tronChannelInitializer, "channel"); - ReflectUtils.setFieldValue(channel, "handshakeHandler", handshakeHandlerTest); - - new Thread(new Runnable() { - @Override - public void run() { - peerClient.connect(nodeEntity.getHost(), nodeEntity.getPort(), nodeEntity.getHexId()); - } - }).start(); - Thread.sleep(1000); - Map activePeers = ReflectUtils - .getFieldValue(channelManager, "activePeers"); - int tryTimes = 0; - while (MapUtils.isEmpty(activePeers) && ++tryTimes < 10) { - Thread.sleep(1000); - } - go = true; - } catch (Exception e) { - e.printStackTrace(); - } - } - - @AfterClass - public static void destroy() { - Args.clearParam(); - Collection peerConnections = ReflectUtils.invokeMethod(node, "getActivePeer"); - for (PeerConnection peer : peerConnections) { - peer.close(); - } - handshakeHandlerTest.close(); - appT.shutdownServices(); - appT.shutdown(); - context.destroy(); - FileUtil.deleteDir(new File(dbPath)); - } -} diff --git a/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java b/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java deleted file mode 100644 index 005b41e400a..00000000000 --- a/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java +++ /dev/null @@ -1,246 +0,0 @@ -package org.tron.core.net.node; - -import com.google.protobuf.ByteString; -import java.io.File; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.MapUtils; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.TronApplicationContext; -import org.tron.common.crypto.ECKey; -import org.tron.common.overlay.discover.node.Node; -import org.tron.common.overlay.server.Channel; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.ReflectUtils; -import org.tron.core.Constant; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.config.DefaultConfig; -import org.tron.core.config.args.Args; -import org.tron.core.db.ByteArrayWrapper; -import org.tron.core.db.Manager; -import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.node.override.HandshakeHandlerTest; -import org.tron.core.net.node.override.PeerClientTest; -import org.tron.core.net.node.override.TronChannelInitializerTest; -import org.tron.core.net.peer.Item; -import org.tron.core.net.peer.PeerConnection; -import org.tron.core.services.RpcApiService; -import org.tron.core.services.WitnessService; -import org.tron.protos.Protocol.Block; -import org.tron.protos.Protocol.BlockHeader; -import org.tron.protos.Protocol.Inventory.InventoryType; - -@Slf4j -public class HandleBlockMessageTest { - - private static TronApplicationContext context; - private static NodeImpl node; - private RpcApiService rpcApiService; - private static PeerClientTest peerClient; - private ChannelManager channelManager; - private SyncPool pool; - private static Application appT; - private Manager dbManager; - private Node nodeEntity; - private static HandshakeHandlerTest handshakeHandlerTest; - - private static final String dbPath = "output-HandleBlockMessageTest"; - private static final String dbDirectory = "db_HandleBlockMessage_test"; - private static final String indexDirectory = "index_HandleBlockMessage_test"; - - @Test - public void testHandleBlockMessage() throws Exception { - List activePeers = ReflectUtils.getFieldValue(pool, "activePeers"); - Thread.sleep(5000); - if (activePeers.size() < 1) { - return; - } - PeerConnection peer = activePeers.get(0); - - //receive a sync block - BlockCapsule headBlockCapsule = dbManager.getHead(); - BlockCapsule syncblockCapsule = generateOneBlockCapsule(headBlockCapsule); - BlockMessage blockMessage = new BlockMessage(syncblockCapsule); - peer.getSyncBlockRequested().put(blockMessage.getBlockId(), System.currentTimeMillis()); - node.onMessage(peer, blockMessage); - Assert.assertEquals(peer.getSyncBlockRequested().isEmpty(), true); - - //receive a advertise block - BlockCapsule advblockCapsule = generateOneBlockCapsule(headBlockCapsule); - BlockMessage advblockMessage = new BlockMessage(advblockCapsule); - peer.getAdvObjWeRequested().put(new Item(advblockMessage.getBlockId(), InventoryType.BLOCK), - System.currentTimeMillis()); - node.onMessage(peer, advblockMessage); - Assert.assertEquals(peer.getAdvObjWeRequested().size(), 0); - - //receive a sync block but not requested - BlockCapsule blockCapsule = generateOneBlockCapsule(headBlockCapsule); - blockMessage = new BlockMessage(blockCapsule); - BlockCapsule blockCapsuleOther = generateOneBlockCapsule(blockCapsule); - BlockMessage blockMessageOther = new BlockMessage(blockCapsuleOther); - - peer.getSyncBlockRequested().put(blockMessage.getBlockId(), System.currentTimeMillis()); - node.onMessage(peer, blockMessageOther); - Assert.assertEquals(peer.getSyncBlockRequested().isEmpty(), false); - } - - // generate ong block by parent block - private BlockCapsule generateOneBlockCapsule(BlockCapsule parentCapsule) { - ByteString witnessAddress = ByteString.copyFrom( - ECKey.fromPrivate( - ByteArray.fromHexString( - Args.getInstance().getLocalWitnesses().getPrivateKey())) - .getAddress()); - BlockHeader.raw raw = BlockHeader.raw.newBuilder() - .setTimestamp(System.currentTimeMillis()) - .setParentHash(parentCapsule.getBlockId().getByteString()) - .setNumber(parentCapsule.getNum() + 1) - .setWitnessAddress(witnessAddress) - .setWitnessId(1).build(); - BlockHeader blockHeader = BlockHeader.newBuilder() - .setRawData(raw) - .build(); - - Block block = Block.newBuilder().setBlockHeader(blockHeader).build(); - - BlockCapsule blockCapsule = new BlockCapsule(block); - blockCapsule.setMerkleRoot(); - blockCapsule.sign( - ByteArray.fromHexString(Args.getInstance().getLocalWitnesses().getPrivateKey())); - blockCapsule.setMerkleRoot(); - blockCapsule.sign( - ByteArray.fromHexString(Args.getInstance().getLocalWitnesses().getPrivateKey())); - - return blockCapsule; - } - - private static boolean go = false; - - @Before - public void init() { - nodeEntity = new Node( - "enode://e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c@127.0.0.1:17894"); - - new Thread(new Runnable() { - @Override - public void run() { - logger.info("Full node running."); - Args.setParam( - new String[]{ - "--output-directory", dbPath, - "--storage-db-directory", dbDirectory, - "--storage-index-directory", indexDirectory - }, - Constant.TEST_CONF - ); - Args cfgArgs = Args.getInstance(); - cfgArgs.setNodeListenPort(17894); - cfgArgs.setNodeDiscoveryEnable(false); - cfgArgs.getSeedNode().getIpList().clear(); - cfgArgs.setNeedSyncCheck(false); - cfgArgs.setNodeExternalIp("127.0.0.1"); - - context = new TronApplicationContext(DefaultConfig.class); - - if (cfgArgs.isHelp()) { - logger.info("Here is the help message."); - return; - } - appT = ApplicationFactory.create(context); - rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); - if (cfgArgs.isWitness()) { - appT.addService(new WitnessService(appT, context)); - } -// appT.initServices(cfgArgs); -// appT.startServices(); -// appT.startup(); - node = context.getBean(NodeImpl.class); - peerClient = context.getBean(PeerClientTest.class); - channelManager = context.getBean(ChannelManager.class); - pool = context.getBean(SyncPool.class); - dbManager = context.getBean(Manager.class); - handshakeHandlerTest = context.getBean(HandshakeHandlerTest.class); - handshakeHandlerTest.setNode(nodeEntity); - NodeDelegate nodeDelegate = new NodeDelegateImpl(dbManager); - node.setNodeDelegate(nodeDelegate); - pool.init(node); - prepare(); - rpcApiService.blockUntilShutdown(); - } - }).start(); - int tryTimes = 0; - while (tryTimes < 10 && (node == null || peerClient == null - || channelManager == null || pool == null || !go)) { - try { - logger.info("node:{},peerClient:{},channelManager:{},pool:{},{}", node, peerClient, - channelManager, pool, go); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - ++tryTimes; - } - } - } - - private void prepare() { - try { - ExecutorService advertiseLoopThread = ReflectUtils.getFieldValue(node, "broadPool"); - advertiseLoopThread.shutdownNow(); - - peerClient.prepare(nodeEntity.getHexId()); - - ReflectUtils.setFieldValue(node, "isAdvertiseActive", false); - ReflectUtils.setFieldValue(node, "isFetchActive", false); - - TronChannelInitializerTest tronChannelInitializer = ReflectUtils - .getFieldValue(peerClient, "tronChannelInitializer"); - tronChannelInitializer.prepare(); - Channel channel = ReflectUtils.getFieldValue(tronChannelInitializer, "channel"); - ReflectUtils.setFieldValue(channel, "handshakeHandler", handshakeHandlerTest); - - new Thread(new Runnable() { - @Override - public void run() { - peerClient.connect(nodeEntity.getHost(), nodeEntity.getPort(), nodeEntity.getHexId()); - } - }).start(); - Thread.sleep(1000); - Map activePeers = ReflectUtils - .getFieldValue(channelManager, "activePeers"); - int tryTimes = 0; - while (MapUtils.isEmpty(activePeers) && ++tryTimes < 10) { - Thread.sleep(1000); - } - go = true; - } catch (Exception e) { - e.printStackTrace(); - } - } - - @AfterClass - public static void destroy() { - Args.clearParam(); - Collection peerConnections = ReflectUtils.invokeMethod(node, "getActivePeer"); - for (PeerConnection peer : peerConnections) { - peer.close(); - } - handshakeHandlerTest.close(); - appT.shutdownServices(); - appT.shutdown(); - context.destroy(); - FileUtil.deleteDir(new File(dbPath)); - } -} diff --git a/src/test/java/org/tron/core/net/node/HandleSyncBlockTest.java b/src/test/java/org/tron/core/net/node/HandleSyncBlockTest.java deleted file mode 100644 index 41bc23f3ec9..00000000000 --- a/src/test/java/org/tron/core/net/node/HandleSyncBlockTest.java +++ /dev/null @@ -1,271 +0,0 @@ -package org.tron.core.net.node; - -import com.google.protobuf.ByteString; -import java.io.File; -import java.util.Collection; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.MapUtils; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.TronApplicationContext; -import org.tron.common.crypto.ECKey; -import org.tron.common.overlay.discover.node.Node; -import org.tron.common.overlay.server.Channel; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.ReflectUtils; -import org.tron.common.utils.Sha256Hash; -import org.tron.core.Constant; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.capsule.utils.BlockUtil; -import org.tron.core.config.DefaultConfig; -import org.tron.core.config.args.Args; -import org.tron.core.db.ByteArrayWrapper; -import org.tron.core.db.Manager; -import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.node.override.HandshakeHandlerTest; -import org.tron.core.net.node.override.PeerClientTest; -import org.tron.core.net.node.override.TronChannelInitializerTest; -import org.tron.core.net.peer.PeerConnection; -import org.tron.core.services.RpcApiService; -import org.tron.core.services.WitnessService; -import org.tron.protos.Protocol; - -@Slf4j -public class HandleSyncBlockTest { - - private static TronApplicationContext context; - private static NodeImpl node; - private RpcApiService rpcApiService; - private static PeerClientTest peerClient; - private ChannelManager channelManager; - private SyncPool pool; - private static Application appT; - private Node nodeEntity; - private static HandshakeHandlerTest handshakeHandlerTest; - private static final String dbPath = "output-nodeImplTest-handleSyncBlock"; - private static final String dbDirectory = "db_HandleSyncBlock_test"; - private static final String indexDirectory = "index_HandleSyncBlock_test"; - - private class Condition { - - private Sha256Hash blockId; - - public Condition(Sha256Hash blockId) { - this.blockId = blockId; - } - - public Sha256Hash getBlockId() { - return blockId; - } - } - - private Sha256Hash testBlockBroad() { - Protocol.Block block = Protocol.Block.getDefaultInstance(); - BlockMessage blockMessage = new BlockMessage(new BlockCapsule(block)); - node.broadcast(blockMessage); - ConcurrentHashMap advObjToSpread = ReflectUtils - .getFieldValue(node, "advObjToSpread"); - Assert.assertEquals(advObjToSpread.get(blockMessage.getMessageId()), - Protocol.Inventory.InventoryType.BLOCK); - return blockMessage.getMessageId(); - } - - private Condition testConsumerAdvObjToSpread() { - Sha256Hash blockId = testBlockBroad(); - - ReflectUtils.invokeMethod(node, "consumerAdvObjToSpread"); - Collection activePeers = ReflectUtils.invokeMethod(node, "getActivePeer"); - - boolean result = true; - for (PeerConnection peerConnection : activePeers) { - if (!peerConnection.getAdvObjWeSpread().containsKey(blockId)) { - result &= false; - } - } - for (PeerConnection peerConnection : activePeers) { - peerConnection.getAdvObjWeSpread().clear(); - } - Assert.assertTrue(result); - return new Condition(blockId); - } - - private BlockMessage buildBlockMessage() throws Exception { - BlockCapsule genesisBlockCapsule = BlockUtil.newGenesisBlockCapsule(); - - ByteString witnessAddress = ByteString.copyFrom( - ECKey.fromPrivate( - ByteArray.fromHexString( - Args.getInstance().getLocalWitnesses().getPrivateKey())) - .getAddress()); - Protocol.BlockHeader.raw raw = Protocol.BlockHeader.raw.newBuilder() - .setTimestamp(System.currentTimeMillis()) - .setParentHash(genesisBlockCapsule.getBlockId().getByteString()) - .setNumber(genesisBlockCapsule.getNum() + 1) - .setWitnessAddress(witnessAddress) - .setWitnessId(1).build(); - Protocol.BlockHeader blockHeader = Protocol.BlockHeader.newBuilder() - .setRawData(raw) - .build(); - - Protocol.Block block = Protocol.Block.newBuilder().setBlockHeader(blockHeader).build(); - - BlockCapsule blockCapsule = new BlockCapsule(block); - blockCapsule.setMerkleRoot(); - blockCapsule.sign(ByteArray.fromHexString(Args.getInstance().getLocalWitnesses().getPrivateKey())); - BlockMessage blockMessage = new BlockMessage(blockCapsule); - return blockMessage; - } - - @Test - public void testHandleSyncBlock() throws Exception { - testConsumerAdvObjToSpread(); - // build block Message - BlockMessage blockMessage = buildBlockMessage(); - // build blockJustReceived - Map blockJustReceived = new ConcurrentHashMap<>(); - blockJustReceived.put(blockMessage, new PeerConnection()); - ReflectUtils.setFieldValue(node, "blockJustReceived", blockJustReceived); - Thread.sleep(1000); - // retrieve the first active peer - Collection activePeers = ReflectUtils.invokeMethod(node, "getActivePeer"); - activePeers.iterator().next().getSyncBlockToFetch().push(blockMessage.getBlockId()); - // clean up freshBlockId - Queue freshBlockId = ReflectUtils - .getFieldValue(node, "freshBlockId"); - freshBlockId.poll(); - // trigger handlesyncBlock method - ReflectUtils.invokeMethod(node, "handleSyncBlock"); - - Assert.assertTrue(freshBlockId.contains(blockMessage.getBlockId())); - } - - private static boolean go = false; - - @Before - public void init() { - nodeEntity = new Node( - "enode://e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c@127.0.0.1:17893"); - - new Thread(new Runnable() { - @Override - public void run() { - logger.info("Full node running."); - Args.setParam( - new String[]{ - "--output-directory", dbPath, - "--storage-db-directory", dbDirectory, - "--storage-index-directory", indexDirectory - }, - Constant.TEST_CONF - ); - Args cfgArgs = Args.getInstance(); - cfgArgs.setNodeListenPort(17893); - cfgArgs.setNodeDiscoveryEnable(false); - cfgArgs.getSeedNode().getIpList().clear(); - cfgArgs.setNeedSyncCheck(false); - cfgArgs.setNodeExternalIp("127.0.0.1"); - - context = new TronApplicationContext(DefaultConfig.class); - - if (cfgArgs.isHelp()) { - logger.info("Here is the help message."); - return; - } - appT = ApplicationFactory.create(context); - rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); - if (cfgArgs.isWitness()) { - appT.addService(new WitnessService(appT, context)); - } -// appT.initServices(cfgArgs); -// appT.startServices(); -// appT.startup(); - node = context.getBean(NodeImpl.class); - peerClient = context.getBean(PeerClientTest.class); - channelManager = context.getBean(ChannelManager.class); - pool = context.getBean(SyncPool.class); - Manager dbManager = context.getBean(Manager.class); - handshakeHandlerTest = context.getBean(HandshakeHandlerTest.class); - handshakeHandlerTest.setNode(nodeEntity); - NodeDelegate nodeDelegate = new NodeDelegateImpl(dbManager); - node.setNodeDelegate(nodeDelegate); - pool.init(node); - prepare(); - rpcApiService.blockUntilShutdown(); - } - }).start(); - int tryTimes = 0; - while (tryTimes < 10 && (node == null || peerClient == null - || channelManager == null || pool == null || !go)) { - try { - logger.info("node:{},peerClient:{},channelManager:{},pool:{},{}", node, peerClient, - channelManager, pool, go); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - ++tryTimes; - } - } - } - - private void prepare() { - try { - ExecutorService advertiseLoopThread = ReflectUtils.getFieldValue(node, "broadPool"); - advertiseLoopThread.shutdownNow(); - - peerClient.prepare(nodeEntity.getHexId()); - - ReflectUtils.setFieldValue(node, "isAdvertiseActive", false); - ReflectUtils.setFieldValue(node, "isFetchActive", false); - - TronChannelInitializerTest tronChannelInitializer = ReflectUtils - .getFieldValue(peerClient, "tronChannelInitializer"); - tronChannelInitializer.prepare(); - Channel channel = ReflectUtils.getFieldValue(tronChannelInitializer, "channel"); - ReflectUtils.setFieldValue(channel, "handshakeHandler", handshakeHandlerTest); - - new Thread(new Runnable() { - @Override - public void run() { - peerClient.connect(nodeEntity.getHost(), nodeEntity.getPort(), nodeEntity.getHexId()); - } - }).start(); - Thread.sleep(1000); - Map activePeers = ReflectUtils - .getFieldValue(channelManager, "activePeers"); - int tryTimes = 0; - while (MapUtils.isEmpty(activePeers) && ++tryTimes < 10) { - Thread.sleep(1000); - } - go = true; - } catch (Exception e) { - e.printStackTrace(); - } - } - - @AfterClass - public static void destroy() { - Args.clearParam(); - Collection peerConnections = ReflectUtils.invokeMethod(node, "getActivePeer"); - for (PeerConnection peer : peerConnections) { - peer.close(); - } - handshakeHandlerTest.close(); - context.destroy(); - appT.shutdownServices(); - appT.shutdown(); - FileUtil.deleteDir(new File(dbPath)); - } -} diff --git a/src/test/java/org/tron/core/net/node/HandleTransactionTest.java b/src/test/java/org/tron/core/net/node/HandleTransactionTest.java deleted file mode 100644 index ff02f1d95e1..00000000000 --- a/src/test/java/org/tron/core/net/node/HandleTransactionTest.java +++ /dev/null @@ -1,234 +0,0 @@ -package org.tron.core.net.node; - -import com.google.protobuf.ByteString; -import java.io.File; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.MapUtils; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Test; -import org.testng.collections.Lists; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.TronApplicationContext; -import org.tron.common.overlay.discover.node.Node; -import org.tron.common.overlay.server.Channel; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.ReflectUtils; -import org.tron.core.Constant; -import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.config.DefaultConfig; -import org.tron.core.config.args.Args; -import org.tron.core.db.ByteArrayWrapper; -import org.tron.core.db.Manager; -import org.tron.core.net.message.TransactionMessage; -import org.tron.core.net.message.TransactionsMessage; -import org.tron.core.net.node.override.HandshakeHandlerTest; -import org.tron.core.net.node.override.PeerClientTest; -import org.tron.core.net.node.override.TronChannelInitializerTest; -import org.tron.core.net.peer.Item; -import org.tron.core.net.peer.PeerConnection; -import org.tron.core.services.RpcApiService; -import org.tron.core.services.WitnessService; -import org.tron.protos.Contract.TransferContract; -import org.tron.protos.Protocol; -import org.tron.protos.Protocol.Inventory.InventoryType; -import org.tron.protos.Protocol.Transaction.Contract.ContractType; - - -@Slf4j -public class HandleTransactionTest { - - private static TronApplicationContext context; - private static NodeImpl node; - private RpcApiService rpcApiService; - private static PeerClientTest peerClient; - private ChannelManager channelManager; - private SyncPool pool; - private static Application appT; - private static Manager dbManager; - private Node nodeEntity; - private static HandshakeHandlerTest handshakeHandlerTest; - - private static final String dbPath = "output-HandleTransactionTest"; - private static final String dbDirectory = "db_HandleTransaction_test"; - private static final String indexDirectory = "index_HandleTransaction_test"; - - private static Boolean deleteFolder(File index) { - if (!index.isDirectory() || index.listFiles().length <= 0) { - return index.delete(); - } - for (File file : index.listFiles()) { - if (null != file && !deleteFolder(file)) { - return false; - } - } - return index.delete(); - } - - @Test - public void testHandleTransactionMessage() throws Exception{ - - TransferContract tc = - TransferContract.newBuilder() - .setAmount(10) - .setOwnerAddress(ByteString.copyFromUtf8("aaa")) - .setToAddress(ByteString.copyFromUtf8("bbb")) - .build(); - - TransactionCapsule trx = new TransactionCapsule(tc, ContractType.TransferContract); - - Protocol.Transaction transaction = trx.getInstance(); - - TransactionMessage transactionMessage = new TransactionMessage(transaction); - List list = Lists.newArrayList(); - list.add(transaction); - TransactionsMessage transactionsMessage = new TransactionsMessage(list); - - PeerConnection peer = new PeerConnection(); - //没有向peer广播请求过交易信息 - peer.getAdvObjWeRequested().clear(); - peer.setSyncFlag(true); - //nodeImpl.onMessage(peer, transactionMessage); - //Assert.assertEquals(peer.getSyncFlag(), false); - - //向peer广播请求过交易信息 - peer.getAdvObjWeRequested().put(new Item(transactionMessage.getMessageId(), InventoryType.TRX), System.currentTimeMillis()); - peer.setSyncFlag(true); - node.onMessage(peer, transactionsMessage); - //Assert.assertEquals(peer.getAdvObjWeRequested().isEmpty(), true); - //ConcurrentHashMap advObjToSpread = ReflectUtils.getFieldValue(nodeImpl, "advObjToSpread"); - //Assert.assertEquals(advObjToSpread.contains(transactionMessage.getMessageId()), true); - } - - private static boolean go = false; - - @Before - public void init() { - nodeEntity = new Node( - "enode://e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c@127.0.0.1:17891"); - - new Thread(new Runnable() { - @Override - public void run() { - logger.info("Full node running."); - Args.setParam( - new String[]{ - "--output-directory", dbPath, - "--storage-db-directory", dbDirectory, - "--storage-index-directory", indexDirectory - }, - Constant.TEST_CONF - ); - Args cfgArgs = Args.getInstance(); - cfgArgs.setNodeListenPort(17891); - cfgArgs.setNodeDiscoveryEnable(false); - cfgArgs.getSeedNode().getIpList().clear(); - cfgArgs.setNeedSyncCheck(false); - cfgArgs.setNodeExternalIp("127.0.0.1"); - - context = new TronApplicationContext(DefaultConfig.class); - - if (cfgArgs.isHelp()) { - logger.info("Here is the help message."); - return; - } - appT = ApplicationFactory.create(context); - rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); - if (cfgArgs.isWitness()) { - appT.addService(new WitnessService(appT, context)); - } -// appT.initServices(cfgArgs); -// appT.startServices(); -// appT.startup(); - node = context.getBean(NodeImpl.class); - peerClient = context.getBean(PeerClientTest.class); - channelManager = context.getBean(ChannelManager.class); - pool = context.getBean(SyncPool.class); - dbManager = context.getBean(Manager.class); - handshakeHandlerTest = context.getBean(HandshakeHandlerTest.class); - handshakeHandlerTest.setNode(nodeEntity); - NodeDelegate nodeDelegate = new NodeDelegateImpl(dbManager); - node.setNodeDelegate(nodeDelegate); - pool.init(node); - prepare(); - rpcApiService.blockUntilShutdown(); - } - }).start(); - int tryTimes = 0; - while (tryTimes < 10 && (node == null || peerClient == null - || channelManager == null || pool == null || !go)) { - try { - logger.info("node:{},peerClient:{},channelManager:{},pool:{},{}", node, peerClient, - channelManager, pool, go); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - ++tryTimes; - } - } - } - - private void prepare() { - try { - ExecutorService advertiseLoopThread = ReflectUtils.getFieldValue(node, "broadPool"); - advertiseLoopThread.shutdownNow(); - - peerClient.prepare(nodeEntity.getHexId()); - - ReflectUtils.setFieldValue(node, "isAdvertiseActive", false); - ReflectUtils.setFieldValue(node, "isFetchActive", false); - - TronChannelInitializerTest tronChannelInitializer = ReflectUtils - .getFieldValue(peerClient, "tronChannelInitializer"); - tronChannelInitializer.prepare(); - Channel channel = ReflectUtils.getFieldValue(tronChannelInitializer, "channel"); - ReflectUtils.setFieldValue(channel, "handshakeHandler", handshakeHandlerTest); - - new Thread(new Runnable() { - @Override - public void run() { - peerClient.connect(nodeEntity.getHost(), nodeEntity.getPort(), nodeEntity.getHexId()); - } - }).start(); - Thread.sleep(1000); - Map activePeers = ReflectUtils - .getFieldValue(channelManager, "activePeers"); - int tryTimes = 0; - while (MapUtils.isEmpty(activePeers) && ++tryTimes < 10) { - Thread.sleep(1000); - } - go = true; - } catch (Exception e) { - e.printStackTrace(); - } - } - - @AfterClass - public static void destroy() { - Args.clearParam(); - Collection peerConnections = ReflectUtils.invokeMethod(node, "getActivePeer"); - for (PeerConnection peer : peerConnections) { - peer.close(); - } - handshakeHandlerTest.close(); - appT.shutdownServices(); - appT.shutdown(); - context.destroy(); - dbManager.getSession().reset(); - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - FileUtil.deleteDir(new File(dbPath)); - } -} diff --git a/src/test/java/org/tron/core/net/node/NodeImplTest.java b/src/test/java/org/tron/core/net/node/NodeImplTest.java deleted file mode 100644 index 43dd9382f38..00000000000 --- a/src/test/java/org/tron/core/net/node/NodeImplTest.java +++ /dev/null @@ -1,205 +0,0 @@ -package org.tron.core.net.node; - -import com.google.protobuf.ByteString; -import lombok.extern.slf4j.Slf4j; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.TronApplicationContext; -import org.tron.common.crypto.ECKey; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -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.capsule.utils.BlockUtil; -import org.tron.core.config.DefaultConfig; -import org.tron.core.config.Parameter.NetConstants; -import org.tron.core.config.args.Args; -import org.tron.core.db.Manager; -import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.peer.Item; -import org.tron.core.net.peer.PeerConnection; -import org.tron.protos.Protocol.Block; -import org.tron.protos.Protocol.BlockHeader; -import org.tron.protos.Protocol.Inventory.InventoryType; - -import java.io.File; -import java.util.concurrent.ConcurrentHashMap; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - - -@Slf4j -public class NodeImplTest { - - private static TronApplicationContext context; - - private static Application appT; - private static String dbPath = "output_nodeimpl_test"; - private static NodeImpl nodeImpl; - private static Manager dbManager; - private static NodeDelegateImpl nodeDelegate; - - static { - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); - context = new TronApplicationContext(DefaultConfig.class); - Args.getInstance().setSolidityNode(true); - appT = ApplicationFactory.create(context); - } - - @Test - public void testSyncBlockMessage() throws Exception { - PeerConnection peer = new PeerConnection(); - BlockCapsule genesisBlockCapsule = BlockUtil.newGenesisBlockCapsule(); - - ByteString witnessAddress = ByteString.copyFrom( - ECKey.fromPrivate( - ByteArray.fromHexString( - Args.getInstance().getLocalWitnesses().getPrivateKey())) - .getAddress()); - BlockHeader.raw raw = BlockHeader.raw.newBuilder() - .setTimestamp(System.currentTimeMillis()) - .setParentHash(genesisBlockCapsule.getParentHash().getByteString()) - .setNumber(genesisBlockCapsule.getNum() + 1) - .setWitnessAddress(witnessAddress) - .setWitnessId(1).build(); - BlockHeader blockHeader = BlockHeader.newBuilder() - .setRawData(raw) - .build(); - - Block block = Block.newBuilder().setBlockHeader(blockHeader).build(); - - BlockCapsule blockCapsule = new BlockCapsule(block); - blockCapsule.sign( - ByteArray.fromHexString(Args.getInstance().getLocalWitnesses().getPrivateKey())); - blockCapsule.setMerkleRoot(); - BlockMessage blockMessage = new BlockMessage(blockCapsule); - peer.getSyncBlockRequested().put(blockMessage.getBlockId(), System.currentTimeMillis()); - nodeImpl.onMessage(peer, blockMessage); - Assert.assertEquals(peer.getSyncBlockRequested().size(), 0); - } - - @Test - public void testAdvBlockMessage() throws Exception{ - PeerConnection peer = new PeerConnection(); - BlockCapsule genesisBlockCapsule = BlockUtil.newGenesisBlockCapsule(); - - ByteString witnessAddress = ByteString.copyFrom( - ECKey.fromPrivate( - ByteArray.fromHexString( - Args.getInstance().getLocalWitnesses().getPrivateKey())) - .getAddress()); - BlockHeader.raw raw = BlockHeader.raw.newBuilder() - .setTimestamp(System.currentTimeMillis()) - .setParentHash(genesisBlockCapsule.getBlockId().getByteString()) - .setNumber(genesisBlockCapsule.getNum() + 1) - .setWitnessAddress(witnessAddress) - .setWitnessId(1).build(); - BlockHeader blockHeader = BlockHeader.newBuilder() - .setRawData(raw) - .build(); - - Block block = Block.newBuilder().setBlockHeader(blockHeader).build(); - - BlockCapsule blockCapsule = new BlockCapsule(block); - blockCapsule.setMerkleRoot(); - blockCapsule.sign( - ByteArray.fromHexString(Args.getInstance().getLocalWitnesses().getPrivateKey())); - BlockMessage blockMessage = new BlockMessage(blockCapsule); - peer.getAdvObjWeRequested().put(new Item(blockMessage.getBlockId(), InventoryType.BLOCK), System.currentTimeMillis()); - nodeImpl.onMessage(peer, blockMessage); - Assert.assertEquals(peer.getAdvObjWeRequested().size(), 0); - } - - // @Test - public void testDisconnectInactive() { - // generate test data - ConcurrentHashMap advObjWeRequested1 = new ConcurrentHashMap<>(); - ConcurrentHashMap advObjWeRequested2 = new ConcurrentHashMap<>(); - ConcurrentHashMap advObjWeRequested3 = new ConcurrentHashMap<>(); - ConcurrentHashMap syncBlockRequested1 = new ConcurrentHashMap<>(); - ConcurrentHashMap syncBlockRequested2 = new ConcurrentHashMap<>(); - ConcurrentHashMap syncBlockRequested3 = new ConcurrentHashMap<>(); - - advObjWeRequested1.put(new Item(new Sha256Hash(1, Sha256Hash.ZERO_HASH), InventoryType.TRX), - System.currentTimeMillis() - NetConstants.ADV_TIME_OUT); - syncBlockRequested1.put(new BlockId(), - System.currentTimeMillis()); - advObjWeRequested2.put(new Item(new Sha256Hash(1, Sha256Hash.ZERO_HASH), InventoryType.TRX), - System.currentTimeMillis()); - syncBlockRequested2.put(new BlockId(), - System.currentTimeMillis() - NetConstants.SYNC_TIME_OUT); - advObjWeRequested3.put(new Item(new Sha256Hash(1, Sha256Hash.ZERO_HASH), InventoryType.TRX), - System.currentTimeMillis()); - syncBlockRequested3.put(new BlockId(), - System.currentTimeMillis()); - - PeerConnection peer1 = new PeerConnection(); - PeerConnection peer2 = new PeerConnection(); - PeerConnection peer3 = new PeerConnection(); - - peer1.setAdvObjWeRequested(advObjWeRequested1); - peer1.setSyncBlockRequested(syncBlockRequested1); - peer2.setAdvObjWeRequested(advObjWeRequested2); - peer2.setSyncBlockRequested(syncBlockRequested2); - peer3.setAdvObjWeRequested(advObjWeRequested3); - peer3.setSyncBlockRequested(syncBlockRequested3); - - // fetch failed - SyncPool pool = new SyncPool(); - pool.addActivePeers(peer1); - nodeImpl.setPool(pool); - try { - nodeImpl.disconnectInactive(); - fail("disconnectInactive failed"); - } catch (RuntimeException e) { - assertTrue("disconnect successfully, reason is fetch failed", true); - } - - // sync failed - pool = new SyncPool(); - pool.addActivePeers(peer2); - nodeImpl.setPool(pool); - try { - nodeImpl.disconnectInactive(); - fail("disconnectInactive failed"); - } catch (RuntimeException e) { - assertTrue("disconnect successfully, reason is sync failed", true); - } - - // should not disconnect - pool = new SyncPool(); - pool.addActivePeers(peer3); - nodeImpl.setPool(pool); - try { - nodeImpl.disconnectInactive(); - assertTrue("not disconnect", true); - } catch (RuntimeException e) { - fail("should not disconnect!"); - } - } - - @BeforeClass - public static void init() { - nodeImpl = context.getBean(NodeImpl.class); - dbManager = context.getBean(Manager.class); - nodeDelegate = new NodeDelegateImpl(dbManager); - nodeImpl.setNodeDelegate(nodeDelegate); - } - - @AfterClass - public static void destroy(){ - Args.clearParam(); - context.destroy(); - appT.shutdownServices(); - appT.shutdown(); - FileUtil.deleteDir(new File(dbPath)); - } -} diff --git a/src/test/java/org/tron/core/net/node/StartFetchSyncBlockTest.java b/src/test/java/org/tron/core/net/node/StartFetchSyncBlockTest.java deleted file mode 100644 index 672b0fde837..00000000000 --- a/src/test/java/org/tron/core/net/node/StartFetchSyncBlockTest.java +++ /dev/null @@ -1,257 +0,0 @@ -package org.tron.core.net.node; - -import com.google.common.cache.Cache; -import java.io.File; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.MapUtils; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.TronApplicationContext; -import org.tron.common.overlay.discover.node.Node; -import org.tron.common.overlay.server.Channel; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.common.overlay.server.SyncPool; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.ReflectUtils; -import org.tron.common.utils.Sha256Hash; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.config.DefaultConfig; -import org.tron.core.config.args.Args; -import org.tron.core.db.ByteArrayWrapper; -import org.tron.core.db.Manager; -import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.node.override.HandshakeHandlerTest; -import org.tron.core.net.node.override.PeerClientTest; -import org.tron.core.net.node.override.TronChannelInitializerTest; -import org.tron.core.net.peer.PeerConnection; -import org.tron.core.services.RpcApiService; -import org.tron.core.services.WitnessService; -import org.tron.protos.Protocol; - -@Slf4j -public class StartFetchSyncBlockTest { - - private static TronApplicationContext context; - private NodeImpl node; - private RpcApiService rpcApiService; - private static PeerClientTest peerClient; - private ChannelManager channelManager; - private SyncPool pool; - private static Application appT; - private Node nodeEntity; - private static HandshakeHandlerTest handshakeHandlerTest; - private static final String dbPath = "output-nodeImplTest-startFetchSyncBlockTest"; - private static final String dbDirectory = "db_StartFetchSyncBlock_test"; - private static final String indexDirectory = "index_StartFetchSyncBlock_test"; - - private class Condition { - - private Sha256Hash blockId; - - public Condition(Sha256Hash blockId) { - this.blockId = blockId; - } - - public Sha256Hash getBlockId() { - return blockId; - } - - } - - private Sha256Hash testBlockBroad() { - Protocol.Block block = Protocol.Block.getDefaultInstance(); - BlockMessage blockMessage = new BlockMessage(new BlockCapsule(block)); - node.broadcast(blockMessage); - ConcurrentHashMap advObjToSpread = ReflectUtils - .getFieldValue(node, "advObjToSpread"); - Assert.assertEquals(advObjToSpread.get(blockMessage.getMessageId()), - Protocol.Inventory.InventoryType.BLOCK); - return blockMessage.getMessageId(); - } - - private BlockMessage removeTheBlock(Sha256Hash blockId) { - Cache blockCache = ReflectUtils.getFieldValue(node, "BlockCache"); - BlockMessage blockMessage = blockCache.getIfPresent(blockId); - if (blockMessage != null) { - blockCache.invalidate(blockId); - } - return blockMessage; - } - - private void addTheBlock(BlockMessage blockMessag) { - Cache blockCache = ReflectUtils.getFieldValue(node, "BlockCache"); - blockCache.put(blockMessag.getMessageId(), blockMessag); - } - - private Condition testConsumerAdvObjToSpread() { - Sha256Hash blockId = testBlockBroad(); - //remove the block - BlockMessage blockMessage = removeTheBlock(blockId); - ReflectUtils.invokeMethod(node, "consumerAdvObjToSpread"); - Collection activePeers = ReflectUtils.invokeMethod(node, "getActivePeer"); - - boolean result = true; - for (PeerConnection peerConnection : activePeers) { - if (!peerConnection.getAdvObjWeSpread().containsKey(blockId)) { - result &= false; - } - } - for (PeerConnection peerConnection : activePeers) { - peerConnection.getAdvObjWeSpread().clear(); - } - Assert.assertTrue(result); - return new Condition(blockId); - } - - @Test - public void testStartFetchSyncBlock() throws InterruptedException { - testConsumerAdvObjToSpread(); - Collection activePeers = ReflectUtils.invokeMethod(node, "getActivePeer"); - Thread.sleep(5000); - if (activePeers.size() < 1) { - return; - } - ReflectUtils.setFieldValue(activePeers.iterator().next(), "needSyncFromPeer", true); - // construct a block - Protocol.Block block = Protocol.Block.getDefaultInstance(); - BlockMessage blockMessage = new BlockMessage(new BlockCapsule(block)); - // push the block to syncBlockToFetch - activePeers.iterator().next().getSyncBlockToFetch().push(blockMessage.getBlockId()); - // invoke testing method - addTheBlock(blockMessage); - ReflectUtils.invokeMethod(node, "startFetchSyncBlock"); - Cache syncBlockIdWeRequested = ReflectUtils - .getFieldValue(node, "syncBlockIdWeRequested"); - Assert.assertTrue(syncBlockIdWeRequested.size() == 1); - } - - - private static boolean go = false; - - @Before - public void init() { - nodeEntity = new Node( - "enode://e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c@127.0.0.1:17890"); - - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - logger.info("Full node running."); - Args.setParam( - new String[]{ - "--output-directory", dbPath, - "--storage-db-directory", dbDirectory, - "--storage-index-directory", indexDirectory - }, - "config.conf" - ); - Args cfgArgs = Args.getInstance(); - cfgArgs.setNodeListenPort(17890); - cfgArgs.setNodeDiscoveryEnable(false); - cfgArgs.getSeedNode().getIpList().clear(); - cfgArgs.setNeedSyncCheck(false); - cfgArgs.setNodeExternalIp("127.0.0.1"); - - context = new TronApplicationContext(DefaultConfig.class); - - if (cfgArgs.isHelp()) { - logger.info("Here is the help message."); - return; - } - appT = ApplicationFactory.create(context); - rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); - if (cfgArgs.isWitness()) { - appT.addService(new WitnessService(appT, context)); - } -// appT.initServices(cfgArgs); -// appT.startServices(); -// appT.startup(); - node = context.getBean(NodeImpl.class); - peerClient = context.getBean(PeerClientTest.class); - channelManager = context.getBean(ChannelManager.class); - pool = context.getBean(SyncPool.class); - Manager dbManager = context.getBean(Manager.class); - handshakeHandlerTest = context.getBean(HandshakeHandlerTest.class); - handshakeHandlerTest.setNode(nodeEntity); - NodeDelegate nodeDelegate = new NodeDelegateImpl(dbManager); - node.setNodeDelegate(nodeDelegate); - pool.init(node); - prepare(); - rpcApiService.blockUntilShutdown(); - } - }); - thread.start(); - try { - thread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - int tryTimes = 0; - while (tryTimes < 10 && (node == null || peerClient == null - || channelManager == null || pool == null || !go)) { - try { - logger.info("node:{},peerClient:{},channelManager:{},pool:{},{}", node, peerClient, - channelManager, pool, go); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - ++tryTimes; - } - } - } - - private void prepare() { - try { - ExecutorService advertiseLoopThread = ReflectUtils.getFieldValue(node, "broadPool"); - advertiseLoopThread.shutdownNow(); - - peerClient.prepare(nodeEntity.getHexId()); - - ReflectUtils.setFieldValue(node, "isAdvertiseActive", false); - ReflectUtils.setFieldValue(node, "isFetchActive", false); - - TronChannelInitializerTest tronChannelInitializer = ReflectUtils - .getFieldValue(peerClient, "tronChannelInitializer"); - tronChannelInitializer.prepare(); - Channel channel = ReflectUtils.getFieldValue(tronChannelInitializer, "channel"); - ReflectUtils.setFieldValue(channel, "handshakeHandler", handshakeHandlerTest); - - new Thread(new Runnable() { - @Override - public void run() { - peerClient.connect(nodeEntity.getHost(), nodeEntity.getPort(), nodeEntity.getHexId()); - } - }).start(); - Thread.sleep(1000); - Map activePeers = ReflectUtils - .getFieldValue(channelManager, "activePeers"); - int tryTimes = 0; - while (MapUtils.isEmpty(activePeers) && ++tryTimes < 10) { - Thread.sleep(1000); - } - go = true; - } catch (Exception e) { - e.printStackTrace(); - } - } - - @AfterClass - public static void destroy() { - Args.clearParam(); - handshakeHandlerTest.close(); - context.destroy(); - appT.shutdownServices(); - appT.shutdown(); - FileUtil.deleteDir(new File(dbPath)); - } -} diff --git a/src/test/java/org/tron/core/net/node/override/HandshakeHandlerTest.java b/src/test/java/org/tron/core/net/node/override/HandshakeHandlerTest.java deleted file mode 100644 index c7c94350817..00000000000 --- a/src/test/java/org/tron/core/net/node/override/HandshakeHandlerTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.tron.core.net.node.override; - -import io.netty.channel.ChannelHandlerContext; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; -import org.tron.common.overlay.discover.node.Node; -import org.tron.common.overlay.message.HelloMessage; -import org.tron.common.overlay.server.HandshakeHandler; - -@Slf4j(topic = "test") -@Component -@Scope("prototype") -public class HandshakeHandlerTest extends HandshakeHandler { - - private Node node; - - public HandshakeHandlerTest() { - } - - public HandshakeHandlerTest setNode(Node node) { - this.node = node; - return this; - } - - @Override - protected void sendHelloMsg(ChannelHandlerContext ctx, long time) { - HelloMessage message = new HelloMessage(node, time, - manager.getGenesisBlockId(), manager.getSolidBlockId(), manager.getHeadBlockId()); - ctx.writeAndFlush(message.getSendData()); - channel.getNodeStatistics().messageStatistics.addTcpOutMessage(message); - logger.info("Handshake Send to {}, {}", ctx.channel().remoteAddress(), message); - } - - public void close() { - manager.closeAllStore(); - } -} diff --git a/src/test/java/org/tron/core/net/node/override/PeerClientTest.java b/src/test/java/org/tron/core/net/node/override/PeerClientTest.java deleted file mode 100644 index 3b32bf2eacf..00000000000 --- a/src/test/java/org/tron/core/net/node/override/PeerClientTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.tron.core.net.node.override; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelOption; -import io.netty.channel.DefaultMessageSizeEstimator; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.nio.NioSocketChannel; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; -import org.tron.core.config.args.Args; - -@Component -public class PeerClientTest { - - private static final Logger logger = LoggerFactory.getLogger("PeerClient"); - - @Autowired - private ApplicationContext ctx; - - @Autowired - @Lazy - private NodeImpl node; - - private EventLoopGroup workerGroup; - - private TronChannelInitializerTest tronChannelInitializer; - - public PeerClientTest() { - workerGroup = new NioEventLoopGroup(0, new ThreadFactory() { - AtomicInteger cnt = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "TronJClientWorker-test-" + cnt.getAndIncrement()); - } - }); - } - - public void prepare(String remoteId) { - tronChannelInitializer = ctx.getBean(TronChannelInitializerTest.class, remoteId); - tronChannelInitializer.setNodeImpl(node); - } - - public void connect(String host, int port, String remoteId) { - try { - ChannelFuture f = connectAsync(host, port, remoteId, false); - f.sync().channel().closeFuture().sync(); - } catch (Exception e) { - logger - .info("PeerClient: Can't connect to " + host + ":" + port + " (" + e.getMessage() + ")"); - } - } - - public ChannelFuture connectAsync(String host, int port, String remoteId, boolean discoveryMode) { - - logger.info("connect peer {} {} {}", host, port, remoteId); - - Bootstrap b = new Bootstrap(); - b.group(workerGroup); - b.channel(NioSocketChannel.class); - - b.option(ChannelOption.SO_KEEPALIVE, true); - b.option(ChannelOption.MESSAGE_SIZE_ESTIMATOR, DefaultMessageSizeEstimator.DEFAULT); - b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Args.getInstance().getNodeConnectionTimeout()); - b.remoteAddress(host, port); - - b.handler(tronChannelInitializer); - - // Start the client. - return b.connect(); - } - - public void close() { - tronChannelInitializer.close(); - workerGroup.shutdownGracefully(); - workerGroup.terminationFuture().syncUninterruptibly(); - } -} diff --git a/src/test/java/org/tron/core/net/node/override/TronChannelInitializerTest.java b/src/test/java/org/tron/core/net/node/override/TronChannelInitializerTest.java deleted file mode 100644 index 503eeca8728..00000000000 --- a/src/test/java/org/tron/core/net/node/override/TronChannelInitializerTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.tron.core.net.node.override; - -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.FixedRecvByteBufAllocator; -import io.netty.channel.socket.nio.NioSocketChannel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; -import org.tron.common.overlay.server.Channel; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.core.net.peer.PeerConnection; - -@Component -@Scope("prototype") -public class TronChannelInitializerTest extends ChannelInitializer { - - private static final Logger logger = LoggerFactory.getLogger("TronChannelInitializer"); - - @Autowired - private ApplicationContext ctx; - - @Autowired - ChannelManager channelManager; - - private NodeImpl p2pNode; - - private String remoteId; - - private boolean peerDiscoveryMode = false; - - private Channel channel; - - public TronChannelInitializerTest(String remoteId) { - this.remoteId = remoteId; - } - - public void prepare() { - channel = ctx.getBean(PeerConnection.class); - } - - @Override - public void initChannel(NioSocketChannel ch) throws Exception { - try { - channel.init(ch.pipeline(), remoteId, peerDiscoveryMode, channelManager, p2pNode); - - // limit the size of receiving buffer to 1024 - ch.config().setRecvByteBufAllocator(new FixedRecvByteBufAllocator(256 * 1024)); - ch.config().setOption(ChannelOption.SO_RCVBUF, 256 * 1024); - ch.config().setOption(ChannelOption.SO_BACKLOG, 1024); - - // be aware of channel closing - ch.closeFuture().addListener((ChannelFutureListener) future -> { - logger.info("Close channel:" + channel); - if (!peerDiscoveryMode) { - channelManager.notifyDisconnect(channel); - } - }); - - } catch (Exception e) { - logger.error("Unexpected error: ", e); - } - } - - private boolean isInbound() { - return remoteId == null || remoteId.isEmpty(); - } - - public void setPeerDiscoveryMode(boolean peerDiscoveryMode) { - this.peerDiscoveryMode = peerDiscoveryMode; - } - - public void setNodeImpl(NodeImpl p2pNode) { - this.p2pNode = p2pNode; - } - - public void close() { - channelManager.close(); - channel.close(); - } -} diff --git a/src/test/java/org/tron/core/services/NodeInfoServiceTest.java b/src/test/java/org/tron/core/services/NodeInfoServiceTest.java index 0efab5b0279..265f256265d 100644 --- a/src/test/java/org/tron/core/services/NodeInfoServiceTest.java +++ b/src/test/java/org/tron/core/services/NodeInfoServiceTest.java @@ -5,36 +5,28 @@ import io.grpc.ManagedChannelBuilder; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; -import org.junit.Test; import org.tron.api.GrpcAPI.EmptyMessage; import org.tron.api.WalletGrpc; import org.tron.api.WalletGrpc.WalletBlockingStub; +import org.tron.common.application.TronApplicationContext; import org.tron.common.entity.NodeInfo; import org.tron.common.utils.Sha256Hash; import org.tron.core.capsule.BlockCapsule; -import org.tron.core.net.node.BaseNetTest; import org.tron.program.Version; import stest.tron.wallet.common.client.Configuration; @Slf4j -public class NodeInfoServiceTest extends BaseNetTest { - - private static final String dbPath = "output-nodeImplTest-nodeinfo"; - private static final String dbDirectory = "db_nodeinfo_test"; - private static final String indexDirectory = "index_nodeinfo_test"; - private final static int port = 15899; +public class NodeInfoServiceTest { private NodeInfoService nodeInfoService; private WitnessProductBlockService witnessProductBlockService; - public NodeInfoServiceTest() { - super(dbPath, dbDirectory, indexDirectory, port); + public NodeInfoServiceTest(TronApplicationContext context) { + nodeInfoService = context.getBean("nodeInfoService", NodeInfoService.class); + witnessProductBlockService = context.getBean(WitnessProductBlockService.class); } - @Test public void test() { - nodeInfoService = context.getBean("nodeInfoService", NodeInfoService.class); - witnessProductBlockService = context.getBean(WitnessProductBlockService.class); BlockCapsule blockCapsule1 = new BlockCapsule(1, Sha256Hash.ZERO_HASH, 100, ByteString.EMPTY); BlockCapsule blockCapsule2 = new BlockCapsule(1, Sha256Hash.ZERO_HASH, @@ -57,8 +49,4 @@ public void testGrpc() { logger.info("getNodeInfo: {}",walletStub.getNodeInfo(EmptyMessage.getDefaultInstance())); } - public static void main(String[] args) { - NodeInfoServiceTest test = new NodeInfoServiceTest(); - test.testGrpc(); - } } diff --git a/src/test/java/org/tron/core/services/RpcApiServiceTest.java b/src/test/java/org/tron/core/services/RpcApiServiceTest.java deleted file mode 100644 index 0b95c342bf0..00000000000 --- a/src/test/java/org/tron/core/services/RpcApiServiceTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.tron.core.services; - -public class RpcApiServiceTest { - -} From b534b648abd030e909fdfe010542e0973eb32c38 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Wed, 27 Feb 2019 17:20:17 +0800 Subject: [PATCH 24/41] modify SyncService --- .../ChainInventoryMsgHandler.java | 5 ----- .../FetchInvDataMsgHandler.java | 2 -- .../messagehandler/InventoryMsgHandler.java | 4 +--- .../tron/core/net/peer/PeerStatusCheck.java | 22 ++++++++----------- .../org/tron/core/net/service/AdvService.java | 14 +++--------- .../tron/core/net/service/SyncService.java | 10 --------- 6 files changed, 13 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java index 40aa1203194..f205d75ae52 100644 --- a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -5,7 +5,6 @@ import java.util.Deque; import java.util.LinkedList; import java.util.List; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -15,7 +14,6 @@ import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.net.TronNetClient; import org.tron.core.net.TronProxy; import org.tron.core.net.message.ChainInventoryMessage; import org.tron.core.net.message.TronMessage; @@ -32,9 +30,6 @@ public class ChainInventoryMsgHandler implements TronMsgHandler { @Autowired private SyncService syncService; - @Setter - private TronNetClient tronManager; - @Override public void processMessage (PeerConnection peer, TronMessage msg) throws P2pException { diff --git a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index 28a2bf20719..94dae061da0 100644 --- a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -92,8 +92,6 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws P2pExce private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) throws P2pException{ MessageTypes type = fetchInvDataMsg.getInvMessageType(); - //todo check inv size not gt MAX_INV_FETCH_PER_PEER - if (type == MessageTypes.TRX) { int fetchCount = peer.getNodeStatistics().messageStatistics.tronInTrxFetchInvDataElement .getCount(10); diff --git a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index 5071ea618ac..69783974daa 100644 --- a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -39,9 +39,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) { for (Sha256Hash id : inventoryMessage.getHashList()) { Item item = new Item(id, type); peer.getAdvInvReceive().put(item, System.currentTimeMillis()); - if (!advService.addInv(item)) { - logger.info("This item {} from peer {} Already exist.", item, peer.getInetAddress()); - } + advService.addInv(item); } } diff --git a/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java b/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java index 6bf047338b0..fed2e4f2498 100644 --- a/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java +++ b/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java @@ -43,28 +43,24 @@ public void statusCheck() { tronProxy.getActivePeer().forEach(peer -> { - final boolean[] isDisconnected = {false}; + boolean isDisconnected = false; if (peer.isNeedSyncFromPeer() && peer.getBlockBothHaveUpdateTime() < now - blockUpdateTimeout){ logger.warn("Peer {} not sync for a long time.", peer.getInetAddress()); - isDisconnected[0] = true; + isDisconnected = true; } - if (!isDisconnected[0]) { - peer.getAdvInvRequest().values().stream() - .filter(time -> time < now - NetConstants.ADV_TIME_OUT) - .findFirst() - .ifPresent(time -> isDisconnected[0] = true); + if (!isDisconnected) { + isDisconnected = peer.getAdvInvRequest().values().stream() + .anyMatch(time -> time < now - NetConstants.ADV_TIME_OUT); } - if (!isDisconnected[0]) { - peer.getSyncBlockRequested().values().stream() - .filter(time -> time < now - NetConstants.SYNC_TIME_OUT) - .findFirst() - .ifPresent(time -> isDisconnected[0] = true); + if (!isDisconnected) { + isDisconnected = peer.getSyncBlockRequested().values().stream() + .anyMatch(time -> time < now - NetConstants.SYNC_TIME_OUT); } - if (isDisconnected[0]) { + if (isDisconnected) { peer.disconnect(ReasonCode.TIME_OUT); } }); diff --git a/src/main/java/org/tron/core/net/service/AdvService.java b/src/main/java/org/tron/core/net/service/AdvService.java index b0864bfe4a5..c940176abab 100644 --- a/src/main/java/org/tron/core/net/service/AdvService.java +++ b/src/main/java/org/tron/core/net/service/AdvService.java @@ -46,18 +46,10 @@ public class AdvService { private ConcurrentHashMap invToSpread = new ConcurrentHashMap<>(); private Cache invToFetchCache = CacheBuilder.newBuilder() - .maximumSize(500_000).expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); - - private Cache messageCache = CacheBuilder.newBuilder() .maximumSize(100_000).expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); -// private Cache trxCache = CacheBuilder.newBuilder() -// .maximumSize(50_000).expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(50_000) -// .recordStats().build(); -// -// private Cache blockCache = CacheBuilder.newBuilder() -// .maximumSize(10).expireAfterWrite(60, TimeUnit.SECONDS) -// .recordStats().build(); + private Cache messageCache = CacheBuilder.newBuilder() + .maximumSize(50_000).expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); private ScheduledExecutorService spreadExecutor = Executors.newSingleThreadScheduledExecutor(); @@ -141,7 +133,7 @@ public void onDisconnect (PeerConnection peer) { private void consumerInvToFetch() { Collection peers = tronProxy.getActivePeer().stream() - .filter(peer -> peer.isIdle() && !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) + .filter(peer -> peer.isIdle()) .collect(Collectors.toList()); if (invToFetch.isEmpty() || peers.isEmpty()) { diff --git a/src/main/java/org/tron/core/net/service/SyncService.java b/src/main/java/org/tron/core/net/service/SyncService.java index 5ac315651f7..1127141a134 100644 --- a/src/main/java/org/tron/core/net/service/SyncService.java +++ b/src/main/java/org/tron/core/net/service/SyncService.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -21,7 +20,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.overlay.server.Channel.TronState; -import org.tron.common.utils.Sha256Hash; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BlockCapsule.BlockId; import org.tron.core.config.Parameter.NodeConstant; @@ -194,7 +192,6 @@ private LinkedList getBlockChainSummary(PeerConnection peer) throws Exc private void startFetchSyncBlock() { HashMap> send = new HashMap<>(); -// HashSet request = new HashSet<>(); tronProxy.getActivePeer().stream() .filter(peer -> peer.isNeedSyncFromPeer() && peer.isIdle()) @@ -207,7 +204,6 @@ private void startFetchSyncBlock() { requestBlockIds.put(blockId, System.currentTimeMillis()); peer.getSyncBlockRequested().put(blockId, System.currentTimeMillis()); send.get(peer).add(blockId); -// request.add(blockId); if (send.get(peer).size() >= MAX_BLOCK_FETCH_PER_PEER) { break; } @@ -216,16 +212,10 @@ private void startFetchSyncBlock() { }); send.forEach((peer, blockIds) -> { -// blockIds.forEach(blockId -> { -// requestBlockIds.put(blockId, System.currentTimeMillis()); -// peer.getSyncBlockRequested().put(blockId, System.currentTimeMillis()); -// }); if (!blockIds.isEmpty()) { peer.sendMessage(new FetchInvDataMessage(new LinkedList<>(blockIds), InventoryType.BLOCK)); } }); - -// send.clear(); } private synchronized void handleSyncBlock() { From a2c1a891e8471706195f392f96d101d98554db11 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Thu, 7 Mar 2019 11:34:40 +0800 Subject: [PATCH 25/41] modify TronNetService --- .../java/org/tron/core/net/TronNetService.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index aafbb20d8e6..b5776deb9fe 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -13,9 +13,9 @@ import org.tron.core.net.messagehandler.InventoryMsgHandler; import org.tron.core.net.messagehandler.SyncBlockChainMsgHadler; import org.tron.core.net.messagehandler.TransactionsMsgHandler; -import org.tron.core.net.service.AdvService; import org.tron.core.net.peer.PeerConnection; import org.tron.core.net.peer.PeerStatusCheck; +import org.tron.core.net.service.AdvService; import org.tron.core.net.service.SyncService; import org.tron.protos.Protocol.ReasonCode; @@ -104,6 +104,7 @@ public void onMessage(PeerConnection peer, TronMessage msg) { private void processException (PeerConnection peer, TronMessage msg, Exception ex) { ReasonCode code = null; + boolean exceptionPrintFlag = false; if (ex instanceof P2pException) { TypeEnum type = ((P2pException) ex).getType(); switch (type) { @@ -112,6 +113,7 @@ private void processException (PeerConnection peer, TronMessage msg, Exception e break; case BAD_BLOCK: code = ReasonCode.BAD_BLOCK; + exceptionPrintFlag = true; break; case NO_SUCH_MESSAGE: case MESSAGE_WITH_WRONG_LENGTH: @@ -128,11 +130,17 @@ private void processException (PeerConnection peer, TronMessage msg, Exception e code = ReasonCode.UNKNOWN; break; } - logger.error("Process {} from peer {} failed, reason: ", peer.getInetAddress(), msg.getType(), type.getDesc(), ex); - }else { - logger.error("Process {} from peer {} failed.", peer.getInetAddress(), msg.getType(), ex); + } else { + exceptionPrintFlag = true; code = ReasonCode.UNKNOWN; } + + if (exceptionPrintFlag) { + logger.error("Message {} /n process failed from peer {}.", msg, peer.getInetAddress(), ex); + } else { + logger.error("Message {} /n process failed from peer {}, reason: {}.", msg, peer.getInetAddress(), ex.getMessage()); + } + peer.disconnect(code); } } From c431bc93781c4365b5207ae0fdafd562811a29b9 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 11 Mar 2019 11:42:59 +0800 Subject: [PATCH 26/41] modify log --- src/main/java/org/tron/common/overlay/server/Channel.java | 5 ++++- src/main/java/org/tron/core/net/peer/PeerConnection.java | 2 +- src/main/java/org/tron/core/net/service/SyncService.java | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/tron/common/overlay/server/Channel.java b/src/main/java/org/tron/common/overlay/server/Channel.java index f0a4ed6b996..54c31828540 100644 --- a/src/main/java/org/tron/common/overlay/server/Channel.java +++ b/src/main/java/org/tron/common/overlay/server/Channel.java @@ -151,7 +151,10 @@ public void disconnect(ReasonCode reason) { this.isDisconnect = true; channelManager.processDisconnect(this, reason); DisconnectMessage msg = new DisconnectMessage(reason); - logger.info("Send to {}, {}", ctx.channel().remoteAddress(), msg); + logger.info("Send to {} online-time {}s, {}", + ctx.channel().remoteAddress(), + (System.currentTimeMillis() - startTime) / 1000, + msg); getNodeStatistics().nodeDisconnectedLocal(reason); ctx.writeAndFlush(msg.getSendData()).addListener(future -> close()); } diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index 98336d49988..7d7aa339703 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -182,7 +182,7 @@ public String log () { //// return String.format( "Peer %s: [ %18s, ping %6s ms]-----------\n" - + "connect time: %d\n" + + "connect time: %ds\n" + "last know block num: %s\n" + "needSyncFromPeer:%b\n" + "needSyncFromUs:%b\n" diff --git a/src/main/java/org/tron/core/net/service/SyncService.java b/src/main/java/org/tron/core/net/service/SyncService.java index 1127141a134..6de369ba3ae 100644 --- a/src/main/java/org/tron/core/net/service/SyncService.java +++ b/src/main/java/org/tron/core/net/service/SyncService.java @@ -233,7 +233,6 @@ private synchronized void handleSyncBlock() { blockWaitToProcess.forEach((msg, peerConnection) -> { if (peerConnection.isDisconnect()) { - logger.warn("Peer {} is disconnect, drop block {}", peerConnection.getInetAddress(), msg.getBlockId().getString()); blockWaitToProcess.remove(msg); invalid(msg.getBlockId()); return; From dfca86465ffd406e4670f6f0a5955cd082d51c07 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 11 Mar 2019 12:22:53 +0800 Subject: [PATCH 27/41] modify tron class name --- .../tron/common/overlay/server/Channel.java | 10 +++--- src/main/java/org/tron/core/Wallet.java | 14 ++++---- src/main/java/org/tron/core/db/Manager.java | 3 ++ .../java/org/tron/core/net/TronNetClient.java | 18 ---------- .../{TronProxy.java => TronNetDelegate.java} | 2 +- .../{TronHandler.java => TronNetHandler.java} | 4 +-- .../org/tron/core/net/TronNetService.java | 9 +++-- .../net/messagehandler/BlockMsgHandler.java | 14 ++++---- .../ChainInventoryMsgHandler.java | 18 +++++----- .../FetchInvDataMsgHandler.java | 6 ++-- .../messagehandler/InventoryMsgHandler.java | 4 +-- .../SyncBlockChainMsgHadler.java | 33 ++++++------------- .../TransactionsMsgHandler.java | 6 ++-- .../tron/core/net/peer/PeerConnection.java | 6 ++-- .../tron/core/net/peer/PeerStatusCheck.java | 8 ++--- .../org/tron/core/net/service/AdvService.java | 10 +++--- .../tron/core/net/service/SyncService.java | 28 +++++++--------- .../tron/core/services/WitnessService.java | 8 ++--- src/test/java/org/tron/core/net/BaseNet.java | 15 +++------ src/test/java/org/tron/core/net/TcpTest.java | 11 +++---- 20 files changed, 95 insertions(+), 132 deletions(-) delete mode 100644 src/main/java/org/tron/core/net/TronNetClient.java rename src/main/java/org/tron/core/net/{TronProxy.java => TronNetDelegate.java} (99%) rename src/main/java/org/tron/core/net/{TronHandler.java => TronNetHandler.java} (90%) diff --git a/src/main/java/org/tron/common/overlay/server/Channel.java b/src/main/java/org/tron/common/overlay/server/Channel.java index 54c31828540..3689ea23d6f 100644 --- a/src/main/java/org/tron/common/overlay/server/Channel.java +++ b/src/main/java/org/tron/common/overlay/server/Channel.java @@ -39,7 +39,7 @@ import org.tron.common.overlay.message.StaticMessages; import org.tron.core.db.ByteArrayWrapper; import org.tron.core.exception.P2pException; -import org.tron.core.net.TronHandler; +import org.tron.core.net.TronNetHandler; import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") @@ -69,7 +69,7 @@ public class Channel { private P2pHandler p2pHandler; @Autowired - private TronHandler tronHandler; + private TronNetHandler tronNetHandler; private ChannelManager channelManager; @@ -119,10 +119,10 @@ public void init(ChannelPipeline pipeline, String remoteId, boolean discoveryMod msgQueue.setChannel(this); handshakeHandler.setChannel(this, remoteId); p2pHandler.setChannel(this); - tronHandler.setChannel(this); + tronNetHandler.setChannel(this); p2pHandler.setMsgQueue(msgQueue); - tronHandler.setMsgQueue(msgQueue); + tronNetHandler.setMsgQueue(msgQueue); } public void publicHandshakeFinished(ChannelHandlerContext ctx, HelloMessage msg) { @@ -131,7 +131,7 @@ public void publicHandshakeFinished(ChannelHandlerContext ctx, HelloMessage msg) msgQueue.activate(ctx); ctx.pipeline().addLast("messageCodec", messageCodec); ctx.pipeline().addLast("p2p", p2pHandler); - ctx.pipeline().addLast("data", tronHandler); + ctx.pipeline().addLast("data", tronNetHandler); setStartTime(msg.getTimestamp()); setTronState(TronState.HANDSHAKE_FINISHED); getNodeStatistics().p2pHandShake.add(); diff --git a/src/main/java/org/tron/core/Wallet.java b/src/main/java/org/tron/core/Wallet.java index 20a8733f598..b56f0772bd3 100755 --- a/src/main/java/org/tron/core/Wallet.java +++ b/src/main/java/org/tron/core/Wallet.java @@ -114,8 +114,8 @@ import org.tron.core.exception.TransactionExpirationException; import org.tron.core.exception.VMIllegalException; import org.tron.core.exception.ValidateSignatureException; -import org.tron.core.net.TronNetClient; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; +import org.tron.core.net.TronNetService; import org.tron.core.net.message.TransactionMessage; import org.tron.protos.Contract.AssetIssueContract; import org.tron.protos.Contract.CreateSmartContract; @@ -146,9 +146,9 @@ public class Wallet { @Getter private final ECKey ecKey; @Autowired - private TronNetClient tronNetClient; + private TronNetService tronNetService; @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; @Autowired private Manager dbManager; @Autowired @@ -418,14 +418,14 @@ public GrpcAPI.Return broadcastTransaction(Transaction signaturedTransaction) { try { if (minEffectiveConnection != 0) { - if (tronProxy.getActivePeer().isEmpty()) { + if (tronNetDelegate.getActivePeer().isEmpty()) { logger.warn("Broadcast transaction {} failed, no connection.", trx.getTransactionId()); return builder.setResult(false).setCode(response_code.NO_CONNECTION) .setMessage(ByteString.copyFromUtf8("no connection")) .build(); } - int count = (int) tronProxy.getActivePeer().stream() + int count = (int) tronNetDelegate.getActivePeer().stream() .filter(p -> !p.isNeedSyncFromUs() && !p.isNeedSyncFromPeer()) .count(); @@ -460,7 +460,7 @@ public GrpcAPI.Return broadcastTransaction(Transaction signaturedTransaction) { trx.resetResult(); } dbManager.pushTransaction(trx); - tronNetClient.broadcast(message); + tronNetService.broadcast(message); logger.info("Broadcast transaction {} successfully.", trx.getTransactionId()); return builder.setResult(true).setCode(response_code.SUCCESS).build(); } catch (ValidateSignatureException e) { diff --git a/src/main/java/org/tron/core/db/Manager.java b/src/main/java/org/tron/core/db/Manager.java index 9bbe176f3b4..cacbe7fb4a8 100644 --- a/src/main/java/org/tron/core/db/Manager.java +++ b/src/main/java/org/tron/core/db/Manager.java @@ -1269,6 +1269,9 @@ public boolean processTransaction(final TransactionCapsule trxCap, BlockCapsule if (isMultSignTransaction(trxCap.getInstance())) { ownerAddressSet.add(ByteArray.toHexString(TransactionCapsule.getOwner(contract))); } + + trxCap.setTrxTrace(null); + return true; } diff --git a/src/main/java/org/tron/core/net/TronNetClient.java b/src/main/java/org/tron/core/net/TronNetClient.java deleted file mode 100644 index f05098b6843..00000000000 --- a/src/main/java/org/tron/core/net/TronNetClient.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.tron.core.net; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.tron.common.overlay.message.Message; -import org.tron.core.net.service.AdvService; - -@Component -public class TronNetClient { - - @Autowired - private AdvService advService; - - public void broadcast(Message msg) { - advService.broadcast(msg); - } - -} diff --git a/src/main/java/org/tron/core/net/TronProxy.java b/src/main/java/org/tron/core/net/TronNetDelegate.java similarity index 99% rename from src/main/java/org/tron/core/net/TronProxy.java rename to src/main/java/org/tron/core/net/TronNetDelegate.java index 5ded824ba2e..ef621ce28ec 100644 --- a/src/main/java/org/tron/core/net/TronProxy.java +++ b/src/main/java/org/tron/core/net/TronNetDelegate.java @@ -45,7 +45,7 @@ @Slf4j @Component -public class TronProxy { +public class TronNetDelegate { @Autowired private SyncPool syncPool; diff --git a/src/main/java/org/tron/core/net/TronHandler.java b/src/main/java/org/tron/core/net/TronNetHandler.java similarity index 90% rename from src/main/java/org/tron/core/net/TronHandler.java rename to src/main/java/org/tron/core/net/TronNetHandler.java index f199081a4b4..87c23ba0b65 100644 --- a/src/main/java/org/tron/core/net/TronHandler.java +++ b/src/main/java/org/tron/core/net/TronNetHandler.java @@ -13,7 +13,7 @@ @Component @Scope("prototype") -public class TronHandler extends SimpleChannelInboundHandler { +public class TronNetHandler extends SimpleChannelInboundHandler { protected PeerConnection peer; @@ -23,7 +23,7 @@ public class TronHandler extends SimpleChannelInboundHandler { private TronNetService tronNetService; // @Autowired -// private TronHandler (final ApplicationContext ctx){ +// private TronNetHandler (final ApplicationContext ctx){ // tronNetService = ctx.getBean(TronNetService.class); // } diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index b5776deb9fe..5cbc32559cb 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -3,6 +3,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.overlay.message.Message; import org.tron.common.overlay.server.ChannelManager; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; @@ -72,7 +73,11 @@ public void close () { logger.info("TronNetService closed successfully."); } - public void onMessage(PeerConnection peer, TronMessage msg) { + public void broadcast(Message msg) { + advService.broadcast(msg); + } + + protected void onMessage(PeerConnection peer, TronMessage msg) { try { switch (msg.getType()) { case SYNC_BLOCK_CHAIN: @@ -102,9 +107,9 @@ public void onMessage(PeerConnection peer, TronMessage msg) { } private void processException (PeerConnection peer, TronMessage msg, Exception ex) { - ReasonCode code = null; boolean exceptionPrintFlag = false; + if (ex instanceof P2pException) { TypeEnum type = ((P2pException) ex).getType(); switch (type) { diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index f7a9c91ccff..5c0b800d0c3 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -10,8 +10,7 @@ import org.tron.core.capsule.BlockCapsule.BlockId; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.net.TronNetClient; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.Item; @@ -26,7 +25,7 @@ public class BlockMsgHandler implements TronMsgHandler { @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; @Autowired private TronNetClient tronManager; @@ -77,14 +76,15 @@ private void check (PeerConnection peer, BlockMessage msg) throws P2pException { private void processBlock(PeerConnection peer, BlockCapsule block) throws P2pException { BlockId blockId = block.getBlockId(); - if (!tronProxy.containBlock(block.getParentBlockId())) { - logger.warn("Get unlink block {} from {}, head is {}.", blockId.getString(), peer.getInetAddress(), tronProxy.getHeadBlockId().getString()); + if (!tronNetDelegate.containBlock(block.getParentBlockId())) { + logger.warn("Get unlink block {} from {}, head is {}.", blockId.getString(), peer.getInetAddress(), tronNetDelegate + .getHeadBlockId().getString()); syncService.startSync(peer); return; } - tronProxy.processBlock(block); + tronNetDelegate.processBlock(block); witnessProductBlockService.validWitnessProductTwoBlock(block); - tronProxy.getActivePeer().forEach(p -> { + tronNetDelegate.getActivePeer().forEach(p -> { if (p.getAdvInvReceive().getIfPresent(blockId) != null) { p.setBlockBothHave(blockId); } diff --git a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java index f205d75ae52..1e82f2160df 100644 --- a/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -14,7 +14,7 @@ import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.ChainInventoryMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.PeerConnection; @@ -25,7 +25,7 @@ public class ChainInventoryMsgHandler implements TronMsgHandler { @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; @Autowired private SyncService syncService; @@ -43,7 +43,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws P2pExce Deque blockIdWeGet = new LinkedList<>(chainInventoryMessage.getBlockIds()); - if (blockIdWeGet.size() == 1 && tronProxy.containBlock(blockIdWeGet.peek())) { + if (blockIdWeGet.size() == 1 && tronNetDelegate.containBlock(blockIdWeGet.peek())) { peer.setNeedSyncFromPeer(false); return; } @@ -60,8 +60,9 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws P2pExce peer.setRemainNum(chainInventoryMessage.getRemainNum()); peer.getSyncBlockToFetch().addAll(blockIdWeGet); - synchronized (tronProxy.getBlockLock()) { - while (!peer.getSyncBlockToFetch().isEmpty() && tronProxy.containBlock(peer.getSyncBlockToFetch().peek())) { + synchronized (tronNetDelegate.getBlockLock()) { + while (!peer.getSyncBlockToFetch().isEmpty() && tronNetDelegate + .containBlock(peer.getSyncBlockToFetch().peek())) { BlockId blockId = peer.getSyncBlockToFetch().pop(); logger.info("Block {} from {} is processed", blockId.getString(), peer.getNode().getHost()); } @@ -111,9 +112,10 @@ private void check(PeerConnection peer, ChainInventoryMessage msg) throws P2pExc + ", peer: " + blockIds.get(0).getString()); } - if (tronProxy.getHeadBlockId().getNum() > 0) { - long maxRemainTime = ChainConstant.CLOCK_MAX_DELAY + System.currentTimeMillis() - tronProxy.getBlockTime(tronProxy.getSolidBlockId()); - long maxFutureNum = maxRemainTime / BLOCK_PRODUCED_INTERVAL + tronProxy.getSolidBlockId().getNum(); + if (tronNetDelegate.getHeadBlockId().getNum() > 0) { + long maxRemainTime = ChainConstant.CLOCK_MAX_DELAY + System.currentTimeMillis() - tronNetDelegate + .getBlockTime(tronNetDelegate.getSolidBlockId()); + long maxFutureNum = maxRemainTime / BLOCK_PRODUCED_INTERVAL + tronNetDelegate.getSolidBlockId().getNum(); long lastNum = blockIds.get(blockIds.size() - 1).getNum(); if (lastNum + msg.getRemainNum() > maxFutureNum) { throw new P2pException(TypeEnum.BAD_MESSAGE, "lastNum: " + lastNum + " + remainNum: " diff --git a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index 94dae061da0..ed516cdd458 100644 --- a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -13,7 +13,7 @@ import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.FetchInvDataMessage; import org.tron.core.net.message.MessageTypes; @@ -33,7 +33,7 @@ public class FetchInvDataMsgHandler implements TronMsgHandler { @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; @Autowired private SyncService syncService; @@ -60,7 +60,7 @@ public void processMessage (PeerConnection peer, TronMessage msg) throws P2pExce Message message = advService.getMessage(item); if (message == null) { try { - message = tronProxy.getData(hash, type); + message = tronNetDelegate.getData(hash, type); } catch (Exception e) { logger.error("Fetch item {} failed. reason: {}", item, hash, e.getMessage()); peer.disconnect(ReasonCode.FETCH_FAIL); diff --git a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index 69783974daa..c4fc17e20a4 100644 --- a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -4,7 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.utils.Sha256Hash; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.InventoryMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.Item; @@ -17,7 +17,7 @@ public class InventoryMsgHandler implements TronMsgHandler{ @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; @Autowired private AdvService advService; diff --git a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java index c892c7d2daa..28bc66c8520 100644 --- a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java +++ b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java @@ -1,40 +1,27 @@ package org.tron.core.net.messagehandler; -import com.google.common.collect.Iterables; -import com.google.common.primitives.Longs; -import java.util.Arrays; -import java.util.Collections; import java.util.LinkedList; import java.util.List; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; -import org.spongycastle.util.encoders.Hex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.overlay.discover.node.statistics.MessageCount; -import org.tron.common.overlay.server.Channel.TronState; -import org.tron.common.utils.Sha256Hash; import org.tron.core.capsule.BlockCapsule.BlockId; -import org.tron.core.config.Parameter.ChainConstant; import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.exception.StoreException; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.ChainInventoryMessage; -import org.tron.core.net.message.FetchInvDataMessage; -import org.tron.core.net.message.MessageTypes; import org.tron.core.net.message.SyncBlockChainMessage; import org.tron.core.net.message.TronMessage; import org.tron.core.net.peer.PeerConnection; -import org.tron.protos.Protocol.ReasonCode; @Slf4j @Component public class SyncBlockChainMsgHadler implements TronMsgHandler { @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; @Override public void processMessage(PeerConnection peer, TronMessage msg) throws P2pException { @@ -53,12 +40,12 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws P2pExcep peer.setNeedSyncFromUs(false); }else { peer.setNeedSyncFromUs(true); - remainNum = tronProxy.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); + remainNum = tronNetDelegate.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); } // // if (!peer.isNeedSyncFromPeer() -// && !tronProxy.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) -// && tronProxy.canChainRevoke(summaryChainIds.get(0).getNum())) { +// && !tronNetDelegate.contain(Iterables.getLast(summaryChainIds), MessageTypes.BLOCK) +// && tronNetDelegate.canChainRevoke(summaryChainIds.get(0).getNum())) { // //startSyncWithPeer(peer); // } @@ -74,11 +61,11 @@ private void check(PeerConnection peer, SyncBlockChainMessage msg) throws P2pExc } BlockId firstId = blockIds.get(0); - if (!tronProxy.containBlockInMainChain(firstId)){ + if (!tronNetDelegate.containBlockInMainChain(firstId)){ throw new P2pException(TypeEnum.BAD_MESSAGE, "No first block:" + firstId.getString()); } - long headNum = tronProxy.getHeadBlockId().getNum(); + long headNum = tronNetDelegate.getHeadBlockId().getNum(); if (firstId.getNum() > headNum){ throw new P2pException(TypeEnum.BAD_MESSAGE, "First blockNum:" + firstId.getNum() +" gt my head BlockNum:" + headNum); } @@ -94,17 +81,17 @@ private LinkedList getLostBlockIds(List blockIds) throws P2pEx BlockId unForkId = null; for (int i = blockIds.size() - 1; i >= 0; i--){ - if (tronProxy.containBlockInMainChain(blockIds.get(i))){ + if (tronNetDelegate.containBlockInMainChain(blockIds.get(i))){ unForkId = blockIds.get(i); break; } } - long len = Math.min(tronProxy.getHeadBlockId().getNum(), unForkId.getNum() + NodeConstant.SYNC_FETCH_BATCH_NUM); + long len = Math.min(tronNetDelegate.getHeadBlockId().getNum(), unForkId.getNum() + NodeConstant.SYNC_FETCH_BATCH_NUM); LinkedList ids = new LinkedList<>(); for (long i = unForkId.getNum(); i <= len; i++) { - BlockId id = tronProxy.getBlockIdByNum(i); + BlockId id = tronNetDelegate.getBlockIdByNum(i); ids.add(id); } return ids; diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index 8c8a04171bc..9bcc7d81cf5 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -14,7 +14,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.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.TransactionMessage; import org.tron.core.net.message.TransactionsMessage; import org.tron.core.net.message.TronMessage; @@ -31,7 +31,7 @@ public class TransactionsMsgHandler implements TronMsgHandler { @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; @Autowired private AdvService advService; @@ -129,7 +129,7 @@ private void handleTransaction (PeerConnection peer, TransactionMessage trx) { return; } try { - tronProxy.pushTransaction(trx.getTransactionCapsule()); + tronNetDelegate.pushTransaction(trx.getTransactionCapsule()); advService.broadcast(trx); }catch (P2pException e) { logger.warn("Trx {} from peer {} process failed. type: {}, reason: {}", diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index 7d7aa339703..035d4b4fd91 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -24,7 +24,7 @@ import org.tron.common.utils.Sha256Hash; import org.tron.core.capsule.BlockCapsule.BlockId; import org.tron.core.config.Parameter.NodeConstant; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.service.AdvService; import org.tron.core.net.service.SyncService; @@ -34,7 +34,7 @@ public class PeerConnection extends Channel { @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; @Autowired private SyncService syncService; @@ -131,7 +131,7 @@ public void sendMessage(Message message) { } public void onConnectPeer() { - if (getHelloMessage().getHeadBlockId().getNum() > tronProxy.getHeadBlockId().getNum()) { + if (getHelloMessage().getHeadBlockId().getNum() > tronNetDelegate.getHeadBlockId().getNum()) { setTronState(TronState.SYNCING); syncService.startSync(this); } else { diff --git a/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java b/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java index fed2e4f2498..103dadabf94 100644 --- a/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java +++ b/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java @@ -1,7 +1,5 @@ package org.tron.core.net.peer; -import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; - import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -9,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.core.config.Parameter.NetConstants; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.protos.Protocol.ReasonCode; @Slf4j @@ -17,7 +15,7 @@ public class PeerStatusCheck { @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; private ScheduledExecutorService peerStatusCheckExecutor = Executors.newSingleThreadScheduledExecutor(); @@ -41,7 +39,7 @@ public void statusCheck() { long now = System.currentTimeMillis(); - tronProxy.getActivePeer().forEach(peer -> { + tronNetDelegate.getActivePeer().forEach(peer -> { boolean isDisconnected = false; diff --git a/src/main/java/org/tron/core/net/service/AdvService.java b/src/main/java/org/tron/core/net/service/AdvService.java index c940176abab..5d7c0217608 100644 --- a/src/main/java/org/tron/core/net/service/AdvService.java +++ b/src/main/java/org/tron/core/net/service/AdvService.java @@ -25,7 +25,7 @@ import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.Time; import org.tron.core.capsule.BlockCapsule.BlockId; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.FetchInvDataMessage; import org.tron.core.net.message.InventoryMessage; @@ -39,7 +39,7 @@ public class AdvService { @Autowired - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; private ConcurrentHashMap invToFetch = new ConcurrentHashMap<>(); @@ -123,7 +123,7 @@ public void broadcast(Message msg) { public void onDisconnect (PeerConnection peer) { if (!peer.getAdvInvRequest().isEmpty()) { peer.getAdvInvRequest().keySet().forEach(item -> { - if (tronProxy.getActivePeer().stream() + if (tronNetDelegate.getActivePeer().stream() .anyMatch(p -> !p.equals(peer) && p.getAdvInvReceive().getIfPresent(item) != null)){ invToFetch.put(item, System.currentTimeMillis()); } @@ -132,7 +132,7 @@ public void onDisconnect (PeerConnection peer) { } private void consumerInvToFetch() { - Collection peers = tronProxy.getActivePeer().stream() + Collection peers = tronNetDelegate.getActivePeer().stream() .filter(peer -> peer.isIdle()) .collect(Collectors.toList()); @@ -173,7 +173,7 @@ private void consumerInvToSpread() { invToSpread.clear(); } - tronProxy.getActivePeer().stream() + tronNetDelegate.getActivePeer().stream() .filter(peer -> !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) .forEach(peer -> spread.entrySet().stream() .filter(entry -> peer.getAdvInvReceive().getIfPresent(entry.getKey()) == null && peer.getAdvInvSpread().getIfPresent(entry.getKey()) == null) diff --git a/src/main/java/org/tron/core/net/service/SyncService.java b/src/main/java/org/tron/core/net/service/SyncService.java index 6de369ba3ae..85c7a321716 100644 --- a/src/main/java/org/tron/core/net/service/SyncService.java +++ b/src/main/java/org/tron/core/net/service/SyncService.java @@ -25,8 +25,7 @@ import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; -import org.tron.core.net.TronNetClient; -import org.tron.core.net.TronProxy; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.FetchInvDataMessage; import org.tron.core.net.message.SyncBlockChainMessage; @@ -39,10 +38,7 @@ public class SyncService { @Autowired - private TronProxy tronProxy; - - @Autowired - private TronNetClient tronManager; + private TronNetDelegate tronNetDelegate; private Map blockWaitToProcess = new ConcurrentHashMap<>(); @@ -95,7 +91,7 @@ public void startSync(PeerConnection peer) { peer.setNeedSyncFromPeer(true); peer.getSyncBlockToFetch().clear(); peer.setRemainNum(0); - peer.setBlockBothHave(tronProxy.getGenesisBlockId()); + peer.setBlockBothHave(tronNetDelegate.getGenesisBlockId()); syncNext(peer); } @@ -145,18 +141,18 @@ private LinkedList getBlockChainSummary(PeerConnection peer) throws Exc List blockIds = new ArrayList<>(peer.getSyncBlockToFetch()); LinkedList forkList = new LinkedList<>(); LinkedList summary = new LinkedList<>(); - long syncBeginNumber = tronProxy.getSyncBeginNumber(); + long syncBeginNumber = tronNetDelegate.getSyncBeginNumber(); long low = syncBeginNumber < 0 ? 0 : syncBeginNumber; long highNoFork; long high; if (beginBlockId.getNum() == 0){ - highNoFork = high = tronProxy.getHeadBlockId().getNum(); + highNoFork = high = tronNetDelegate.getHeadBlockId().getNum(); }else { - if (tronProxy.containBlockInMainChain(beginBlockId)) { + if (tronNetDelegate.containBlockInMainChain(beginBlockId)) { highNoFork = high = beginBlockId.getNum(); } else { - forkList = tronProxy.getBlockChainHashesOnFork(beginBlockId); + forkList = tronNetDelegate.getBlockChainHashesOnFork(beginBlockId); if (forkList.isEmpty()) { throw new P2pException(TypeEnum.SYNC_FAILED, "can't find blockId: " + beginBlockId.getString()); } @@ -178,7 +174,7 @@ private LinkedList getBlockChainSummary(PeerConnection peer) throws Exc while (low <= realHigh) { if (low <= highNoFork) { - summary.offer(tronProxy.getBlockIdByNum(low)); + summary.offer(tronNetDelegate.getBlockIdByNum(low)); } else if (low <= high) { summary.offer(forkList.get((int) (low - highNoFork - 1))); } else { @@ -193,7 +189,7 @@ private LinkedList getBlockChainSummary(PeerConnection peer) throws Exc private void startFetchSyncBlock() { HashMap> send = new HashMap<>(); - tronProxy.getActivePeer().stream() + tronNetDelegate.getActivePeer().stream() .filter(peer -> peer.isNeedSyncFromPeer() && peer.isIdle()) .forEach(peer -> { if (!send.containsKey(peer)) { @@ -238,7 +234,7 @@ private synchronized void handleSyncBlock() { return; } final boolean[] isFound = {false}; - tronProxy.getActivePeer().stream() + tronNetDelegate.getActivePeer().stream() .filter(peer -> msg.getBlockId().equals(peer.getSyncBlockToFetch().peek())) .forEach(peer -> { peer.getSyncBlockToFetch().pop(); @@ -258,12 +254,12 @@ private void processSyncBlock (BlockCapsule block) { boolean flag = true; BlockId blockId = block.getBlockId(); try { - tronProxy.processBlock(block); + tronNetDelegate.processBlock(block); } catch (Exception e) { logger.error("Process sync block {} failed.", blockId.getString(), e); flag = false; } - for (PeerConnection peer: tronProxy.getActivePeer()) { + for (PeerConnection peer: tronNetDelegate.getActivePeer()) { if (peer.getSyncBlockInProcess().remove(blockId)) { if (flag){ peer.setBlockBothHave(blockId); diff --git a/src/main/java/org/tron/core/services/WitnessService.java b/src/main/java/org/tron/core/services/WitnessService.java index 5b0edcb179f..9d762cb4d26 100755 --- a/src/main/java/org/tron/core/services/WitnessService.java +++ b/src/main/java/org/tron/core/services/WitnessService.java @@ -34,7 +34,7 @@ import org.tron.core.exception.UnLinkedBlockException; import org.tron.core.exception.ValidateScheduleException; import org.tron.core.exception.ValidateSignatureException; -import org.tron.core.net.TronNetClient; +import org.tron.core.net.TronNetService; import org.tron.core.net.message.BlockMessage; import org.tron.core.witness.BlockProductionCondition; import org.tron.core.witness.WitnessController; @@ -68,7 +68,7 @@ public class WitnessService implements Service { private BackupServer backupServer; - private TronNetClient tronNetClient; + private TronNetService tronNetService; private AtomicInteger dupBlockCount = new AtomicInteger(0); private AtomicLong dupBlockTime = new AtomicLong(0); @@ -83,7 +83,7 @@ public WitnessService(Application tronApp, TronApplicationContext context) { this.context = context; backupManager = context.getBean(BackupManager.class); backupServer = context.getBean(BackupServer.class); - tronNetClient = context.getBean(TronNetClient.class); + tronNetService = context.getBean(TronNetService.class); generateThread = new Thread(scheduleProductionLoop); manager = tronApp.getDbManager(); manager.setWitnessService(this); @@ -310,7 +310,7 @@ public boolean validateWitnessPermission(ByteString scheduledWitness) { private void broadcastBlock(BlockCapsule block) { try { - tronNetClient.broadcast(new BlockMessage(block.getData())); + tronNetService.broadcast(new BlockMessage(block.getData())); } catch (Exception ex) { throw new RuntimeException("BroadcastBlock error"); } diff --git a/src/test/java/org/tron/core/net/BaseNet.java b/src/test/java/org/tron/core/net/BaseNet.java index d09fdbcff18..1ff00528b7c 100644 --- a/src/test/java/org/tron/core/net/BaseNet.java +++ b/src/test/java/org/tron/core/net/BaseNet.java @@ -21,22 +21,15 @@ import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; -import org.tron.common.overlay.client.PeerClient; -import org.tron.common.overlay.server.ChannelManager; -import org.tron.common.overlay.server.SyncPool; import org.tron.common.utils.FileUtil; import org.tron.common.utils.ReflectUtils; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; -import org.tron.core.db.Manager; -import org.tron.core.net.TronProxy; import org.tron.core.net.peer.PeerConnection; import org.tron.core.services.RpcApiService; -import org.tron.core.services.WitnessService; @Slf4j public abstract class BaseNet { @@ -50,7 +43,7 @@ public abstract class BaseNet { private RpcApiService rpcApiService; private Application appT; - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; private ExecutorService executorService = Executors.newFixedThreadPool(1); @@ -79,12 +72,12 @@ public void run() { appT.initServices(cfgArgs); appT.startServices(); appT.startup(); - tronProxy = context.getBean(TronProxy.class); + tronNetDelegate = context.getBean(TronNetDelegate.class); rpcApiService.blockUntilShutdown(); } }); int tryTimes = 0; - while (++tryTimes < 100 && tronProxy == null) { + while (++tryTimes < 100 && tronNetDelegate == null) { Thread.sleep(3000); } } @@ -115,7 +108,7 @@ protected void initChannel(Channel ch) throws Exception { @After public void destroy() { - Collection peerConnections = ReflectUtils.invokeMethod(tronProxy, "getActivePeer"); + Collection peerConnections = ReflectUtils.invokeMethod(tronNetDelegate, "getActivePeer"); for (PeerConnection peer : peerConnections) { peer.close(); } diff --git a/src/test/java/org/tron/core/net/TcpTest.java b/src/test/java/org/tron/core/net/TcpTest.java index 50aa9ae17a4..7a042495439 100644 --- a/src/test/java/org/tron/core/net/TcpTest.java +++ b/src/test/java/org/tron/core/net/TcpTest.java @@ -14,11 +14,8 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; @@ -47,7 +44,7 @@ public class TcpTest { private ChannelManager channelManager; private Manager manager; private SyncPool pool; - private TronProxy tronProxy; + private TronNetDelegate tronNetDelegate; private int tryTimes = 10; private int sleepTime = 1000; @@ -59,7 +56,7 @@ public TcpTest(TronApplicationContext context) { channelManager = context.getBean(ChannelManager.class); manager = context.getBean(Manager.class); pool = context.getBean(SyncPool.class); - tronProxy = context.getBean(TronProxy.class); + tronNetDelegate = context.getBean(TronNetDelegate.class); } private enum TestType { @@ -214,7 +211,7 @@ private void validResultCloseConnect(Channel channel) throws InterruptedExceptio finish = false; channel.close(); Thread.sleep(sleepTime); - Collection peerConnections = ReflectUtils.invokeMethod(tronProxy, "getActivePeer"); + Collection peerConnections = ReflectUtils.invokeMethod(tronNetDelegate, "getActivePeer"); for (PeerConnection peer : peerConnections) { peer.close(); } @@ -234,7 +231,7 @@ private void validResultUnCloseConnect() throws InterruptedException { private void clearConnect(Channel channel) throws InterruptedException { channel.close(); Thread.sleep(sleepTime); - Collection peerConnections = ReflectUtils.invokeMethod(tronProxy, "getActivePeer"); + Collection peerConnections = ReflectUtils.invokeMethod(tronNetDelegate, "getActivePeer"); for (PeerConnection peer : peerConnections) { peer.close(); } From f36134e74bb685eb9ee5097e1d69b78a627b14d5 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 12 Mar 2019 12:26:40 +0800 Subject: [PATCH 28/41] add unit test --- .../java/org/tron/core/config/Parameter.java | 2 +- .../org/tron/core/net/TronNetService.java | 6 +- .../net/messagehandler/BlockMsgHandler.java | 3 - ...ler.java => SyncBlockChainMsgHandler.java} | 2 +- src/test/java/org/tron/core/net/UdpTest.java | 26 +++++++- .../messagehandler/BlockMsgHandlerTest.java | 62 +++++++++++++++++++ .../ChainInventoryMsgHandlerTest.java | 4 +- .../SyncBlockChainMsgHandlerTest.java | 23 +++++++ .../core/net/services/AdvServiceTest.java | 34 ++++++++++ 9 files changed, 150 insertions(+), 12 deletions(-) rename src/main/java/org/tron/core/net/messagehandler/{SyncBlockChainMsgHadler.java => SyncBlockChainMsgHandler.java} (98%) create mode 100644 src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java create mode 100644 src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java create mode 100644 src/test/java/org/tron/core/net/services/AdvServiceTest.java diff --git a/src/main/java/org/tron/core/config/Parameter.java b/src/main/java/org/tron/core/config/Parameter.java index f3358700d40..5d3e52533be 100644 --- a/src/main/java/org/tron/core/config/Parameter.java +++ b/src/main/java/org/tron/core/config/Parameter.java @@ -43,7 +43,7 @@ interface NetConstants { long GRPC_IDLE_TIME_OUT = 60000L; long ADV_TIME_OUT = 20000L; - long SYNC_TIME_OUT = 5000L; + long SYNC_TIME_OUT = 20000L; long HEAD_NUM_MAX_DELTA = 1000L; long HEAD_NUM_CHECK_TIME = 60000L; int MAX_INVENTORY_SIZE_IN_MINUTES = 2; diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index 5cbc32559cb..493ce4f390c 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -12,7 +12,7 @@ import org.tron.core.net.messagehandler.ChainInventoryMsgHandler; import org.tron.core.net.messagehandler.FetchInvDataMsgHandler; import org.tron.core.net.messagehandler.InventoryMsgHandler; -import org.tron.core.net.messagehandler.SyncBlockChainMsgHadler; +import org.tron.core.net.messagehandler.SyncBlockChainMsgHandler; import org.tron.core.net.messagehandler.TransactionsMsgHandler; import org.tron.core.net.peer.PeerConnection; import org.tron.core.net.peer.PeerStatusCheck; @@ -37,7 +37,7 @@ public class TronNetService { private PeerStatusCheck peerStatusCheck; @Autowired - private SyncBlockChainMsgHadler syncBlockChainMsgHadler; + private SyncBlockChainMsgHandler syncBlockChainMsgHandler; @Autowired private ChainInventoryMsgHandler chainInventoryMsgHandler; @@ -81,7 +81,7 @@ protected void onMessage(PeerConnection peer, TronMessage msg) { try { switch (msg.getType()) { case SYNC_BLOCK_CHAIN: - syncBlockChainMsgHadler.processMessage(peer, msg); + syncBlockChainMsgHandler.processMessage(peer, msg); break; case BLOCK_CHAIN_INVENTORY: chainInventoryMsgHandler.processMessage(peer, msg); diff --git a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 5c0b800d0c3..f1bef4e6d90 100644 --- a/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -27,9 +27,6 @@ public class BlockMsgHandler implements TronMsgHandler { @Autowired private TronNetDelegate tronNetDelegate; - @Autowired - private TronNetClient tronManager; - @Autowired private AdvService advService; diff --git a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java similarity index 98% rename from src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java rename to src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java index 28bc66c8520..ff9a85efe1b 100644 --- a/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHadler.java +++ b/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java @@ -18,7 +18,7 @@ @Slf4j @Component -public class SyncBlockChainMsgHadler implements TronMsgHandler { +public class SyncBlockChainMsgHandler implements TronMsgHandler { @Autowired private TronNetDelegate tronNetDelegate; diff --git a/src/test/java/org/tron/core/net/UdpTest.java b/src/test/java/org/tron/core/net/UdpTest.java index bc7b78f81ea..af01e17ad53 100644 --- a/src/test/java/org/tron/core/net/UdpTest.java +++ b/src/test/java/org/tron/core/net/UdpTest.java @@ -32,12 +32,34 @@ public class UdpTest { private NodeManager nodeManager; private int port = Args.getInstance().getNodeListenPort(); + private volatile boolean finishFlag = false; + private long timeOut = 30_000; public UdpTest(TronApplicationContext context) { nodeManager = context.getBean(NodeManager.class); } public void test() throws Exception { + Thread thread = new Thread(() -> { + try { + discover(); + } catch (Exception e) { + logger.info("Discover test failed.", e); + } + }); + thread.start(); + + long time = System.currentTimeMillis(); + while (!finishFlag && System.currentTimeMillis() - time < timeOut) { + Thread.sleep(1000); + } + if (!finishFlag) { + thread.interrupt(); + Assert.assertTrue(false); + } + } + + public void discover() throws Exception { InetAddress server = InetAddress.getByName("127.0.0.1"); @@ -82,9 +104,7 @@ public void test() throws Exception { boolean findNodeFlag = false; boolean neighborsFlag = false; while (true) { - System.out.println("pingFlag:" + pingFlag + "pongFlag:" + pongFlag + "findNodeFlag:" + findNodeFlag + "neighborsFlag:" + neighborsFlag ); socket.receive(packet); - System.out.println("wwww"); byte[] bytes = Arrays.copyOfRange(data, 0, packet.getLength()); Message msg = Message.parse(bytes); Assert.assertTrue(Arrays.equals(msg.getFrom().getId(), nodeManager.getPublicHomeNode().getId())); @@ -112,6 +132,8 @@ public void test() throws Exception { Assert.assertTrue(nodeManager.getTable().getAllNodes().size() == 1); socket.close(); + + finishFlag = true; } } diff --git a/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java b/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java new file mode 100644 index 00000000000..7004b847c49 --- /dev/null +++ b/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java @@ -0,0 +1,62 @@ +package org.tron.core.net.messagehandler; + +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.testng.collections.Lists; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.exception.P2pException; +import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.peer.Item; +import org.tron.core.net.peer.PeerConnection; +import org.tron.protos.Protocol.Inventory.InventoryType; +import org.tron.protos.Protocol.Transaction; + +public class BlockMsgHandlerTest { + + BlockMsgHandler handler = new BlockMsgHandler(); + PeerConnection peer = new PeerConnection(); + BlockCapsule blockCapsule; + BlockMessage msg; + + @Test + public void testProcessMessage() { + try { + blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, + System.currentTimeMillis(), Sha256Hash.ZERO_HASH.getByteString()); + msg = new BlockMessage(blockCapsule); + handler.processMessage(peer, new BlockMessage(blockCapsule)); + }catch (P2pException e) { + Assert.assertTrue(e.getMessage().equals("no request")); + } + + try { + List transactionList = Lists.newArrayList(); + for (int i = 0; i < 1100000; i++) { + transactionList.add(Transaction.newBuilder().build()); + } + blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH.getByteString(), + System.currentTimeMillis() + 10000,transactionList); + msg = new BlockMessage(blockCapsule); + System.out.println("len = " + blockCapsule.getInstance().getSerializedSize()); + peer.getAdvInvRequest().put(new Item(msg.getBlockId(), InventoryType.BLOCK), System.currentTimeMillis()); + handler.processMessage(peer, msg); + }catch (P2pException e) { + System.out.println(e); + Assert.assertTrue(e.getMessage().equals("block size over limit")); + } + + try { + blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, + System.currentTimeMillis() + 10000, Sha256Hash.ZERO_HASH.getByteString()); + msg = new BlockMessage(blockCapsule); + peer.getAdvInvRequest().put(new Item(msg.getBlockId(), InventoryType.BLOCK), System.currentTimeMillis()); + handler.processMessage(peer, msg); + }catch (P2pException e) { + System.out.println(e); + Assert.assertTrue(e.getMessage().equals("block time error")); + } + } + +} diff --git a/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java b/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java index 135f49749d6..d7ffc6be92f 100644 --- a/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java +++ b/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java @@ -15,12 +15,12 @@ public class ChainInventoryMsgHandlerTest { ChainInventoryMsgHandler handler = new ChainInventoryMsgHandler(); + PeerConnection peer = new PeerConnection(); ChainInventoryMessage msg = new ChainInventoryMessage(new ArrayList<>(), 0l); List blockIds = new ArrayList<>(); - PeerConnection peer = new PeerConnection(); @Test - public void test() { + public void testProcessMessage() { try { handler.processMessage(peer, msg); }catch (P2pException e) { diff --git a/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java b/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java new file mode 100644 index 00000000000..03739f82fdc --- /dev/null +++ b/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java @@ -0,0 +1,23 @@ +package org.tron.core.net.messagehandler; + +import java.util.ArrayList; +import org.junit.Assert; +import org.junit.Test; +import org.tron.core.exception.P2pException; +import org.tron.core.net.message.SyncBlockChainMessage; +import org.tron.core.net.peer.PeerConnection; + +public class SyncBlockChainMsgHandlerTest { + SyncBlockChainMsgHandler handler = new SyncBlockChainMsgHandler(); + PeerConnection peer = new PeerConnection(); + + @Test + public void testProcessMessage() { + try { + handler.processMessage(peer, new SyncBlockChainMessage(new ArrayList<>())); + }catch (P2pException e) { + Assert.assertTrue(e.getMessage().equals("SyncBlockChain blockIds is empty")); + } + } + +} diff --git a/src/test/java/org/tron/core/net/services/AdvServiceTest.java b/src/test/java/org/tron/core/net/services/AdvServiceTest.java new file mode 100644 index 00000000000..650f1701f96 --- /dev/null +++ b/src/test/java/org/tron/core/net/services/AdvServiceTest.java @@ -0,0 +1,34 @@ +package org.tron.core.net.services; + +import org.junit.Assert; +import org.junit.Test; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.peer.Item; +import org.tron.core.net.service.AdvService; +import org.tron.protos.Protocol.Inventory.InventoryType; + +public class AdvServiceTest { + AdvService service = new AdvService(); + + @Test + public void testAddInv () { + boolean flag; + Item item = new Item(Sha256Hash.ZERO_HASH, InventoryType.BLOCK); + flag = service.addInv(item); + Assert.assertTrue(flag); + flag = service.addInv(item); + Assert.assertTrue(!flag); + } + + @Test + public void testBroadcast () { + BlockCapsule blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, + System.currentTimeMillis(), Sha256Hash.ZERO_HASH.getByteString()); + BlockMessage msg = new BlockMessage(blockCapsule); + service.broadcast(msg); + Item item = new Item(blockCapsule.getBlockId(), InventoryType.BLOCK); + Assert.assertTrue(service.getMessage(item) != null); + } +} From 6a77eecbf58af789ebee5790a2e2f824914c2dc4 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 12 Mar 2019 12:29:21 +0800 Subject: [PATCH 29/41] modify processTransaction --- src/main/java/org/tron/core/db/Manager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/tron/core/db/Manager.java b/src/main/java/org/tron/core/db/Manager.java index cacbe7fb4a8..72d9ae1b005 100644 --- a/src/main/java/org/tron/core/db/Manager.java +++ b/src/main/java/org/tron/core/db/Manager.java @@ -1270,8 +1270,6 @@ public boolean processTransaction(final TransactionCapsule trxCap, BlockCapsule ownerAddressSet.add(ByteArray.toHexString(TransactionCapsule.getOwner(contract))); } - trxCap.setTrxTrace(null); - return true; } From 246aa698c0237284659150fdba5dda117c12f2f0 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 12 Mar 2019 18:12:20 +0800 Subject: [PATCH 30/41] modify AdvService --- .../common/overlay/client/PeerClient.java | 2 +- .../org/tron/core/net/service/AdvService.java | 26 +++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/tron/common/overlay/client/PeerClient.java b/src/main/java/org/tron/common/overlay/client/PeerClient.java index 9fad24caf9f..3f1693769cf 100644 --- a/src/main/java/org/tron/common/overlay/client/PeerClient.java +++ b/src/main/java/org/tron/common/overlay/client/PeerClient.java @@ -55,7 +55,7 @@ public ChannelFuture connectAsync(NodeHandler nodeHandler, boolean discoveryMode return connectAsync(node.getHost(), node.getPort(), node.getHexId(), discoveryMode) .addListener((ChannelFutureListener) future -> { if (!future.isSuccess()) { - logger.error("connect to {}:{} fail,cause:{}", node.getHost(), node.getPort(), + logger.warn("connect to {}:{} fail,cause:{}", node.getHost(), node.getPort(), future.cause().getMessage()); nodeHandler.getNodeStatistics().nodeDisconnectedLocal(ReasonCode.CONNECT_FAIL); nodeHandler.getNodeStatistics().notifyDisconnect(); diff --git a/src/main/java/org/tron/core/net/service/AdvService.java b/src/main/java/org/tron/core/net/service/AdvService.java index 5d7c0217608..3e8bc6559f5 100644 --- a/src/main/java/org/tron/core/net/service/AdvService.java +++ b/src/main/java/org/tron/core/net/service/AdvService.java @@ -48,9 +48,12 @@ public class AdvService { private Cache invToFetchCache = CacheBuilder.newBuilder() .maximumSize(100_000).expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); - private Cache messageCache = CacheBuilder.newBuilder() + private Cache trxCache = CacheBuilder.newBuilder() .maximumSize(50_000).expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); + private Cache blockCache = CacheBuilder.newBuilder() + .maximumSize(10).expireAfterWrite(1, TimeUnit.MINUTES).recordStats().build(); + private ScheduledExecutorService spreadExecutor = Executors.newSingleThreadScheduledExecutor(); private ScheduledExecutorService fetchExecutor = Executors.newSingleThreadScheduledExecutor(); @@ -85,16 +88,28 @@ synchronized public boolean addInv (Item item) { if (invToFetchCache.getIfPresent(item) != null) { return false; } - if (messageCache.getIfPresent(item) != null) { - return false; + + if (item.getType().equals(InventoryType.TRX)) { + if (trxCache.getIfPresent(item) != null) { + return false; + } + } else { + if (blockCache.getIfPresent(item) != null) { + return false; + } } + invToFetchCache.put(item, System.currentTimeMillis()); invToFetch.put(item, System.currentTimeMillis()); return true; } public Message getMessage (Item item) { - return messageCache.getIfPresent(item); + if (item.getType().equals(InventoryType.TRX)) { + return trxCache.getIfPresent(item); + } else { + return blockCache.getIfPresent(item); + } } public void broadcast(Message msg) { @@ -106,15 +121,16 @@ public void broadcast(Message msg) { blockMsg.getBlockCapsule().getTransactions().forEach(transactionCapsule -> invToSpread.remove(transactionCapsule.getTransactionId()) ); + blockCache.put(item, msg); } else if (msg instanceof TransactionMessage) { TransactionMessage trxMsg = (TransactionMessage) msg; item = new Item(trxMsg.getMessageId(), InventoryType.TRX); trxCount.add(); + trxCache.put(item, msg); } else { logger.error("Adv item is neither block nor trx, type: {}", msg.getType()); return; } - messageCache.put(item, msg); synchronized (invToSpread) { invToSpread.put(item, System.currentTimeMillis()); } From 8d6287e43e2ad1bf3a903840bf5458a40bf1143e Mon Sep 17 00:00:00 2001 From: wubin01 Date: Wed, 13 Mar 2019 19:54:27 +0800 Subject: [PATCH 31/41] modify InventoryMsgHandler --- .../FetchInvDataMsgHandler.java | 10 +++---- .../messagehandler/InventoryMsgHandler.java | 25 +++++++++------- .../tron/core/net/peer/PeerConnection.java | 12 +------- .../messagehandler/BlockMsgHandlerTest.java | 8 ++--- .../ChainInventoryMsgHandlerTest.java | 8 ++--- .../FetchInvDataMsgHandlerTest.java | 5 ++++ .../InventoryMsgHandlerTest.java | 30 +++++++++++++++++++ .../SyncBlockChainMsgHandlerTest.java | 4 +-- 8 files changed, 66 insertions(+), 36 deletions(-) create mode 100644 src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java create mode 100644 src/test/java/org/tron/core/net/messagehandler/InventoryMsgHandlerTest.java diff --git a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index ed516cdd458..67c7dba5608 100644 --- a/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -93,17 +93,17 @@ private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) thr MessageTypes type = fetchInvDataMsg.getInvMessageType(); if (type == MessageTypes.TRX) { + for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { + if (peer.getAdvInvSpread().getIfPresent(new Item(hash, InventoryType.TRX)) == null) { + throw new P2pException(TypeEnum.BAD_MESSAGE, "not spread inv: {}" + hash); + } + } int fetchCount = peer.getNodeStatistics().messageStatistics.tronInTrxFetchInvDataElement .getCount(10); int maxCount = advService.getTrxCount().getCount(60); if (fetchCount > maxCount) { throw new P2pException(TypeEnum.BAD_MESSAGE, "maxCount: " + maxCount + ", fetchCount: " + fetchCount); } - for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - if (peer.getAdvInvSpread().getIfPresent(new Item(hash, InventoryType.TRX)) == null) { - throw new P2pException(TypeEnum.BAD_MESSAGE, "not spread inv: {}" + hash); - } - } } else { boolean isAdv = true; for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { diff --git a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index c4fc17e20a4..618ccfc8523 100644 --- a/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -56,17 +56,22 @@ private boolean check (PeerConnection peer, InventoryMessage inventoryMessage) { type, size, peer.getInetAddress(), peer.isNeedSyncFromUs(), peer.isNeedSyncFromPeer()); return false; } - if (transactionsMsgHandler.isBusy() && type.equals(InventoryType.TRX)) { - logger.warn("Drop inv: {} size: {} from Peer {}, transactionsMsgHandler is busy.", - type, size, peer.getInetAddress()); - return false; - } - int count = peer.getNodeStatistics().messageStatistics.tronInTrxInventoryElement.getCount(10); - if (count > maxCountIn10s) { - logger.warn("Drop inv: {} size: {} from Peer {}, Inv count: {} is overload.", - type, size, peer.getInetAddress(), count); - return false; + + if (type.equals(InventoryType.TRX)) { + int count = peer.getNodeStatistics().messageStatistics.tronInTrxInventoryElement.getCount(10); + if (count > maxCountIn10s) { + logger.warn("Drop inv: {} size: {} from Peer {}, Inv count: {} is overload.", + type, size, peer.getInetAddress(), count); + return false; + } + + if (transactionsMsgHandler.isBusy()) { + logger.warn("Drop inv: {} size: {} from Peer {}, transactionsMsgHandler is busy.", + type, size, peer.getInetAddress()); + return false; + } } + return true; } } diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index 035d4b4fd91..9c9fd679eb7 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -42,7 +42,7 @@ public class PeerConnection extends Channel { @Autowired private AdvService advService; - private int invCacheSize = 500_000; + private int invCacheSize = 100_000; @Setter @Getter @@ -112,16 +112,6 @@ public void setBlockBothHave (BlockId blockId) { @Getter private boolean needSyncFromUs; - private void removeIterator(Iterator> iterator, long oldestTimestamp) { - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - Long ts = (Long) entry.getValue(); - if (ts < oldestTimestamp) { - iterator.remove(); - } - } - } - public boolean isIdle() { return advInvRequest.isEmpty() && syncBlockRequested.isEmpty() && syncChainRequested == null; } diff --git a/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java b/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java index 7004b847c49..2dbd55db147 100644 --- a/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java +++ b/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java @@ -15,10 +15,10 @@ public class BlockMsgHandlerTest { - BlockMsgHandler handler = new BlockMsgHandler(); - PeerConnection peer = new PeerConnection(); - BlockCapsule blockCapsule; - BlockMessage msg; + private BlockMsgHandler handler = new BlockMsgHandler(); + private PeerConnection peer = new PeerConnection(); + private BlockCapsule blockCapsule; + private BlockMessage msg; @Test public void testProcessMessage() { diff --git a/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java b/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java index d7ffc6be92f..e26444b2fe4 100644 --- a/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java +++ b/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java @@ -14,10 +14,10 @@ public class ChainInventoryMsgHandlerTest { - ChainInventoryMsgHandler handler = new ChainInventoryMsgHandler(); - PeerConnection peer = new PeerConnection(); - ChainInventoryMessage msg = new ChainInventoryMessage(new ArrayList<>(), 0l); - List blockIds = new ArrayList<>(); + private ChainInventoryMsgHandler handler = new ChainInventoryMsgHandler(); + private PeerConnection peer = new PeerConnection(); + private ChainInventoryMessage msg = new ChainInventoryMessage(new ArrayList<>(), 0l); + private List blockIds = new ArrayList<>(); @Test public void testProcessMessage() { diff --git a/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java b/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java new file mode 100644 index 00000000000..e885741c29c --- /dev/null +++ b/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java @@ -0,0 +1,5 @@ +package org.tron.core.net.messagehandler; + +public class FetchInvDataMsgHandlerTest { + +} diff --git a/src/test/java/org/tron/core/net/messagehandler/InventoryMsgHandlerTest.java b/src/test/java/org/tron/core/net/messagehandler/InventoryMsgHandlerTest.java new file mode 100644 index 00000000000..b6942efdd19 --- /dev/null +++ b/src/test/java/org/tron/core/net/messagehandler/InventoryMsgHandlerTest.java @@ -0,0 +1,30 @@ +package org.tron.core.net.messagehandler; + +import java.util.ArrayList; +import org.junit.Test; +import org.tron.core.net.message.InventoryMessage; +import org.tron.core.net.peer.PeerConnection; +import org.tron.protos.Protocol.Inventory.InventoryType; + +public class InventoryMsgHandlerTest { + private InventoryMsgHandler handler = new InventoryMsgHandler(); + private PeerConnection peer = new PeerConnection(); + + @Test + public void testProcessMessage() { + InventoryMessage msg = new InventoryMessage(new ArrayList<>(), InventoryType.TRX); + + peer.setNeedSyncFromPeer(true); + peer.setNeedSyncFromUs(true); + handler.processMessage(peer, msg); + + peer.setNeedSyncFromPeer(true); + peer.setNeedSyncFromUs(false); + handler.processMessage(peer, msg); + + peer.setNeedSyncFromPeer(false); + peer.setNeedSyncFromUs(true); + handler.processMessage(peer, msg); + + } +} diff --git a/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java b/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java index 03739f82fdc..ff4c116c98f 100644 --- a/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java +++ b/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java @@ -8,8 +8,8 @@ import org.tron.core.net.peer.PeerConnection; public class SyncBlockChainMsgHandlerTest { - SyncBlockChainMsgHandler handler = new SyncBlockChainMsgHandler(); - PeerConnection peer = new PeerConnection(); + private SyncBlockChainMsgHandler handler = new SyncBlockChainMsgHandler(); + private PeerConnection peer = new PeerConnection(); @Test public void testProcessMessage() { From a833f697a80834e97e46417a08630bf8c07a9246 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Thu, 14 Mar 2019 11:32:53 +0800 Subject: [PATCH 32/41] modify peerconnection --- .../java/org/tron/common/overlay/server/SyncPool.java | 10 ++-------- .../java/org/tron/core/net/peer/PeerConnection.java | 4 ++-- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/tron/common/overlay/server/SyncPool.java b/src/main/java/org/tron/common/overlay/server/SyncPool.java index af5b3f44986..fae0de6c9e4 100644 --- a/src/main/java/org/tron/common/overlay/server/SyncPool.java +++ b/src/main/java/org/tron/common/overlay/server/SyncPool.java @@ -123,12 +123,6 @@ private void fillUp() { }); } - // for test only - public void addActivePeers(PeerConnection p) { - activePeers.add(p); - } - - synchronized void logActivePeers() { logger.info("-------- active connect channel {}", activePeersCount.get()); @@ -178,7 +172,7 @@ public synchronized void onConnect(Channel peer) { } activePeers.add(peerConnection); activePeers.sort(Comparator.comparingDouble(c -> c.getPeerStats().getAvgLatency())); - peerConnection.onConnectPeer(); + peerConnection.onConnect(); } } @@ -191,7 +185,7 @@ public synchronized void onDisconnect(Channel peer) { activePeersCount.decrementAndGet(); } activePeers.remove(peerConnection); - peerConnection.onDisconnectPeer(); + peerConnection.onDisconnect(); } } diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index 9c9fd679eb7..c74a14cf0df 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -120,7 +120,7 @@ public void sendMessage(Message message) { msgQueue.sendMessage(message); } - public void onConnectPeer() { + public void onConnect() { if (getHelloMessage().getHeadBlockId().getNum() > tronNetDelegate.getHeadBlockId().getNum()) { setTronState(TronState.SYNCING); syncService.startSync(this); @@ -129,7 +129,7 @@ public void onConnectPeer() { } } - public void onDisconnectPeer() { + public void onDisconnect() { syncService.onDisconnect(this); advService.onDisconnect(this); advInvReceive.cleanUp(); From 1cbd25e8cc3a0000ddad2088790b5de2d517ad1c Mon Sep 17 00:00:00 2001 From: wubin01 Date: Mon, 18 Mar 2019 16:31:38 +0800 Subject: [PATCH 33/41] modify Channel handle exception --- .../tron/common/overlay/server/Channel.java | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/tron/common/overlay/server/Channel.java b/src/main/java/org/tron/common/overlay/server/Channel.java index 3689ea23d6f..634f9b40df3 100644 --- a/src/main/java/org/tron/common/overlay/server/Channel.java +++ b/src/main/java/org/tron/common/overlay/server/Channel.java @@ -22,6 +22,7 @@ import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; import io.netty.handler.timeout.ReadTimeoutException; import io.netty.handler.timeout.ReadTimeoutHandler; +import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -164,17 +165,15 @@ public void processException(Throwable throwable) { while (baseThrowable.getCause() != null) { baseThrowable = baseThrowable.getCause(); } - String errMsg = throwable.getMessage(); SocketAddress address = ctx.channel().remoteAddress(); - if (throwable instanceof ReadTimeoutException) { - logger.error("Read timeout, {}", address); + if (throwable instanceof ReadTimeoutException || + throwable instanceof IOException) { + logger.warn("Close peer {}, reason: {}", address, throwable.getMessage()); } else if (baseThrowable instanceof P2pException) { - logger.error("type: {}, info: {}, {}", ((P2pException) baseThrowable).getType(), - baseThrowable.getMessage(), address); - } else if (errMsg != null && errMsg.contains("Connection reset by peer")) { - logger.error("{}, {}", errMsg, address); + logger.warn("Close peer {}, type: {}, info: {}", + address,((P2pException) baseThrowable).getType(), baseThrowable.getMessage()); } else { - logger.error("exception caught, {}", address, throwable); + logger.error("Close peer {}, exception caught", address, throwable); } close(); } @@ -220,10 +219,6 @@ public void setChannelHandlerContext(ChannelHandlerContext ctx) { this.inetSocketAddress = ctx == null ? null : (InetSocketAddress) ctx.channel().remoteAddress(); } - public ChannelHandlerContext getChannelHandlerContext() { - return this.ctx; - } - public InetAddress getInetAddress() { return ctx == null ? null : ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress(); } @@ -245,10 +240,6 @@ public void setTronState(TronState tronState) { logger.info("Peer {} status change to {}.", inetSocketAddress, tronState); } - public TronState getTronState() { - return tronState; - } - public boolean isActive() { return isActive; } @@ -257,10 +248,6 @@ public boolean isDisconnect() { return isDisconnect; } - public boolean isProtocolsInitialized() { - return tronState.ordinal() > TronState.INIT.ordinal(); - } - public boolean isTrustPeer() { return isTrustPeer; } From 00ac4d9454a1bcacd768ee489ff44c8570a8afe5 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 19 Mar 2019 12:01:14 +0800 Subject: [PATCH 34/41] modify AdvService broadcast inf --- src/main/java/org/tron/core/net/service/AdvService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/tron/core/net/service/AdvService.java b/src/main/java/org/tron/core/net/service/AdvService.java index 3e8bc6559f5..6ab156b5675 100644 --- a/src/main/java/org/tron/core/net/service/AdvService.java +++ b/src/main/java/org/tron/core/net/service/AdvService.java @@ -126,7 +126,7 @@ public void broadcast(Message msg) { TransactionMessage trxMsg = (TransactionMessage) msg; item = new Item(trxMsg.getMessageId(), InventoryType.TRX); trxCount.add(); - trxCache.put(item, msg); + trxCache.put(item, new TransactionMessage(((TransactionMessage) msg).getTransactionCapsule().getInstance())); } else { logger.error("Adv item is neither block nor trx, type: {}", msg.getType()); return; From 76b188a32dc9272680fe86f9cc1ddb0d7f9490e3 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 19 Mar 2019 16:21:44 +0800 Subject: [PATCH 35/41] modify AdvService consumerInvToFetch func --- .../java/org/tron/core/net/service/AdvService.java | 11 ++++++++--- src/test/java/org/tron/core/net/UdpTest.java | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/tron/core/net/service/AdvService.java b/src/main/java/org/tron/core/net/service/AdvService.java index 6ab156b5675..08d88edd6a9 100644 --- a/src/main/java/org/tron/core/net/service/AdvService.java +++ b/src/main/java/org/tron/core/net/service/AdvService.java @@ -118,9 +118,11 @@ public void broadcast(Message msg) { BlockMessage blockMsg = (BlockMessage) msg; item = new Item(blockMsg.getMessageId(), InventoryType.BLOCK); logger.info("Ready to broadcast block {}", blockMsg.getBlockId().getString()); - blockMsg.getBlockCapsule().getTransactions().forEach(transactionCapsule -> - invToSpread.remove(transactionCapsule.getTransactionId()) - ); + blockMsg.getBlockCapsule().getTransactions().forEach(transactionCapsule ->{ + Sha256Hash tid = transactionCapsule.getTransactionId(); + invToSpread.remove(tid); + invToFetchCache.put(new Item(tid, InventoryType.TRX), System.currentTimeMillis()); + }); blockCache.put(item, msg); } else if (msg instanceof TransactionMessage) { TransactionMessage trxMsg = (TransactionMessage) msg; @@ -142,6 +144,8 @@ public void onDisconnect (PeerConnection peer) { if (tronNetDelegate.getActivePeer().stream() .anyMatch(p -> !p.equals(peer) && p.getAdvInvReceive().getIfPresent(item) != null)){ invToFetch.put(item, System.currentTimeMillis()); + } else { + invToFetchCache.invalidate(item); } }); } @@ -162,6 +166,7 @@ private void consumerInvToFetch() { if (time < now - MSG_CACHE_DURATION_IN_BLOCKS * BLOCK_PRODUCED_INTERVAL) { logger.info("This obj is too late to fetch, type: {} hash: {}.", item.getType(), item.getHash()); invToFetch.remove(item); + invToFetchCache.invalidate(item); return; } peers.stream() diff --git a/src/test/java/org/tron/core/net/UdpTest.java b/src/test/java/org/tron/core/net/UdpTest.java index af01e17ad53..4763f1c1be9 100644 --- a/src/test/java/org/tron/core/net/UdpTest.java +++ b/src/test/java/org/tron/core/net/UdpTest.java @@ -40,6 +40,7 @@ public UdpTest(TronApplicationContext context) { } public void test() throws Exception { + /* Thread thread = new Thread(() -> { try { discover(); @@ -57,6 +58,7 @@ public void test() throws Exception { thread.interrupt(); Assert.assertTrue(false); } + */ } public void discover() throws Exception { From 41ba41616c2bab5417f6909425e2878ad7883e6d Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 19 Mar 2019 16:28:40 +0800 Subject: [PATCH 36/41] modify MessageQueue sendmsg --- src/main/java/org/tron/common/overlay/server/MessageQueue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/tron/common/overlay/server/MessageQueue.java b/src/main/java/org/tron/common/overlay/server/MessageQueue.java index 0a7897ac17a..bdd27903677 100644 --- a/src/main/java/org/tron/common/overlay/server/MessageQueue.java +++ b/src/main/java/org/tron/common/overlay/server/MessageQueue.java @@ -71,7 +71,7 @@ public void activate(ChannelHandlerContext ctx) { } Message msg = msgQueue.take(); ctx.writeAndFlush(msg.getSendData()).addListener((ChannelFutureListener) future -> { - if (!future.isSuccess()) { + if (!future.isSuccess() && !channel.isDisconnect()) { logger.error("Fail send to {}, {}", ctx.channel().remoteAddress(), msg); } }); From da177dc3858d1b0c7df1e333e99a735967516713 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 19 Mar 2019 17:18:23 +0800 Subject: [PATCH 37/41] modify trx handle --- .../core/net/messagehandler/TransactionsMsgHandler.java | 7 +++++++ src/main/java/org/tron/core/net/service/AdvService.java | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index 9bcc7d81cf5..403209419fa 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -1,5 +1,6 @@ package org.tron.core.net.messagehandler; +import com.googlecode.cqengine.query.simple.In; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -128,6 +129,12 @@ private void handleTransaction (PeerConnection peer, TransactionMessage trx) { logger.warn("Peer {} is disconnect, drop trx {}", peer.getInetAddress(), trx.getMessageId()); return; } + + if (advService.getMessage(new Item(trx.getMessageId(), InventoryType.TRX)) != null) { + logger.warn("Trx {} from {} is exit, drop it.", trx.getMessageId(), peer.getInetAddress()); + return; + } + try { tronNetDelegate.pushTransaction(trx.getTransactionCapsule()); advService.broadcast(trx); diff --git a/src/main/java/org/tron/core/net/service/AdvService.java b/src/main/java/org/tron/core/net/service/AdvService.java index 08d88edd6a9..9d0a826bcc8 100644 --- a/src/main/java/org/tron/core/net/service/AdvService.java +++ b/src/main/java/org/tron/core/net/service/AdvService.java @@ -121,7 +121,7 @@ public void broadcast(Message msg) { blockMsg.getBlockCapsule().getTransactions().forEach(transactionCapsule ->{ Sha256Hash tid = transactionCapsule.getTransactionId(); invToSpread.remove(tid); - invToFetchCache.put(new Item(tid, InventoryType.TRX), System.currentTimeMillis()); + trxCache.put(new Item(tid, InventoryType.TRX), new TransactionMessage(transactionCapsule.getInstance())); }); blockCache.put(item, msg); } else if (msg instanceof TransactionMessage) { From e19ca8988e7732396b214d40add69290fba848ae Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 19 Mar 2019 18:00:59 +0800 Subject: [PATCH 38/41] modify trx handle --- .../net/messagehandler/TransactionsMsgHandler.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index 403209419fa..a710a2adf3c 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -112,26 +112,21 @@ private void handleSmartContract() { try { while (queue.size() < MAX_SMART_CONTRACT_SUBMIT_SIZE) { TrxEvent event = smartContractQueue.take(); -// if (System.currentTimeMillis() - event.getTime() > TIME_OUT) { -// logger.warn("Drop smart contract {} from peer {}."); -// continue; -// } trxHandlePool.submit(() -> handleTransaction(event.getPeer(), event.getMsg())); } } catch (Exception e) { - logger.error("Handle smart contract exception", e); + logger.error("Handle smart contract exception.", e); } }, 1000, 20, TimeUnit.MILLISECONDS); } private void handleTransaction (PeerConnection peer, TransactionMessage trx) { if (peer.isDisconnect()) { - logger.warn("Peer {} is disconnect, drop trx {}", peer.getInetAddress(), trx.getMessageId()); + logger.warn("Drop trx {} from {}, peer is disconnect.", peer.getInetAddress(), trx.getMessageId()); return; } if (advService.getMessage(new Item(trx.getMessageId(), InventoryType.TRX)) != null) { - logger.warn("Trx {} from {} is exit, drop it.", trx.getMessageId(), peer.getInetAddress()); return; } @@ -145,7 +140,7 @@ private void handleTransaction (PeerConnection peer, TransactionMessage trx) { peer.disconnect(ReasonCode.BAD_TX); } }catch (Exception e) { - logger.warn("Trx {} from peer {} process failed.", trx.getMessageId(), peer.getInetAddress(), e); + logger.error("Trx {} from peer {} process failed.", trx.getMessageId(), peer.getInetAddress(), e); } } } \ No newline at end of file From 269ce10c304c8b935a559bd0719bb3e9638e09e6 Mon Sep 17 00:00:00 2001 From: wubin01 Date: Tue, 19 Mar 2019 18:01:43 +0800 Subject: [PATCH 39/41] modiyf log --- .../tron/core/net/messagehandler/TransactionsMsgHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index a710a2adf3c..fe6b553fa73 100644 --- a/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -122,7 +122,7 @@ private void handleSmartContract() { private void handleTransaction (PeerConnection peer, TransactionMessage trx) { if (peer.isDisconnect()) { - logger.warn("Drop trx {} from {}, peer is disconnect.", peer.getInetAddress(), trx.getMessageId()); + logger.warn("Drop trx {} from {}, peer is disconnect.", trx.getMessageId(), peer.getInetAddress()); return; } From b7ca6c4a67e94803cfa5ed9d3264b0393c57886e Mon Sep 17 00:00:00 2001 From: wubin01 Date: Wed, 20 Mar 2019 17:07:11 +0800 Subject: [PATCH 40/41] modify http start func --- .../java/org/tron/core/services/http/FullNodeHttpApiService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java b/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java index b78213f0d5f..76c60fe659f 100644 --- a/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java +++ b/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java @@ -245,7 +245,6 @@ public void start() { context.addServlet(new ServletHolder(listExchangesServlet), "/listexchanges"); context.addServlet(new ServletHolder(getChainParametersServlet), "/getchainparameters"); context.addServlet(new ServletHolder(getAccountResourceServlet), "/getaccountresource"); - context.addServlet(new ServletHolder(getNodeInfoServlet), "/getnodeinfo"); context.addServlet(new ServletHolder(addTransactionSignServlet), "/addtransactionsign"); context.addServlet(new ServletHolder(getTransactionSignWeightServlet), "/getsignweight"); context.addServlet(new ServletHolder(getTransactionApprovedListServlet), "/getapprovedlist"); From 824ca31bd7e6529ed4387d7c74b1a5d66b03715b Mon Sep 17 00:00:00 2001 From: wubin01 Date: Fri, 22 Mar 2019 12:42:32 +0800 Subject: [PATCH 41/41] modify tronNet processException --- .../java/org/tron/core/net/TronNetService.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/tron/core/net/TronNetService.java b/src/main/java/org/tron/core/net/TronNetService.java index 493ce4f390c..0fd9da34c99 100644 --- a/src/main/java/org/tron/core/net/TronNetService.java +++ b/src/main/java/org/tron/core/net/TronNetService.java @@ -99,7 +99,7 @@ protected void onMessage(PeerConnection peer, TronMessage msg) { transactionsMsgHandler.processMessage(peer, msg); break; default: - throw new P2pException(TypeEnum.NO_SUCH_MESSAGE, "No such message: " + msg.getType()); + throw new P2pException(TypeEnum.NO_SUCH_MESSAGE, msg.getType().toString()); } }catch (Exception e) { processException(peer, msg, e); @@ -108,7 +108,6 @@ protected void onMessage(PeerConnection peer, TronMessage msg) { private void processException (PeerConnection peer, TronMessage msg, Exception ex) { ReasonCode code = null; - boolean exceptionPrintFlag = false; if (ex instanceof P2pException) { TypeEnum type = ((P2pException) ex).getType(); @@ -118,7 +117,6 @@ private void processException (PeerConnection peer, TronMessage msg, Exception e break; case BAD_BLOCK: code = ReasonCode.BAD_BLOCK; - exceptionPrintFlag = true; break; case NO_SUCH_MESSAGE: case MESSAGE_WITH_WRONG_LENGTH: @@ -135,15 +133,12 @@ private void processException (PeerConnection peer, TronMessage msg, Exception e code = ReasonCode.UNKNOWN; break; } + logger.error("Message {} /n process failed from peer {}, type: {}, detail: {}.", + msg, peer.getInetAddress(), type, ex.getMessage()); } else { - exceptionPrintFlag = true; code = ReasonCode.UNKNOWN; - } - - if (exceptionPrintFlag) { - logger.error("Message {} /n process failed from peer {}.", msg, peer.getInetAddress(), ex); - } else { - logger.error("Message {} /n process failed from peer {}, reason: {}.", msg, peer.getInetAddress(), ex.getMessage()); + logger.error("Message {} /n process failed from peer {}.", + msg, peer.getInetAddress(), ex); } peer.disconnect(code);