Пример #1
0
        public void GetCurrentIndexTest()
        {
            var stream = new FastStreamReader(new byte[10]);

            Assert.Equal(0, stream.GetCurrentIndex());
            _ = stream.TryReadByteArray(3, out _);
            Assert.Equal(3, stream.GetCurrentIndex());
            _ = stream.TryReadByteArray(5, out _);
            Assert.Equal(8, stream.GetCurrentIndex());
            _ = stream.TryReadByteArray(2, out _);
            Assert.Equal(10, stream.GetCurrentIndex());
        }
Пример #2
0
        public void GetRemainingBytesCountTest()
        {
            var stream = new FastStreamReader(new byte[10]);

            Assert.Equal(10, stream.GetRemainingBytesCount());
            _ = stream.TryReadByteArray(2, out _);
            Assert.Equal(8, stream.GetRemainingBytesCount());
            _ = stream.TryReadByteArray(1, out _);
            Assert.Equal(7, stream.GetRemainingBytesCount());
            _ = stream.TryReadByteArray(7, out _);
            Assert.Equal(0, stream.GetRemainingBytesCount());
        }
Пример #3
0
        /// <summary>
        /// Reads the <see cref="OP.RETURN"/> byte and the following specified data length from the specified offset.
        /// The return value indicates success.
        /// </summary>
        /// <param name="stream">Stream to use</param>
        /// <param name="length">
        /// Length of the data to read. Must be at least 1 byte, the <see cref="OP.RETURN"/> itself.
        /// (note that <see cref="OP.RETURN"/> doesn't have any internal mechanism to tell us how much data it holds,
        /// the length is instead specified before <see cref="OP.RETURN"/> as the length of the whole script).
        /// </param>
        /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure).</param>
        /// <returns>True if reading was successful, false if otherwise.</returns>
        public bool TryRead(FastStreamReader stream, int length, out string error)
        {
            if (stream is null)
            {
                error = "Stream can not be null.";
                return(false);
            }

            // We need the first byte of "data" to be 0x6a so we only peek at that byte.
            if (!stream.TryPeekByte(out byte firstByte))
            {
                error = Err.EndOfStream;
                return(false);
            }
            if (firstByte != (byte)OP.RETURN)
            {
                error = "Stream doesn't start with appropriate (OP_Return) byte.";
                return(false);
            }
            if (length < 1)
            {
                error = "OP_RETURN script length must be at least 1 byte.";
                return(false);
            }

            if (!stream.TryReadByteArray(length, out data))
            {
                error = Err.EndOfStream;
                return(false);
            }

            error = null;
            return(true);
        }
Пример #4
0
        public void TryReadByteArray_FailTest()
        {
            var  stream = new FastStreamReader(new byte[9]);
            bool b      = stream.TryReadByteArray(10, out byte[] actual);

            Assert.False(b);
            Assert.Null(actual);
        }
Пример #5
0
 private void Init()
 {
     byte[] data = fileMan.ReadData(DbName);
     if (data is not null && data.Length != 0)
     {
         var stream = new FastStreamReader(data);
         while (true)
         {
             var utxo = new Utxo();
             if (stream.TryReadByteArray(32, out byte[] hash) && utxo.TryDeserialize(stream, out _))
Пример #6
0
        public void TryReadByteArrayTest()
        {
            var  stream = new FastStreamReader(Helper.GetBytes(12));
            bool b      = stream.TryReadByteArray(10, out byte[] actual);

            byte[] expected = Helper.GetBytes(10);

            Assert.True(b);
            Assert.Equal(expected, actual);
            Assert.Equal(10, stream.GetCurrentIndex());
        }
Пример #7
0
        public void CheckRemainingTest()
        {
            var stream = new FastStreamReader(new byte[5]);

            Assert.True(stream.CheckRemaining(1));
            Assert.True(stream.CheckRemaining(5));
            Assert.False(stream.CheckRemaining(6));

            _ = stream.TryReadByteArray(2, out _);
            Assert.True(stream.CheckRemaining(1));
            Assert.False(stream.CheckRemaining(5));
            Assert.False(stream.CheckRemaining(6));
        }
Пример #8
0
        /// <summary>
        /// Creates a new instance of <see cref="Signature"/> by reading it from a DER encoded byte array with loose rules.
        /// Return value indicates success.
        /// </summary>
        /// <param name="derSig">Signature bytes encoded using DER encoding</param>
        /// <param name="result">Resulting signature (null in case of failure)</param>
        /// <param name="error">Error message (null if sucessful, otherwise contains information about the failure)</param>
        /// <returns>True if successful, otherwise false.</returns>
        public static bool TryReadLoose(byte[] derSig, out Signature result, out string error)
        {
            result = null;

            if (derSig == null)
            {
                error = "Byte array can not be null.";
                return(false);
            }

            // Min = 3006[0201(01)0201(01)]-01
            if (derSig.Length < 9)
            {
                // This also handles the Length == 0 case
                error = "Invalid DER encoding length.";
                return(false);
            }

            FastStreamReader stream = new FastStreamReader(derSig);

            if (!stream.TryReadByte(out byte seqTag) || seqTag != SequenceTag)
            {
                error = "Sequence tag was not found in DER encoded signature.";
                return(false);
            }

            if (!stream.TryReadDerLength(out int seqLen))
            {
                error = "Invalid sequence length.";
                return(false);
            }

            if (seqLen < 6 || !stream.CheckRemaining(seqLen + 1)) // +1 is the SigHash byte (at least 1 byte)
            {
                error = "Invalid total length according to sequence length.";
                return(false);
            }

            if (!stream.TryReadByte(out byte intTag1) || intTag1 != IntegerTag)
            {
                error = "First integer tag was not found in DER encoded signature.";
                return(false);
            }

            if (!stream.TryReadDerLength(out int rLen) || rLen == 0)
            {
                error = "Invalid R length.";
                return(false);
            }

            if (!stream.TryReadByteArray(rLen, out byte[] rBa))
Пример #9
0
        public override bool TryDeserialize(FastStreamReader stream, out string error)
        {
            int actualIndex = stream.GetCurrentIndex();

            Assert.Equal(expectedIndex, actualIndex);

            if (!stream.TryReadByteArray(bytesToRead, out _))
            {
                Assert.True(false, "Stream doesn't have enough bytes.");
            }

            error = retError;
            return(string.IsNullOrEmpty(retError));
        }
Пример #10
0
        /// <summary>
        /// Reads and processes the given bytes from the given buffer and provided length.
        /// </summary>
        /// <param name="buffer">Buffer containing the received bytes</param>
        /// <param name="len">Number of bytes received</param>
        /// <param name="offert">Offset inside <paramref name="buffer"/> parameter where the data begins</param>
        public void ReadBytes(byte[] buffer, int len, int offert)
        {
            if (len > 0 && buffer != null)
            {
                if (IsReceiveCompleted && len >= Constants.MessageHeaderSize)
                {
                    FastStreamReader stream = new FastStreamReader(buffer, offert, len);
                    if (stream.FindAndSkip(magicBytes))
                    {
                        int rem = stream.GetRemainingBytesCount();
                        if (rem >= Constants.MessageHeaderSize)
                        {
                            var msg = new Message(netType);
                            Message.ReadResult res = msg.Read(stream);
                            if (res == Message.ReadResult.Success)
                            {
                                IsReceiveCompleted = true;

                                Message[] reply = replyManager.GetReply(msg);
                                if (reply != null)
                                {
                                    foreach (var item in reply)
                                    {
                                        toSendQueue.Enqueue(item);
                                    }
                                }

                                // TODO: handle received message here. eg. write received block to disk,...

                                // Handle remaining data
                                if (stream.GetRemainingBytesCount() > 0)
                                {
                                    _ = stream.TryReadByteArray(stream.GetRemainingBytesCount(), out tempHolder);
                                    ReadBytes(tempHolder, tempHolder.Length, 0);
                                }
                                else
                                {
                                    tempHolder = null;
                                }
                            }
                            else if (res == Message.ReadResult.NotEnoughBytes)
                            {
                                IsReceiveCompleted = false;
                                tempHolder         = new byte[len];
                                Buffer.BlockCopy(buffer, 0, tempHolder, 0, len);
                            }
                            else // TODO: add violation (invalid message)
                            {
                            }
                        }
                        else if (rem != 0)
                        {
                            stream.TryReadByteArray(rem, out tempHolder);
                            IsReceiveCompleted = false;
                        }
                    }
                    else // TODO: add violation (No magic was found)
                    {
                    }
                    // TODO: some sort of point system is needed to give negative points to malicious nodes
                    //       eg. sending garbage bytes which is what is caught in the "else" part of the "if" above
                }
                else
                {
                    if (tempHolder == null)
                    {
                        tempHolder = new byte[len];
                        Buffer.BlockCopy(buffer, 0, tempHolder, 0, len);
                    }
                    else
                    {
                        byte[] temp = new byte[tempHolder.Length + len];
                        Buffer.BlockCopy(tempHolder, 0, temp, 0, tempHolder.Length);
                        Buffer.BlockCopy(buffer, 0, temp, tempHolder.Length, len);
                        tempHolder = temp;
                    }

                    if (tempHolder.Length >= Constants.MessageHeaderSize)
                    {
                        IsReceiveCompleted = true;
                        ReadBytes(tempHolder, tempHolder.Length, 0);
                    }
                    else
                    {
                        IsReceiveCompleted = false;
                    }
                }
            }
        }