Exemple #1
0
 public long GetBlockTime(BlockId id)
 {
     try
     {
         return(Manager.Instance.DBManager.GetBlockById(id).Timestamp);
     }
     catch (ArgumentException)
     {
         throw new P2pException(P2pException.ErrorType.DB_ITEM_NOT_FOUND, id.GetString());
     }
     catch (ItemNotFoundException)
     {
         throw new P2pException(P2pException.ErrorType.DB_ITEM_NOT_FOUND, id.GetString());
     }
 }
        public void ProcessMessage(PeerConnection peer, MineralMessage message)
        {
            BlockMessage block_message = (BlockMessage)message;

            Check(peer, block_message);

            BlockId block_id = block_message.Block.Id;
            Item    item     = new Item(block_id, InventoryType.Block);

            if (peer.SyncBlockRequest.ContainsKey(block_id))
            {
                peer.SyncBlockRequest.TryRemove(block_id, out _);
                Manager.Instance.SyncService.ProcessBlock(peer, block_message);
            }
            else
            {
                peer.InventoryRequest.TryGetValue(item, out long ms);

                Logger.Info(
                    string.Format("Receive block {0} from {1}, cost {2}ms",
                                  block_id.GetString(),
                                  peer.Address,
                                  Helper.CurrentTimeMillis() - ms));

                peer.InventoryRequest.TryRemove(item, out _);
                ProcessBlock(peer, block_message.Block);
            }
        }
Exemple #3
0
 public List <BlockId> GetBlockChainHashesOnFork(BlockId fork_hash)
 {
     try
     {
         return(Manager.Instance.DBManager.GetBlockChainHashesOnFork(fork_hash));
     }
     catch (NonCommonBlockException e)
     {
         throw new P2pException(Exception.P2pException.ErrorType.HARD_FORKED, fork_hash.GetString(), e);
     }
 }
        private void Check(PeerConnection peer, SyncBlockChainMessage message)
        {
            List <BlockId> ids = message.Ids;

            if (ids.IsNullOrEmpty())
            {
                throw new P2pException(
                          P2pException.ErrorType.BAD_MESSAGE, "SyncBlockChain blockIds is empty");
            }

            BlockId first_id = ids.First();

            if (!Manager.Instance.NetDelegate.ContainBlockInMainChain(first_id))
            {
                throw new P2pException(
                          P2pException.ErrorType.BAD_MESSAGE, "No first block:" + first_id.GetString());
            }

            long head_num = Manager.Instance.NetDelegate.HeadBlockId.Num;

            if (first_id.Num > head_num)
            {
                throw new P2pException(
                          P2pException.ErrorType.BAD_MESSAGE,
                          "First blockNum:" + first_id.Num + " gt my head BlockNum:" + head_num);
            }

            BlockId last_sync_id = peer.LastSyncBlockId;
            long    last_num     = ids[(ids.Count - 1)].Num;

            if (last_sync_id != null &&
                last_sync_id.Num > last_num)
            {
                throw new P2pException(
                          P2pException.ErrorType.BAD_MESSAGE,
                          "lastSyncNum:" + last_sync_id.Num + " gt lastNum:" + last_num);
            }
        }
Exemple #5
0
        private List <BlockId> GetBlockChainSummary(PeerConnection peer)
        {
            BlockId        begin_id = peer.BlockBothHave;
            List <BlockId> ids      = new List <BlockId>(peer.SyncBlockFetch);
            List <BlockId> forks    = new List <BlockId>();
            List <BlockId> summary  = new List <BlockId>();

            long sync_begin    = Manager.Instance.NetDelegate.SyncBeginNumber;
            long low           = sync_begin < 0 ? 0 : sync_begin;
            long hight_no_fork = 0;
            long high          = 0;

            Logger.Refactoring("sync_begin : " + sync_begin);

            if (begin_id.Num == 0)
            {
                hight_no_fork = high = Manager.Instance.NetDelegate.HeadBlockId.Num;
            }
            else
            {
                if (Manager.Instance.NetDelegate.ContainBlockInMainChain(begin_id))
                {
                    hight_no_fork = high = begin_id.Num;
                }
                else
                {
                    forks = Manager.Instance.NetDelegate.GetBlockChainHashesOnFork(begin_id);
                    if (forks.IsNullOrEmpty())
                    {
                        throw new P2pException(
                                  P2pException.ErrorType.SYNC_FAILED, "can't find blockId : " + begin_id.GetString());
                    }

                    hight_no_fork = forks.LastOrDefault().Num;
                    forks.RemoveAt(forks.Count);
                    forks.Reverse();
                    high = hight_no_fork + forks.Count;
                }
            }

            if (low > hight_no_fork)
            {
                throw new P2pException(
                          P2pException.ErrorType.SYNC_FAILED, "low: " + low + " gt highNoFork: " + hight_no_fork);
            }

            long real_high = high + ids.Count;

            Logger.Info(
                string.Format("Get block chain summary, low: {0}, highNoFork: {1}, high: {2}, realHigh: {3}",
                              low,
                              hight_no_fork,
                              high,
                              real_high));

            while (low <= real_high)
            {
                if (low <= hight_no_fork)
                {
                    summary.Add(Manager.Instance.NetDelegate.GetBlockIdByNum(low));
                }
                else if (low <= high)
                {
                    summary.Add(forks[(int)(low - hight_no_fork - 1)]);
                }
                else
                {
                    summary.Add(ids[(int)(low - high - 1)]);
                }
                low += (real_high - low + 2) / 2;
            }

            return(summary);
        }