Пример #1
0
        public void TryDeserializeTest()
        {
            var pl = new VersionPayload();

            byte[] data = Helper.HexToBytes("721101000100000000000000bc8f5e5400000000010000000000000000000000000000000000ffffc61b6409208d010000000000000000000000000000000000ffffcb0071c0208d128035cbc97953f80f2f5361746f7368693a302e392e332fcf05050001");
            bool   b    = pl.TryDeserialize(new FastStreamReader(data), out string error);

            Assert.True(b, error);
            Assert.Null(error);
        }
Пример #2
0
        private Message[] CheckVersion(Message msg)
        {
            var version = new VersionPayload();

            if (!version.TryDeserialize(new FastStreamReader(msg.PayloadData), out _))
            {
                nodeStatus.AddSmallViolation();
                return(null);
            }

            Message[] result = null;

            switch (nodeStatus.HandShake)
            {
            case HandShakeState.None:
                nodeStatus.HandShake = HandShakeState.ReceivedAndReplied;
                result = new Message[2]
                {
                    new Message(new VerackPayload(), settings.Network),
                    GetVersionMsg(version.TransmittingNodeNetworkAddress)
                };
                break;

            case HandShakeState.Sent:
                nodeStatus.HandShake = HandShakeState.SentAndReceived;
                result = new Message[1]
                {
                    new Message(new VerackPayload(), settings.Network)
                };
                break;

            case HandShakeState.SentAndConfirmed:
                nodeStatus.HandShake = HandShakeState.Finished;
                result = new Message[1]
                {
                    new Message(new VerackPayload(), settings.Network)
                };
                break;

            case HandShakeState.ReceivedAndReplied:
            case HandShakeState.SentAndReceived:
            case HandShakeState.Finished:
                nodeStatus.AddMediumViolation();
                break;

            default:
                break;
            }

            return(result);
        }
Пример #3
0
        public static IEnumerable <object[]> GetVersionCases()
        {
            var cs = new MockClientSettings()
            {
                _protoVer = 123,
                _services = NodeServiceFlags.All,
                _time     = 456,
                _port     = 789,
                _ua       = "foo",
                _relay    = true,
                _netType  = NetworkType.MainNet
            };
            var bc = new MockBlockchain()
            {
                _height = 12345
            };
            var verPl = new VersionPayload();

            Assert.True(verPl.TryDeserialize(new FastStreamReader(Helper.HexToBytes("721101000100000000000000bc8f5e5400000000010000000000000000000000000000000000ffffc61b6409208d010000000000000000000000000000000000ffffcb0071c0208d128035cbc97953f80f2f5361746f7368693a302e392e332fcf05050001")), out string error), error);
            var msg   = new Message(verPl, NetworkType.MainNet);
            var rcv   = new NetworkAddress(NodeServiceFlags.NodeNetwork, IPAddress.Parse("203.0.113.192"), 8333);
            var trs   = new NetworkAddress(NodeServiceFlags.All, IPAddress.Loopback, 789);
            var verak = new Message(new VerackPayload(), NetworkType.MainNet);
            var ver   = new Message(new VersionPayload(123, 456, rcv, trs, 0x0158a8e8ba5f3ed3, "foo", 12345, true), NetworkType.MainNet);

            yield return(new object[]
            {
                new MockNodeStatus()
                {
                    _handShakeToReturn = HandShakeState.None,
                    _handShakeToSet = HandShakeState.ReceivedAndReplied,
                    updateTime = true
                },
                cs, bc, msg, new Message[] { verak, ver }
            });

            yield return(new object[]
            {
                new MockNodeStatus()
                {
                    _handShakeToReturn = HandShakeState.ReceivedAndReplied,
                    mediumViolation = true,
                    updateTime = true
                },
                cs, bc, msg, null
            });

            yield return(new object[]
            {
                new MockNodeStatus()
                {
                    _handShakeToReturn = HandShakeState.Sent,
                    _handShakeToSet = HandShakeState.SentAndReceived,
                    updateTime = true
                },
                cs, bc, msg, new Message[] { verak }
            });

            yield return(new object[]
            {
                new MockNodeStatus()
                {
                    _handShakeToReturn = HandShakeState.SentAndConfirmed,
                    _handShakeToSet = HandShakeState.Finished,
                    updateTime = true
                },
                cs, bc, msg, new Message[] { verak }
            });

            yield return(new object[]
            {
                new MockNodeStatus()
                {
                    _handShakeToReturn = HandShakeState.SentAndReceived,
                    mediumViolation = true,
                    updateTime = true
                },
                cs, bc, msg, null
            });

            yield return(new object[]
            {
                new MockNodeStatus()
                {
                    _handShakeToReturn = HandShakeState.Finished,
                    mediumViolation = true,
                    updateTime = true
                },
                cs, bc, msg, null
            });
        }
        /// <inheritdoc/>
        public Message[] GetReply(Message msg)
        {
            if (!Enum.TryParse(Encoding.ASCII.GetString(msg.PayloadName.TrimEnd()), ignoreCase: true, out PayloadType plt))
            {
                // Undefined payload type
                nodeStatus.AddSmallViolation();
            }
            else
            {
                if (nodeStatus.HandShake != HandShakeState.Finished)
                {
                    if (plt == PayloadType.Verack)
                    {
                        var verack = new VerackPayload();
                        if (!verack.TryDeserialize(new FastStreamReader(msg.PayloadData), out _))
                        {
                            nodeStatus.AddSmallViolation();
                        }
                        else if (nodeStatus.HandShake == HandShakeState.None ||
                                 nodeStatus.HandShake == HandShakeState.Finished ||
                                 nodeStatus.HandShake == HandShakeState.SentAndConfirmed)
                        {
                            nodeStatus.AddMediumViolation();
                        }
                        else if (nodeStatus.HandShake == HandShakeState.ReceivedAndReplied ||
                                 nodeStatus.HandShake == HandShakeState.SentAndReceived)
                        {
                            nodeStatus.HandShake = HandShakeState.Finished;
                        }
                        else if (nodeStatus.HandShake == HandShakeState.Sent)
                        {
                            nodeStatus.HandShake = HandShakeState.SentAndConfirmed;
                        }
                    }
                    else if (plt == PayloadType.Version)
                    {
                        var version = new VersionPayload();
                        if (!version.TryDeserialize(new FastStreamReader(msg.PayloadData), out _))
                        {
                            nodeStatus.AddSmallViolation();
                        }
                        else if (nodeStatus.HandShake == HandShakeState.None)
                        {
                            nodeStatus.HandShake = HandShakeState.ReceivedAndReplied;
                            return(new Message[2]
                            {
                                new Message(new VerackPayload(), settings.Network),
                                GetVersionMsg(version.TransmittingNodeNetworkAddress)
                            });
                        }
                        else if (nodeStatus.HandShake == HandShakeState.Sent)
                        {
                            nodeStatus.HandShake = HandShakeState.SentAndReceived;
                            return(new Message[1]
                            {
                                new Message(new VerackPayload(), settings.Network)
                            });
                        }
                        else if (nodeStatus.HandShake == HandShakeState.SentAndConfirmed)
                        {
                            nodeStatus.HandShake = HandShakeState.Finished;
                            return(new Message[1]
                            {
                                new Message(new VerackPayload(), settings.Network)
                            });
                        }
                        else if (nodeStatus.HandShake == HandShakeState.ReceivedAndReplied ||
                                 nodeStatus.HandShake == HandShakeState.SentAndReceived ||
                                 nodeStatus.HandShake == HandShakeState.Finished)
                        {
                            nodeStatus.AddMediumViolation();
                        }
                    }
                    else
                    {
                        // HandShake is not complete but the other node is sending other types of messages
                        nodeStatus.AddMediumViolation();
                    }
                }
                else
                {
                    switch (plt)
                    {
                    case PayloadType.Addr:
                        break;

                    case PayloadType.Alert:
                        // Alert messages are ignored
                        break;

                    case PayloadType.Block:
                        break;

                    case PayloadType.BlockTxn:
                        break;

                    case PayloadType.CmpctBlock:
                        break;

                    case PayloadType.FeeFilter:
                        break;

                    case PayloadType.FilterAdd:
                        break;

                    case PayloadType.FilterClear:
                        break;

                    case PayloadType.FilterLoad:
                        break;

                    case PayloadType.GetAddr:
                        break;

                    case PayloadType.GetBlocks:
                        break;

                    case PayloadType.GetBlockTxn:
                        break;

                    case PayloadType.GetData:
                        break;

                    case PayloadType.GetHeaders:
                        break;

                    case PayloadType.Headers:
                        break;

                    case PayloadType.Inv:
                        break;

                    case PayloadType.MemPool:
                        break;

                    case PayloadType.MerkleBlock:
                        break;

                    case PayloadType.NotFound:
                        break;

                    case PayloadType.Ping:
                        var ping = new PingPayload();
                        if (!ping.TryDeserialize(new FastStreamReader(msg.PayloadData), out _))
                        {
                            nodeStatus.AddSmallViolation();
                            break;
                        }
                        return(new Message[1] {
                            new Message(new PongPayload(ping.Nonce), settings.Network)
                        });

                    case PayloadType.Pong:
                        var pong = new PongPayload();
                        if (!pong.TryDeserialize(new FastStreamReader(msg.PayloadData), out _))
                        {
                            nodeStatus.AddSmallViolation();
                            break;
                        }
                        break;

                    case PayloadType.Reject:
                        // Reject messages are ignored
                        break;

                    case PayloadType.SendCmpct:
                        break;

                    case PayloadType.SendHeaders:
                        break;

                    case PayloadType.Tx:
                        break;

                    case PayloadType.Verack:
                    case PayloadType.Version:
                        nodeStatus.AddMediumViolation();
                        break;

                    default:
                        break;
                    }
                }
            }

            nodeStatus.UpdateTime();
            return(null);
        }
Пример #5
0
        private Message[] CheckVersion(Message msg)
        {
            var version = new VersionPayload();

            if (!version.TryDeserialize(new FastStreamReader(msg.PayloadData), out _))
            {
                nodeStatus.AddSmallViolation();
                return(null);
            }

            if (version.Version < Constants.P2PMinProtoVer)
            {
                nodeStatus.SignalDisconnect();
                return(null);
            }

            nodeStatus.ProtocolVersion = version.Version;
            nodeStatus.Services        = version.Services;
            nodeStatus.Nonce           = version.Nonce;
            nodeStatus.UserAgent       = version.UserAgent;
            nodeStatus.StartHeight     = version.StartHeight;
            nodeStatus.Relay           = version.Relay;
            settings.UpdateMyIP(version.ReceivingNodeNetworkAddress.NodeIP);
            settings.Time.UpdateTime(version.Timestamp);

            Message[] result = null;

            switch (nodeStatus.HandShake)
            {
            case HandShakeState.None:
                nodeStatus.HandShake = HandShakeState.ReceivedAndReplied;
                result = new Message[2]
                {
                    new Message(new VerackPayload(), settings.Network),
                    GetVersionMsg()
                };
                break;

            case HandShakeState.Sent:
                nodeStatus.HandShake = HandShakeState.SentAndReceived;
                result = new Message[1]
                {
                    new Message(new VerackPayload(), settings.Network)
                };
                break;

            case HandShakeState.SentAndConfirmed:
                nodeStatus.HandShake = HandShakeState.Finished;
                result = GetSettingsMessages(new Message(new VerackPayload(), settings.Network));
                break;

            case HandShakeState.ReceivedAndReplied:
            case HandShakeState.SentAndReceived:
            case HandShakeState.Finished:
                nodeStatus.AddMediumViolation();
                break;

            default:
                break;
            }

            return(result);
        }