private async Task DiscoverNodes() { IsRunning = false; var callback = new Action(() => { if (ConnectEvent != null) { IsRunning = true; ConnectEvent(this, EventArgs.Empty); } }); try { var peers = _peersRepository.GetAll(); if (peers.Any()) // DISCOVER THE PEERS FROM THE REPOSITORY. { await DiscoverNodesViaStore(peers); callback(); return; } if (!_isSeedNode) // DISCOVER THE PEERS FROM THE SEEDS. { await DiscoverNodesViaSeeds(); } } catch (Exception) { if (_isSeedNode) { callback(); } return; } callback(); }
public Message Receive(Message message, PeerConnector peer, P2PNetworkConnector p2pNetworkConnector) { var blockChain = _blockChainStore.GetBlockChain(); var smartContract = _smartContractStore.GetSmartContracts(); if (message.GetCommandName() == Constants.MessageNames.Version) // RETURNS VERSION. { var msg = message as VersionMessage; var instance = PeersStore.Instance(); var transmittingNode = instance.GetMyIpAddress(); var receivingNode = msg.TransmittingNode; return(new VersionMessage(transmittingNode, receivingNode, msg.Nonce, msg.UserAgent, msg.StartHeight, msg.Relay, msg.MessageHeader.Network)); } if (message.GetCommandName() == Constants.MessageNames.Ping) // RETURNS PONG. { var msg = message as PingMessage; var pong = new PongMessage(msg.Nonce, msg.MessageHeader.Network); return(pong); } if (message.GetCommandName() == Constants.MessageNames.Verack) // RETURNS VERACK MESSAGE. { var msg = message as VerackMessage; return(new VerackMessage(msg.MessageHeader.Network)); } if (message.GetCommandName() == Constants.MessageNames.Addr) // RETURNS THE ADDRS. { var msg = message as AddrMessage; if (msg.IpAddresses != null) { foreach (var ipAddress in msg.IpAddresses) { PeerEventStore.Instance().NewPeer(ipAddress); } } return(null); } if (message.GetCommandName() == Constants.MessageNames.GetAddr) // RETURNS THE ADDRS. { var msg = message as GetAddressMessage; var ipAdrLst = _peersStorage.GetAll(); var response = new AddrMessage(new CompactSize { Size = (ulong)ipAdrLst.Count() }, msg.MessageHeader.Network); foreach (var ipAdr in ipAdrLst) { response.IpAddresses.Add(ipAdr); } return(response); } if (message.GetCommandName() == Constants.MessageNames.MemPool) // RETURNS THE INVENTORY. { var msg = message as MemPoolMessage; var memoryPool = MemoryPool.Instance(); var txIds = memoryPool.GetTransactions().Select(t => t.Transaction.GetTxId()); var inventories = new List <Inventory>(); foreach (var txId in txIds) { inventories.Add(new Inventory(InventoryTypes.MSG_TX, txId)); } return(new InventoryMessage(inventories, msg.MessageHeader.Network)); } if (message.GetCommandName() == Constants.MessageNames.GetData) // RETURNS ALL THE DATA TO THE PEER. { var msg = message as GetDataMessage; var messages = Execute(msg); if (messages != null) { foreach (var m in messages) { peer.Execute(m.Serialize()); } } return(null); } if (message.GetCommandName() == Constants.MessageNames.Transaction) // ADD TRANSACTION INTO MEMORY POOL & BROADCAST IT. { var msg = message as TransactionMessage; AddTransaction(msg.Transaction); MemoryPool.Instance().Remove(msg.Transaction); p2pNetworkConnector.Broadcast(msg.Transaction, msg.MessageHeader.Ipv6); return(null); } if (message.GetCommandName() == Constants.MessageNames.Block) // ADD THE BLOCK. { var msg = message as BlockMessage; _blockValidator.Check(msg.Block); if (msg.Block.Transactions != null) { MemoryPool.Instance().Remove(msg.Block.Transactions.Select(tx => tx.GetTxId())); } smartContract.AddBlock(msg.Block); smartContract.Commit(); blockChain.AddBlock(msg.Block); } if (message.GetCommandName() == Constants.MessageNames.NotFound) // SOME INVENTORIES ARE NOT FOUND. { return(null); } if (message.GetCommandName() == Constants.MessageNames.GetBlocks) // RETURN THE BLOCKS : https://bitcoin.org/en/developer-reference#getblocks { var msg = message as GetBlocksMessage; int lastBlockHeight = -1; foreach (var blockHash in msg.BlockHashes) { lastBlockHeight = blockChain.GetBlockHeight(blockHash); if (lastBlockHeight != -1) { goto Found; } } Found: var currentBlockHeight = blockChain.GetCurrentBlockHeight(); if (currentBlockHeight == lastBlockHeight) { return(new InventoryMessage(new List <Inventory>(), msg.MessageHeader.Network)); } var nbBlocks = currentBlockHeight - lastBlockHeight; if (lastBlockHeight == -1) { nbBlocks = currentBlockHeight - 1; } if (nbBlocks > Constants.DEFAULT_MAX_GET_INVENTORIES) { nbBlocks = Constants.DEFAULT_MAX_GET_INVENTORIES; } var blocks = blockChain.GetLastBlocks(nbBlocks); var inventories = new List <Inventory>(); foreach (var block in blocks) { inventories.Add(new Inventory(InventoryTypes.MSG_BLOCK, block.GetHashHeader())); } return(new InventoryMessage(inventories, msg.MessageHeader.Network)); } return(null); }