예제 #1
0
        protected override void Write(Span <byte> bytesToWrite)
        {
            _byteBuffer.EnsureWritable(bytesToWrite.Length, true);

            bytesToWrite.CopyTo(_byteBuffer.Array.AsSpan(_byteBuffer.ArrayOffset + _byteBuffer.WriterIndex, bytesToWrite.Length));
            int newWriterIndex = _byteBuffer.WriterIndex + bytesToWrite.Length;

            _byteBuffer.SetWriterIndex(newWriterIndex);
        }
예제 #2
0
        public override void Write(Span <byte> bytesToWrite)
        {
            _buffer.EnsureWritable(bytesToWrite.Length, true);

            Span <byte> target =
                _buffer.Array.AsSpan(_buffer.ArrayOffset + _buffer.WriterIndex, bytesToWrite.Length);

            bytesToWrite.CopyTo(target);
            int newWriterIndex = _buffer.WriterIndex + bytesToWrite.Length;

            _buffer.SetWriterIndex(newWriterIndex);
        }
예제 #3
0
        public void Serialize(IByteBuffer byteBuffer, StatusMessage message)
        {
            int forkIdContentLength = 0;

            if (message.ForkId.HasValue)
            {
                ForkId forkId = message.ForkId.Value;
                forkIdContentLength = Rlp.LengthOf(forkId.ForkHash) + Rlp.LengthOf(forkId.Next);
            }

            NettyRlpStream rlpStream   = new(byteBuffer);
            int            totalLength = GetLength(message, out int contentLength);

            byteBuffer.EnsureWritable(totalLength);
            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.ProtocolVersion);
            rlpStream.Encode(message.ChainId);
            rlpStream.Encode(message.TotalDifficulty);
            rlpStream.Encode(message.BestHash);
            rlpStream.Encode(message.GenesisHash);
            if (message.ForkId != null)
            {
                ForkId forkId = message.ForkId.Value;
                rlpStream.StartSequence(forkIdContentLength);
                rlpStream.Encode(forkId.ForkHash);
                rlpStream.Encode(forkId.Next);
            }
        }
        public void Serialize(IByteBuffer byteBuffer, NewBlockHashesMessage message)
        {
            NettyRlpStream nettyRlpStream = new(byteBuffer);

            int contentLength = 0;

            for (int i = 0; i < message.BlockHashes.Length; i++)
            {
                int miniContentLength = Rlp.LengthOf(message.BlockHashes[i].Item1);
                miniContentLength += Rlp.LengthOf(message.BlockHashes[i].Item2);
                contentLength     += Rlp.GetSequenceRlpLength(miniContentLength);
            }

            int totalLength = Rlp.LengthOfSequence(contentLength);

            byteBuffer.EnsureWritable(totalLength, true);

            nettyRlpStream.StartSequence(contentLength);
            for (int i = 0; i < message.BlockHashes.Length; i++)
            {
                int miniContentLength = Rlp.LengthOf(message.BlockHashes[i].Item1);
                miniContentLength += Rlp.LengthOf(message.BlockHashes[i].Item2);
                nettyRlpStream.StartSequence(miniContentLength);
                nettyRlpStream.Encode(message.BlockHashes[i].Item1);
                nettyRlpStream.Encode(message.BlockHashes[i].Item2);
            }
        }
예제 #5
0
        protected override void Encode(IChannelHandlerContext context, IMessage message, IByteBuffer output)
        {
            int iCode = PtlCodeHelper.Instance.GetCode(message.GetType());

            if (iCode <= 0)
            {
                return;
            }

            int bodyLength = message.CalculateSize();

            if (bodyLength == 0)
            {
                return;
            }

            int headerLength = sizeof(int) * 2;
            int totalLength  = bodyLength + headerLength;

            output.EnsureWritable(totalLength);
            output.WriteInt(totalLength); //长度
            output.WriteInt(iCode);       //协议号

            var buffer = output.GetIoBuffer(output.WriterIndex, bodyLength);

            using (MemoryStream memStream = new MemoryStream(buffer.Array, buffer.Offset, buffer.Count))
            {
                message.WriteTo(memStream);
                output.SetWriterIndex(output.WriterIndex + (int)memStream.Length);
            }
        }
예제 #6
0
        /// <summary>
        /// Allocate or expand the decompression buffer, without exceeding the maximum allocation.
        /// Calls <see cref="DecompressionBufferExhausted(IByteBuffer)"/> if the buffer is full and cannot be expanded further.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="buffer"></param>
        /// <param name="preferredSize"></param>
        /// <returns></returns>
        protected IByteBuffer PrepareDecompressBuffer(IChannelHandlerContext ctx, IByteBuffer buffer, int preferredSize)
        {
            if (buffer is null)
            {
                if (0u >= (uint)_maxAllocation)
                {
                    return(ctx.Allocator.HeapBuffer(preferredSize));
                }

                return(ctx.Allocator.HeapBuffer(Math.Min(preferredSize, _maxAllocation), _maxAllocation));
            }

            // this always expands the buffer if possible, even if the expansion is less than preferredSize
            // we throw the exception only if the buffer could not be expanded at all
            // this means that one final attempt to deserialize will always be made with the buffer at maxAllocation
            if (buffer.EnsureWritable(preferredSize, true) == 1)
            {
                // buffer must be consumed so subclasses don't add it to output
                // we therefore duplicate it when calling decompressionBufferExhausted() to guarantee non-interference
                // but wait until after to consume it so the subclass can tell how much output is really in the buffer
                DecompressionBufferExhausted(buffer.Duplicate());
                _ = buffer.SkipBytes(buffer.ReadableBytes);
                CThrowHelper.ThrowDecompressionException_Decompression_buffer_has_reached_maximum_size(buffer.MaxCapacity);
            }

            return(buffer);
        }
예제 #7
0
        public void Serialize(IByteBuffer byteBuffer, ContractCodesMessage message)
        {
            int innerLength = 0;

            for (int i = 0; i < message.Codes.Length; i++)
            {
                innerLength += Rlp.LengthOf(message.Codes[i]);
            }
            int contentLength =
                Rlp.LengthOf(message.RequestId) +
                Rlp.LengthOf(message.BufferValue) +
                Rlp.GetSequenceRlpLength(innerLength);

            int totalLength = Rlp.GetSequenceRlpLength(contentLength);

            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            byteBuffer.EnsureWritable(totalLength);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.RequestId);
            rlpStream.Encode(message.BufferValue);
            rlpStream.StartSequence(innerLength);
            for (int i = 0; i < message.Codes.Length; i++)
            {
                rlpStream.Encode(message.Codes[i]);
            }
        }
예제 #8
0
        public void Serialize(IByteBuffer byteBuffer, GetContractCodesMessage message)
        {
            // note: If there are any changes to how a hash is encoded, this will break (compression?)
            // calling LengthOf for each hash would be more resistant to future changes, if we think there will be any
            int requestLength     = Rlp.LengthOf(Keccak.OfAnEmptyString) * 2;
            int allRequestsLength = Rlp.GetSequenceRlpLength(requestLength) * message.Requests.Length;
            int contentLength     =
                Rlp.LengthOf(message.RequestId) +
                Rlp.GetSequenceRlpLength(allRequestsLength);

            int totalLength = Rlp.GetSequenceRlpLength(contentLength);

            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            byteBuffer.EnsureWritable(totalLength);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.RequestId);

            rlpStream.StartSequence(allRequestsLength);
            foreach (CodeRequest request in message.Requests)
            {
                rlpStream.StartSequence(requestLength);
                rlpStream.Encode(request.BlockHash);
                rlpStream.Encode(request.AccountKey);
            }
        }
예제 #9
0
        public void Serialize(IByteBuffer byteBuffer, GetBlockHeadersMessage message)
        {
            int contentLength = message.StartingBlockHash == null?Rlp.LengthOf(message.StartingBlockNumber) : Rlp.LengthOf(message.StartingBlockHash);

            contentLength += Rlp.LengthOf(message.MaxHeaders);
            contentLength += Rlp.LengthOf(message.Skip);
            contentLength += Rlp.LengthOf(message.Reverse);

            int totalLength = Rlp.GetSequenceRlpLength(contentLength);

            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            byteBuffer.EnsureWritable(totalLength, true);

            rlpStream.StartSequence(contentLength);
            if (message.StartingBlockHash == null)
            {
                rlpStream.Encode(message.StartingBlockNumber);
            }
            else
            {
                rlpStream.Encode(message.StartingBlockHash);
            }

            rlpStream.Encode(message.MaxHeaders);
            rlpStream.Encode(message.Skip);
            rlpStream.Encode(message.Reverse);
        }
        public void Serialize(IByteBuffer byteBuffer, BlockWitnessHashesMessage message)
        {
            NettyRlpStream nettyRlpStream = new NettyRlpStream(byteBuffer);

            int hashesContentLength = message.Hashes?.Length * Rlp.LengthOfKeccakRlp ?? 0;
            int contentLength       = Rlp.LengthOfSequence(hashesContentLength);

            contentLength += Rlp.LengthOf(message.RequestId);
            int totalLength = Rlp.LengthOfSequence(contentLength);

            byteBuffer.EnsureWritable(totalLength, true);
            nettyRlpStream.StartSequence(contentLength);
            nettyRlpStream.Encode(message.RequestId);
            if (message.Hashes == null)
            {
                nettyRlpStream.EncodeNullObject();
            }
            else
            {
                nettyRlpStream.StartSequence(hashesContentLength);
                foreach (Keccak keccak in message.Hashes)
                {
                    nettyRlpStream.Encode(keccak);
                }
            }
        }
예제 #11
0
        public void Serialize(IByteBuffer byteBuffer, GetHelperTrieProofsMessage message)
        {
            int innerLength = 0;

            foreach (var request in message.Requests)
            {
                innerLength += Rlp.GetSequenceRlpLength(GetRequestLength(request));
            }
            int contentLength = Rlp.LengthOf(message.RequestId) +
                                Rlp.GetSequenceRlpLength(innerLength);

            int totalLength = Rlp.GetSequenceRlpLength(contentLength);

            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            byteBuffer.EnsureWritable(totalLength);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.RequestId);
            rlpStream.StartSequence(innerLength);
            foreach (var request in message.Requests)
            {
                rlpStream.StartSequence(GetRequestLength(request));
                rlpStream.Encode((int)request.SubType);
                rlpStream.Encode(request.SectionIndex);
                rlpStream.Encode(request.Key);
                rlpStream.Encode(request.FromLevel);
                rlpStream.Encode(request.AuxiliaryData);
            }
        }
        public void EnsureWritableWithNotEnoughSpaceShouldThrow()
        {
            IByteBuffer buf = this.NewBuffer(1, 10);

            Assert.Throws <IndexOutOfRangeException>(() => buf.EnsureWritable(11));
            buf.Release();
        }
        public void Serialize(IByteBuffer byteBuffer, GetTrieNodesMessage message)
        {
            (int contentLength, int allPathsLength, int[] pathsLengths) = CalculateLengths(message);

            byteBuffer.EnsureWritable(Rlp.LengthOfSequence(contentLength), true);
            NettyRlpStream stream = new (byteBuffer);

            stream.StartSequence(contentLength);

            stream.Encode(message.RequestId);
            stream.Encode(message.RootHash);

            if (message.Paths == null || message.Paths.Length == 0)
            {
                stream.EncodeNullObject();
            }
            else
            {
                stream.StartSequence(allPathsLength);

                for (int i = 0; i < message.Paths.Length; i++)
                {
                    PathGroup group = message.Paths[i];

                    stream.StartSequence(pathsLengths[i]);

                    for (int j = 0; j < group.Group.Length; j++)
                    {
                        stream.Encode(group.Group[j]);
                    }
                }
            }

            stream.Encode(message.Bytes);
        }
        public void EnsureWritableWithEnoughSpaceShouldNotThrow()
        {
            IByteBuffer buf = this.NewBuffer(1, 10);

            buf.EnsureWritable(3);
            Assert.True(buf.WritableBytes >= 3);
            buf.Release();
        }
예제 #15
0
        public void EnsureWritableWithNotEnoughSpaceShouldThrow()
        {
            IByteBuffer slice     = this.NewBuffer(10);
            IByteBuffer unwrapped = slice.Unwrap();

            unwrapped.SetWriterIndex(unwrapped.WriterIndex + 5);
            Assert.Throws <IndexOutOfRangeException>(() => slice.EnsureWritable(1));
            slice.Release();
        }
예제 #16
0
        public void Serialize(IByteBuffer byteBuffer, GetBlockWitnessHashesMessage message)
        {
            NettyRlpStream nettyRlpStream = new(byteBuffer);
            int            totalLength    = GetLength(message, out int contentLength);

            byteBuffer.EnsureWritable(totalLength, true);
            nettyRlpStream.StartSequence(contentLength);
            nettyRlpStream.Encode(message.RequestId);
            nettyRlpStream.Encode(message.BlockHash);
        }
        public void Serialize(IByteBuffer byteBuffer, TEth66Message message)
        {
            int length = GetLength(message, out int contentLength);

            byteBuffer.EnsureWritable(length, true);
            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.RequestId);
            _ethMessageSerializer.Serialize(byteBuffer, message.EthMessage);
        }
예제 #18
0
        protected NettyRlpStream GetRlpStreamAndStartSequence(IByteBuffer byteBuffer, T msg)
        {
            int totalLength = GetLength(msg, out int contentLength);

            byteBuffer.EnsureWritable(totalLength, true);
            NettyRlpStream stream = new (byteBuffer);

            stream.StartSequence(contentLength);

            return(stream);
        }
예제 #19
0
        public void Serialize(IByteBuffer byteBuffer, GetBlockBodiesMessage message)
        {
            int length = GetLength(message, out int contentLength);

            byteBuffer.EnsureWritable(length, true);
            NettyRlpStream nettyRlpStream = new(byteBuffer);

            nettyRlpStream.StartSequence(contentLength);
            for (int i = 0; i < message.BlockHashes.Count; i++)
            {
                nettyRlpStream.Encode(message.BlockHashes[i]);
            }
        }
        public void Serialize(IByteBuffer byteBuffer, NodeDataMessage message)
        {
            int length = GetLength(message, out int contentLength);

            byteBuffer.EnsureWritable(length, true);
            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            rlpStream.StartSequence(contentLength);
            for (int i = 0; i < message.Data.Length; i++)
            {
                rlpStream.Encode(message.Data[i]);
            }
        }
        public void Serialize(IByteBuffer byteBuffer, NewBlockMessage message)
        {
            int       contentLength = _blockDecoder.GetLength(message.Block, RlpBehaviors.None) + Rlp.LengthOf(message.TotalDifficulty);
            RlpStream rlpStream     = new NettyRlpStream(byteBuffer);

            int totalLength = Rlp.LengthOfSequence(contentLength);

            byteBuffer.EnsureWritable(totalLength, true);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.Block);
            rlpStream.Encode(message.TotalDifficulty);
        }
예제 #22
0
        public void Serialize(IByteBuffer byteBuffer, StorageRangeMessage message)
        {
            (int contentLength, int allSlotsLength, int[] accountSlotsLengths, int proofsLength) = CalculateLengths(message);

            byteBuffer.EnsureWritable(Rlp.LengthOfSequence(contentLength), true);
            NettyRlpStream stream = new(byteBuffer);

            stream.StartSequence(contentLength);

            stream.Encode(message.RequestId);

            if (message.Slots == null || message.Slots.Length == 0)
            {
                stream.EncodeNullObject();
            }
            else
            {
                stream.StartSequence(allSlotsLength);

                for (int i = 0; i < message.Slots.Length; i++)
                {
                    stream.StartSequence(accountSlotsLengths[i]);

                    PathWithStorageSlot[] accountSlots = message.Slots[i];

                    for (int j = 0; j < accountSlots.Length; j++)
                    {
                        var slot = accountSlots[j];

                        int itemLength = Rlp.LengthOf(slot.Path) + Rlp.LengthOf(slot.SlotRlpValue);

                        stream.StartSequence(itemLength);
                        stream.Encode(slot.Path);
                        stream.Encode(slot.SlotRlpValue);
                    }
                }
            }

            if (message.Proofs == null || message.Proofs.Length == 0)
            {
                stream.EncodeNullObject();
            }
            else
            {
                stream.StartSequence(proofsLength);
                for (int i = 0; i < message.Proofs.Length; i++)
                {
                    stream.Encode(message.Proofs[i]);
                }
            }
        }
예제 #23
0
        public void Serialize(IByteBuffer byteBuffer, AnnounceMessage message)
        {
            int length = GetLength(message, out int contentLength);

            byteBuffer.EnsureWritable(length);
            NettyRlpStream rlpStream = new(byteBuffer);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.HeadHash);
            rlpStream.Encode(message.HeadBlockNo);
            rlpStream.Encode(message.TotalDifficulty);
            rlpStream.Encode(message.ReorgDepth);
            rlpStream.Encode(Rlp.OfEmptySequence);
        }
        public void Serialize(IByteBuffer byteBuffer, ByteCodesMessage message)
        {
            (int contentLength, int codesLength) = GetLength(message);
            byteBuffer.EnsureWritable(Rlp.LengthOfSequence(contentLength), true);
            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.RequestId);
            rlpStream.StartSequence(codesLength);
            for (int i = 0; i < message.Codes.Length; i++)
            {
                rlpStream.Encode(message.Codes[i]);
            }
        }
        public void Serialize(IByteBuffer byteBuffer, GetBlockBodiesMessage message)
        {
            Eth.V62.GetBlockBodiesMessageSerializer ethSerializer = new Eth.V62.GetBlockBodiesMessageSerializer();
            Rlp ethMessage    = new Rlp(ethSerializer.Serialize(message.EthMessage));
            int contentLength = Rlp.LengthOf(message.RequestId) + ethMessage.Length;

            int totalLength = Rlp.GetSequenceRlpLength(contentLength);

            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            byteBuffer.EnsureWritable(totalLength);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.RequestId);
            rlpStream.Encode(ethMessage);
        }
        public void Serialize(IByteBuffer byteBuffer, GetReceiptsMessage message)
        {
            Eth.V63.Messages.GetReceiptsMessageSerializer ethSerializer = new();
            Rlp ethMessage    = new(ethSerializer.Serialize(message.EthMessage));
            int contentLength = Rlp.LengthOf(message.RequestId) + ethMessage.Length;

            int totalLength = Rlp.LengthOfSequence(contentLength);

            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            byteBuffer.EnsureWritable(totalLength);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.RequestId);
            rlpStream.Encode(ethMessage);
        }
        public void Serialize <T>(T message, IByteBuffer byteBuffer) where T : MessageBase
        {
            IMessageSerializer <T>     serializer     = GetSerializer <T>();
            IZeroMessageSerializer <T> zeroSerializer = serializer as IZeroMessageSerializer <T>;

            if (zeroSerializer != null)
            {
                zeroSerializer.Serialize(byteBuffer, message);
            }
            else
            {
                byte[] serialized = serializer.Serialize(message);
                byteBuffer.EnsureWritable(serialized.Length, true);
                byteBuffer.WriteBytes(serialized);
            }
        }
예제 #28
0
        public void EnsureWritableWithEnoughSpaceShouldNotThrow()
        {
            IByteBuffer slice     = this.NewBuffer(10);
            IByteBuffer unwrapped = slice.Unwrap();

            unwrapped.SetWriterIndex(unwrapped.WriterIndex + 5);
            slice.SetWriterIndex(slice.ReaderIndex);

            // Run ensureWritable and verify this doesn't change any indexes.
            int originalWriterIndex   = slice.WriterIndex;
            int originalReadableBytes = slice.ReadableBytes;

            slice.EnsureWritable(originalWriterIndex - slice.WriterIndex);
            Assert.Equal(originalWriterIndex, slice.WriterIndex);
            Assert.Equal(originalReadableBytes, slice.ReadableBytes);
            slice.Release();
        }
        public void Serialize(IByteBuffer byteBuffer, ReceiptsMessage message)
        {
            Eth.V63.ReceiptsMessageSerializer ethSerializer = new Eth.V63.ReceiptsMessageSerializer(_specProvider);
            Rlp ethMessage    = new Rlp(ethSerializer.Serialize(message.EthMessage));
            int contentLength = Rlp.LengthOf(message.RequestId) + Rlp.LengthOf(message.BufferValue) + ethMessage.Length;

            int totalLength = Rlp.GetSequenceRlpLength(contentLength);

            RlpStream rlpStream = new NettyRlpStream(byteBuffer);

            byteBuffer.EnsureWritable(totalLength);

            rlpStream.StartSequence(contentLength);
            rlpStream.Encode(message.RequestId);
            rlpStream.Encode(message.BufferValue);
            rlpStream.Encode(ethMessage);
        }
예제 #30
0
        public static void MakeSpace(this IByteBuffer output, int length, string reason = null)
        {
            if (output.WritableBytes < length)
            {
                if (output.ReaderIndex == output.WriterIndex)
                {
                    output.Clear();
                }
                else
                {
                    output.DiscardReadBytes();
                }

                if (output.WritableBytes < length)
                {
                    output.EnsureWritable(length, true);
                }
            }
        }