private async Task DiscoverNodesViaSeeds()
        {
            var dic = GetSeedNodes(_network).Select(s => new KeyValuePair <string, ServiceFlags>(s, ServiceFlags.NODE_NETWORK));

            await ConnectToPeers(dic);

            var instance         = PeersStore.Instance();
            var currentIpAddress = instance.GetMyIpAddress();
            var addrMessage      = new AddrMessage(new CompactSize {
                Size = 1
            }, _network);

            addrMessage.IpAddresses.Add(currentIpAddress);
            Broadcast(addrMessage);
            var getAddrMessage = new GetAddressMessage(_network);
            var getAddrLst     = Broadcast(getAddrMessage);

            if (getAddrLst != null && getAddrLst.Any())
            {
                foreach (var getAddr in getAddrLst)
                {
                    var getAdrMsg = getAddr as AddrMessage;
                    if (getAdrMsg == null)
                    {
                        continue;
                    }

                    _peersRepository.AddPeers(getAdrMsg.IpAddresses);
                }
            }

            var peers = _peersRepository.GetAll();

            if (peers.Any())
            {
                await DiscoverNodesViaStore(peers);
            }
        }
Exemplo n.º 2
0
 ValueTask <bool> INetworkMessageHandler <AddrMessage> .ProcessMessageAsync(AddrMessage message, CancellationToken cancellation)
 {
     logger.LogDebug("Peer sent us a list of addresses.");
     //TODO
     return(new ValueTask <bool>(true));
 }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        public Message Parse(byte[] payload)
        {
            if (payload == null)
            {
                throw new ArgumentNullException(nameof(payload));
            }

            if (payload.Length < 24)
            {
                throw new ParseMessageException(ErrorCodes.InvalidCommandLength);
            }

            var header             = payload.Take(40); // Extract the header.
            var startStringPayload = header.Take(4);
            var network            = Networks.MainNet;

            if (startStringPayload.SequenceEqual(new byte[] { 0xf9, 0xbe, 0xb4, 0xd9 }))
            {
                network = Networks.MainNet;
            }
            else if (startStringPayload.SequenceEqual(new byte[] { 0x0b, 0x11, 0x09, 0x07 }))
            {
                network = Networks.TestNet;
            }
            else if (startStringPayload.SequenceEqual(new byte[] { 0xfa, 0xbf, 0xb5, 0xda }))
            {
                network = Networks.RegTest;
            }
            else
            {
                throw new ParseMessageException(ErrorCodes.InvalidStartString);
            }

            var commandNamePayload = header.Skip(4).Take(12).Where(b => b != 0x00).ToArray();
            var commandName        = System.Text.Encoding.ASCII.GetString(commandNamePayload);
            var ipv6 = header.Skip(16).Take(16);
            var payloadSizePayload = header.Skip(32).Take(4).ToArray();
            var payloadSize        = BitConverter.ToInt32(payloadSizePayload, 0);
            var checkSum           = header.Skip(36).Take(4);

            byte[] contentPayload = null;
            if (payloadSize > 0)
            {
                contentPayload = payload.Skip(40).Take(payloadSize).ToArray();
                SHA256 mySHA256    = SHA256.Create();
                var    newCheckSum = mySHA256.ComputeHash(mySHA256.ComputeHash(contentPayload)).Take(4);
                if (!newCheckSum.SequenceEqual(checkSum))
                {
                    throw new ParseMessageException(ErrorCodes.InvalidChecksum);
                }
            }
            else if (!checkSum.SequenceEqual(new byte[] { 0x5d, 0xf6, 0xe0, 0xe2 }))
            {
                throw new ParseMessageException(ErrorCodes.InvalidChecksum);
            }

            if (!Constants.MessageNameLst.Contains(commandName))
            {
                throw new ParseMessageException(ErrorCodes.InvalidCommandName);
            }

            Message message = null;

            if (commandName == Constants.MessageNames.Ping)
            {
                var nonce = BitConverter.ToUInt64(contentPayload, 0);
                message = new PingMessage(nonce, network);
            }
            else if (commandName == Constants.MessageNames.Addr)
            {
                message = AddrMessage.Deserialize(contentPayload, network);
            }
            else if (commandName == Constants.MessageNames.Version)
            {
                message = VersionMessage.Deserialize(contentPayload, network);
            }
            else if (commandName == Constants.MessageNames.Verack)
            {
                message = new VerackMessage(network);
            }
            else if (commandName == Constants.MessageNames.GetAddr)
            {
                message = new GetAddressMessage(network);
            }
            else if (commandName == Constants.MessageNames.Inventory)
            {
                message = InventoryMessage.Deserialize(contentPayload, network);
            }
            else if (commandName == Constants.MessageNames.Transaction)
            {
                message = TransactionMessage.Deserialize(contentPayload, network, Transactions.TransactionTypes.NoneCoinbase);
            }
            else if (commandName == Constants.MessageNames.Pong)
            {
                var nonce = BitConverter.ToUInt64(contentPayload, 0);
                message = new PongMessage(nonce, network);
            }
            else if (commandName == Constants.MessageNames.MemPool)
            {
                message = new MemPoolMessage(network);
            }
            else if (commandName == Constants.MessageNames.GetData)
            {
                message = GetDataMessage.Deserialize(contentPayload, network);
            }
            else if (commandName == Constants.MessageNames.Block)
            {
                message = BlockMessage.Deserialize(contentPayload, network);
            }
            else if (commandName == Constants.MessageNames.GetBlocks)
            {
                message = GetBlocksMessage.Deserialize(contentPayload, network);
            }
            else if (commandName == Constants.MessageNames.NotFound)
            {
                message = NotFoundMessage.Deserialize(contentPayload, network);
            }

            message.MessageHeader.Ipv6 = ipv6.ToArray();
            return(message);
        }
Exemplo n.º 5
0
 private void Launch(PeerConnector peerConnector, AddrMessage message)
 {
     peerConnector.Execute(message.Serialize());
 }