Optimze logic of construct ChainInventoryMessage

System information

OS: Linux
JVM: Red Hat, Inc. 1.8.0_302 amd64
Git: 9e95599
Version: 4.7.2
Code: 18031

Expected behaviour

Actual behavior

When a node processes the message BLOCK_CHAIN_INVENTORY from a peer, it fails to check this message and throws exceptions:

    if (msg.getRemainNum() != 0 && blockIds.size() < NetConstants.SYNC_FETCH_BATCH_NUM) {
      throw new P2pException(TypeEnum.BAD_MESSAGE,
          "remain: " + msg.getRemainNum() + ", blockIds size: " + blockIds.size());
    }

The size of blockIds is smaller than SYNC_FETCH_BATCH_NUM but remain_num is bigger than 0. The root cause may be that the peer’s head blockId varies when the peer constructs ChainInventoryMessage.

Steps to reproduce the behavior

Backtrace

14:35:51.283 INFO  [peerClient-31] [net](P2pEventHandlerImpl.java:168) Receive message from  peer: /65.108.12.9:18888, type: BLOCK_CHAIN_INVENTORY
size: 135, first blockId: Num:55342988,ID:00000000034c778cf75f75abc9cc1555b3266944b0c2c3b6d026c6321abd0501, end blockId: Num:55343122,ID:00000000034c78127e1f5a61859772d83cca82836ebc7baf3ddb2f64881e8375, remain_num: 1
14:35:51.285 ERROR [peerClient-31] [net](P2pEventHandlerImpl.java:255) Message from /65.108.12.9:18888 process failed, type: BLOCK_CHAIN_INVENTORY
size: 135, first blockId: Num:55342988,ID:00000000034c778cf75f75abc9cc1555b3266944b0c2c3b6d026c6321abd0501, end blockId: Num:55343122,ID:00000000034c78127e1f5a61859772d83cca82836ebc7baf3ddb2f64881e8375, remain_num: 1 
 type: (4, bad message)
org.tron.core.exception.P2pException: remain: 1, blockIds size: 135
        at org.tron.core.net.messagehandler.ChainInventoryMsgHandler.check(ChainInventoryMsgHandler.java:117)
        at org.tron.core.net.messagehandler.ChainInventoryMsgHandler.processMessage(ChainInventoryMsgHandler.java:43)
        at org.tron.core.net.P2pEventHandlerImpl.processMessage(P2pEventHandlerImpl.java:188)
        at org.tron.core.net.P2pEventHandlerImpl.onMessage(P2pEventHandlerImpl.java:140)
        at org.tron.p2p.connection.ChannelManager.handMessage(ChannelManager.java:261)
        at org.tron.p2p.connection.ChannelManager.processMessage(ChannelManager.java:207)
        at org.tron.p2p.connection.socket.MessageHandler.decode(MessageHandler.java:51)
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:510)
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:449)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:279)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
        at org.tron.p2p.stats.TrafficStats$TrafficStatHandler.channelRead(TrafficStats.java:36)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at java.lang.Thread.run(Thread.java:748)

When submitting logs: please submit them in text and not screenshots.