Search in sources :

Example 1 with TraitorPeerException

use of org.tron.core.exception.TraitorPeerException in project java-tron by tronprotocol.

the class NodeImpl method onHandleChainInventoryMessage.

private void onHandleChainInventoryMessage(PeerConnection peer, ChainInventoryMessage msg) {
    // logger.info("on handle block chain inventory message");
    try {
        if (peer.getSyncChainRequested() != null) {
            // List<BlockId> blockIds = msg.getBlockIds();
            Deque<BlockId> blockIdWeGet = new LinkedList<>(msg.getBlockIds());
            // 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 {
                    boolean isFound = false;
                    for (BlockId id : blockIdWeGet) {
                        if (id.equals(blockIdWeGet.peek())) {
                            isFound = true;
                        }
                    }
                    if (!isFound) {
                        throw new TraitorPeerException("We get a unlinked block chain from " + peer);
                    }
                }
            }
            // check finish
            // here this peer's answer is legal
            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);
                }
                // TODO: if sync finish call del.syncToCli();
                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())) {
                        peer.setHeadBlockWeBothHave(blockIdWeGet.peek());
                        peer.setHeadBlockTimeWeBothHave(del.getBlockTime(blockIdWeGet.peek()));
                        blockIdWeGet.poll();
                    }
                }
            } else if (!blockIdWeGet.isEmpty()) {
                while (!peer.getSyncBlockToFetch().isEmpty()) {
                    if (!peer.getSyncBlockToFetch().peekLast().equals(blockIdWeGet.peekFirst())) {
                        blockIdWeGet.pop();
                    } else {
                        break;
                    }
                }
                if (peer.getSyncBlockToFetch().isEmpty()) {
                    updateBlockWeBothHave(peer, ((BlockMessage) del.getData(blockIdWeGet.peek(), MessageTypes.BLOCK)).getBlockCapsule());
                }
                // poll the block we both have.
                blockIdWeGet.pop();
            }
            // sew it
            peer.getSyncBlockToFetch().addAll(blockIdWeGet);
            peer.setUnfetchSyncNum(msg.getRemainNum());
            long newUnSyncNum = getUnSyncNum();
            if (unSyncNum != newUnSyncNum) {
                unSyncNum = newUnSyncNum;
                del.syncToCli(unSyncNum);
            }
            if (msg.getRemainNum() == 0) {
                if (!peer.getSyncBlockToFetch().isEmpty()) {
                    startFetchSyncBlock();
                } else {
                    // let peer know we are sync.
                    syncNextBatchChainIds(peer);
                }
            } else {
                if (peer.getSyncBlockToFetch().size() > NodeConstant.SYNC_FETCH_BATCH_NUM) {
                    // one batch by one batch.
                    startFetchSyncBlock();
                } else {
                    syncNextBatchChainIds(peer);
                }
            }
        // TODO: check head block time is legal here
        // TODO: refresh sync status to cli. call del.syncToCli() here
        } else {
            throw new TraitorPeerException("We don't send sync request to " + peer);
        }
    } catch (TraitorPeerException e) {
        banTraitorPeer(peer);
    }
}
Also used : BlockMessage(org.tron.core.net.message.BlockMessage) PeerConnection(org.tron.core.net.peer.PeerConnection) BlockId(org.tron.core.capsule.BlockCapsule.BlockId) TraitorPeerException(org.tron.core.exception.TraitorPeerException) LinkedList(java.util.LinkedList)

Aggregations

LinkedList (java.util.LinkedList)1 BlockId (org.tron.core.capsule.BlockCapsule.BlockId)1 TraitorPeerException (org.tron.core.exception.TraitorPeerException)1 BlockMessage (org.tron.core.net.message.BlockMessage)1 PeerConnection (org.tron.core.net.peer.PeerConnection)1