Пример #1
0
        public void TryDeserialize_FailTest(FastStreamReader stream, string expErr)
        {
            PingPayload ping = new PingPayload();

            bool b = ping.TryDeserialize(stream, out string error);

            Assert.False(b);
            Assert.Equal(expErr, error);
        }
Пример #2
0
        public void TryDeserializeTest()
        {
            PingPayload      ping   = new PingPayload();
            FastStreamReader stream = new FastStreamReader(new byte[8] {
                2, 0, 0, 0, 0, 0, 0, 0
            });
            bool b = ping.TryDeserialize(stream, out string error);

            Assert.True(b, error);
            Assert.Null(error);
            Assert.Equal(2L, ping.Nonce);
        }
        /// <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);
        }