예제 #1
0
        private SerializeResult SerializeRecursive(SszElement element)
        {
            switch (element)
            {
            //case null:
            //    {
            //        return new SerializeResult(Array.Empty<byte>(), isVariableSize: false);
            //    }
            case SszBasicElement basic:
            {
                return(new SerializeResult(basic.GetBytes(), isVariableSize: false));
            }

            case SszBitvector vector:
            {
                return(new SerializeResult(vector.GetBytes(), isVariableSize: false));
            }

            case SszBitlist list:
            {
                return(new SerializeResult(list.GetBytes(), isVariableSize: true));
            }

            case SszBasicVector vector:
            {
                return(new SerializeResult(vector.GetBytes(), isVariableSize: false));
            }

            case SszBasicList list:
            {
                return(new SerializeResult(list.GetBytes(), isVariableSize: true));
            }

            case SszVector vector:
            {
                return(SerializeCombineValues(vector.GetValues()));
            }

            case SszList list:
            {
                return(SerializeCombineValues(list.GetValues()));
            }

            case SszContainer container:
            {
                return(SerializeCombineValues(container.GetValues()));
            }

            default:
            {
                throw new NotSupportedException();
            }
            }
        }
예제 #2
0
        private ReadOnlySpan <byte> HashTreeRootRecursive(SszElement element, Stack <int> context)
        {
            switch (element)
            {
            //case null:
            //    {
            //        return new byte[BytesPerChunk];
            //    }
            case SszBasicElement basic:
            {
                var bytes        = basic.GetBytes();
                var packed       = Pack(bytes);
                var paddedLength = (ulong)packed.Length;
                return(Merkleize(packed, paddedLength));
            }

            case SszBasicVector vector:
            {
                var bytes        = vector.GetBytes();
                var packed       = Pack(bytes);
                var paddedLength = (ulong)packed.Length;
                return(Merkleize(packed, paddedLength));
            }

            case SszBitvector vector:
            {
                var bytes        = vector.BitfieldBytes();
                var packed       = Pack(bytes);
                var paddedLength =
                    (((ulong)bytes.Length + BytesPerChunk - 1) / BytesPerChunk) * BytesPerChunk;
                return(Merkleize(packed, paddedLength));
            }

            case SszBasicList list:
            {
                var bytes        = list.GetBytes();
                var packed       = Pack(bytes);
                var paddedLength =
                    ((list.ByteLimit + BytesPerChunk - 1) / BytesPerChunk) * BytesPerChunk;
                var merkle = Merkleize(packed, paddedLength);
                return(MixInLength(merkle, (uint)list.Length));
            }

            case SszBitlist list:
            {
                var bytes        = list.BitfieldBytes();
                var packed       = Pack(bytes);
                var paddedLength =
                    ((list.ByteLimit + BytesPerChunk - 1) / BytesPerChunk) * BytesPerChunk;
                var merkle = Merkleize(packed, paddedLength);
                return(MixInLength(merkle, (uint)list.Length));
            }

            case SszVector vector:
            {
                byte[] bytes;
                using (var memory = new MemoryStream())
                {
                    var index = 0;
                    foreach (var value in vector.GetValues())
                    {
                        context.Push(index++);
                        memory.Write(HashTreeRootRecursive(value, context));
                        context.Pop();
                    }
                    bytes = memory.ToArray();
                }
                return(Merkleize(bytes, (ulong)bytes.Length));
            }

            case SszContainer container:
            {
                byte[] bytes;
                using (var memory = new MemoryStream())
                {
                    var index = 0;
                    foreach (var value in container.GetValues())
                    {
                        context.Push(index++);
                        memory.Write(HashTreeRootRecursive(value, context));
                        if (memory.Length % BytesPerChunk != 0)
                        {
                            throw new Exception($"Chunks must by a multiple of {BytesPerChunk} bytes when adding to container.");
                        }
                        context.Pop();
                    }
                    bytes = memory.ToArray();
                }
                return(Merkleize(bytes, (ulong)bytes.Length));
            }

            case SszList list:
            {
                byte[] bytes;
                using (var memory = new MemoryStream())
                {
                    var index = 0;
                    foreach (var value in list.GetValues())
                    {
                        context.Push(index++);
                        memory.Write(HashTreeRootRecursive(value, context));
                        context.Pop();
                    }
                    bytes = memory.ToArray();
                }
                var paddedLength =
                    ((list.ByteLimit + BytesPerChunk - 1) / BytesPerChunk) * BytesPerChunk;
                var merkle = Merkleize(bytes, paddedLength);
                return(MixInLength(merkle, (uint)list.Length));
            }

            default:
            {
                throw new NotImplementedException();
            }
            }
        }
예제 #3
0
 public SszTree(SszElement rootElement)
 {
     RootElement = rootElement;
 }