Пример #1
0
        private Message Launch(PeerConnector peerConnector, VersionMessage message)
        {
            var payload = peerConnector.Execute(message.Serialize());
            var result  = _messageParser.Parse(payload.ToArray());

            if (result.GetCommandName() == Constants.MessageNames.Version)
            {
                var versionMessage = result as VersionMessage;
                var verackMessage  = new VerackMessage(message.MessageHeader.Network);
                payload = peerConnector.Execute(verackMessage.Serialize());
                result  = _messageParser.Parse(payload.ToArray());
                if (result.GetCommandName() == Constants.MessageNames.Verack)
                {
                    return(result);
                }
            }

            return(null);
        }
Пример #2
0
        async ValueTask <bool> INetworkMessageHandler <VerackMessage> .ProcessMessageAsync(VerackMessage verack, CancellationToken cancellation)
        {
            if (!_status.IsVersionSent)
            {
                Misbehave(10, "Received verack without having sent a version.");
                return(false);
            }

            if (_status.VersionAckReceived)
            {
                Misbehave(1, "Received additional verack, a previous one has been received.");
                return(false);
            }

            await _status.VerAckReceivedAsync().ConfigureAwait(false);

            // will prevent to handle version messages to other Processors
            return(false);
        }
        async ValueTask <bool> INetworkMessageHandler <VerackMessage> .ProcessMessageAsync(VerackMessage verack, CancellationToken cancellation)
        {
            if (!_status.IsVersionSent)
            {
                Misbehave(10, "Received verack without having sent a version.");
                return(false);
            }

            if (_status.VersionAckReceived)
            {
                //https://github.com/bitcoin/bitcoin/blob/d9a45500018fa4fd52c9c9326f79521d93d99abb/src/net_processing.cpp#L1909-L1914
                Misbehave(1, "Received additional verack, a previous one has been received.");
                return(false);
            }

            await _status.VerAckReceivedAsync().ConfigureAwait(false);

            // will prevent to handle version messages to other Processors
            return(false);
        }
Пример #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);
        }