private void Check(PeerConnection peer, FetchInventoryDataMessage message)
        {
            MessageTypes.MsgType type = message.InventoryMessageType;

            if (type == MessageTypes.MsgType.TX)
            {
                foreach (SHA256Hash hash in message.GetHashList())
                {
                    if (peer.GetInventorySpread(new Item(hash, InventoryType.Trx)) == null)
                    {
                        throw new P2pException(P2pException.ErrorType.BAD_MESSAGE, "not spread inventory : " + hash);
                    }
                }

                int fetch_count = peer.NodeStatistics.MessageStatistics.MineralInTrxFetchInvDataElement.GetCount(10);
                int max_count   = Manager.Instance.AdvanceService.TxCount.GetCount(60);
                if (fetch_count > max_count)
                {
                    throw new P2pException(
                              P2pException.ErrorType.BAD_MESSAGE, "maxCount: " + max_count + ", fetchCount: " + fetch_count);
                }
            }
            else
            {
                bool is_advance = true;
                foreach (SHA256Hash hash in message.GetHashList())
                {
                    if (peer.GetInventorySpread(new Item(hash, InventoryType.Block)) == null)
                    {
                        is_advance = false;
                        break;
                    }
                }

                if (is_advance)
                {
                    MessageCount out_advance_block = peer.NodeStatistics.MessageStatistics.MineralOutAdvBlock;
                    out_advance_block.Add(message.GetHashList().Count);

                    int out_block_count_1min = out_advance_block.GetCount(60);
                    int produced_block_2min  = 120000 / Parameter.ChainParameters.BLOCK_PRODUCED_INTERVAL;
                    if (out_block_count_1min > produced_block_2min)
                    {
                        throw new P2pException(
                                  P2pException.ErrorType.BAD_MESSAGE,
                                  "producedBlockIn2min: " + produced_block_2min + ", outBlockCountIn1min: " + out_block_count_1min);
                    }
                }
                else
                {
                    if (!peer.IsNeedSyncUs)
                    {
                        throw new P2pException(
                                  P2pException.ErrorType.BAD_MESSAGE, "no need sync");
                    }

                    foreach (SHA256Hash hash in message.GetHashList())
                    {
                        long block_num     = new BlockId(hash).Num;
                        long min_block_num = peer.LastSyncBlockId.Num - 2 * Parameter.NodeParameters.SYNC_FETCH_BATCH_NUM;

                        if (block_num < min_block_num)
                        {
                            throw new P2pException(
                                      P2pException.ErrorType.BAD_MESSAGE, "minBlockNum: " + min_block_num + ", blockNum: " + block_num);
                        }

                        if (peer.GetSyncBlockId(hash) != null)
                        {
                            throw new P2pException(
                                      P2pException.ErrorType.BAD_MESSAGE, new BlockId(hash).GetString() + " is exist");
                        }

                        peer.AddSyncBlockId(hash, Helper.CurrentTimeMillis());
                    }
                }
            }
        }
Example #2
0
        private void AddTcpMessage(Message message, bool flag)
        {
            if (flag)
            {
                MineralInMessage.Add();
            }
            else
            {
                MineralOutMessage.Add();
            }

            switch (message.Type)
            {
            case MessageTypes.MsgType.P2P_HELLO:
                if (flag)
                {
                    P2pInHello.Add();
                }
                else
                {
                    P2pOutHello.Add();
                }
                break;

            case MessageTypes.MsgType.P2P_PING:
                if (flag)
                {
                    P2pInPing.Add();
                }
                else
                {
                    P2pOutPing.Add();
                }
                break;

            case MessageTypes.MsgType.P2P_PONG:
                if (flag)
                {
                    P2pInPong.Add();
                }
                else
                {
                    P2pOutPong.Add();
                }
                break;

            case MessageTypes.MsgType.P2P_DISCONNECT:
                if (flag)
                {
                    P2pInDisconnect.Add();
                }
                else
                {
                    P2pOutDisconnect.Add();
                }
                break;

            case MessageTypes.MsgType.SYNC_BLOCK_CHAIN:
                if (flag)
                {
                    MineralInSyncBlockChain.Add();
                }
                else
                {
                    MineralOutSyncBlockChain.Add();
                }
                break;

            case MessageTypes.MsgType.BLOCK_CHAIN_INVENTORY:
                if (flag)
                {
                    MineralInBlockChainInventory.Add();
                }
                else
                {
                    MineralOutBlockChainInventory.Add();
                }
                break;

            case MessageTypes.MsgType.INVENTORY:
                InventoryMessage inventory_message = (InventoryMessage)message;
                int inventory_count = inventory_message.Inventory.Ids.Count;
                if (flag)
                {
                    if (inventory_message.InventoryMessageType == MessageTypes.MsgType.TX)
                    {
                        MineralInTrxInventory.Add();
                        MineralInTrxInventoryElement.Add(inventory_count);
                    }
                    else
                    {
                        MineralInBlockInventory.Add();
                        MineralInBlockInventoryElement.Add(inventory_count);
                    }
                }
                else
                {
                    if (inventory_message.InventoryMessageType == MessageTypes.MsgType.TX)
                    {
                        MineralOutTrxInventory.Add();
                        MineralOutTrxInventoryElement.Add(inventory_count);
                    }
                    else
                    {
                        MineralOutBlockInventory.Add();
                        MineralOutBlockInventoryElement.Add(inventory_count);
                    }
                }
                break;

            case MessageTypes.MsgType.FETCH_INV_DATA:
                FetchInventoryDataMessage fetch_inventory_message = (FetchInventoryDataMessage)message;
                int fetch_count = fetch_inventory_message.Inventory.Ids.Count;
                if (flag)
                {
                    if (fetch_inventory_message.InventoryMessageType == MessageTypes.MsgType.TX)
                    {
                        MineralInTrxFetchInvData.Add();
                        MineralInTrxFetchInvDataElement.Add(fetch_count);
                    }
                    else
                    {
                        MineralInBlockFetchInvData.Add();
                        MineralInBlockFetchInvDataElement.Add(fetch_count);
                    }
                }
                else
                {
                    if (fetch_inventory_message.InventoryMessageType == MessageTypes.MsgType.TX)
                    {
                        MineralOutTrxFetchInvData.Add();
                        MineralOutTrxFetchInvDataElement.Add(fetch_count);
                    }
                    else
                    {
                        MineralOutBlockFetchInvData.Add();
                        MineralOutBlockFetchInvDataElement.Add(fetch_count);
                    }
                }
                break;

            case MessageTypes.MsgType.TXS:
                TransactionsMessage transactionsMessage = (TransactionsMessage)message;
                if (flag)
                {
                    MineralInTrxs.Add();
                    MineralInTrx.Add(transactionsMessage.Transactions.Transactions_.Count);
                }
                else
                {
                    MineralOutTrxs.Add();
                    MineralOutTrx.Add(transactionsMessage.Transactions.Transactions_.Count);
                }
                break;

            case MessageTypes.MsgType.TX:
                if (flag)
                {
                    MineralInMessage.Add();
                }
                else
                {
                    MineralOutMessage.Add();
                }
                break;

            case MessageTypes.MsgType.BLOCK:
                if (flag)
                {
                    MineralInBlock.Add();
                }
                MineralOutBlock.Add();
                break;

            default:
                break;
            }
        }
        public void ProcessMessage(PeerConnection peer, Messages.MineralMessage message)
        {
            FetchInventoryDataMessage fetch_message = (FetchInventoryDataMessage)message;

            Check(peer, fetch_message);

            InventoryType      type         = fetch_message.InventoryType;
            List <Transaction> transactions = new List <Transaction>();

            int size = 0;

            foreach (SHA256Hash hash in fetch_message.GetHashList())
            {
                Item item = new Item(hash, type);

                Message msg = Manager.Instance.AdvanceService.GetMessage(item);
                if (msg == null)
                {
                    try
                    {
                        msg = Manager.Instance.NetDelegate.GetData(hash, type);
                    }
                    catch (System.Exception e)
                    {
                        Logger.Error(
                            string.Format("Fetch item {0} failed. reason: {1}",
                                          item,
                                          hash,
                                          e.Message));
                        peer.Disconnect(ReasonCode.FetchFail, e.Message);

                        return;
                    }
                }

                if (type == InventoryType.Block)
                {
                    BlockId block_id = ((BlockMessage)msg).Block.Id;
                    if (peer.BlockBothHave.Num < block_id.Num)
                    {
                        peer.BlockBothHave = block_id;
                    }

                    peer.SendMessage(msg);
                }
                else
                {
                    transactions.Add(((TransactionMessage)msg).Transaction.Instance);
                    size += ((TransactionMessage)msg).Transaction.Instance.CalculateSize();

                    if (size > MAX_SIZE)
                    {
                        peer.SendMessage(new TransactionsMessage(transactions));
                        transactions = new List <Transaction>();
                        size         = 0;
                    }
                }
            }
            if (transactions.Count > 0)
            {
                peer.SendMessage(new TransactionsMessage(transactions));
            }
        }