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(); } } }
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(); } } }
public SszTree(SszElement rootElement) { RootElement = rootElement; }