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); } }
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); } }
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); }