1- namespace TonLibDotNet . Cells
1+ using System . Buffers . Binary ;
2+ using System . Security . Cryptography ;
3+
4+ namespace TonLibDotNet . Cells
25{
36 public class Cell
47 {
@@ -7,7 +10,7 @@ public class Cell
710 public const int MaxRefs = 4 ;
811
912 public Cell ( ReadOnlySpan < byte > content , bool isAugmented , ICollection < Cell > ? refs = null )
10- : this ( false , 0 , content , isAugmented , refs )
13+ : this ( false , 0 , content , isAugmented , refs )
1114 {
1215 // Nothing.
1316 }
@@ -54,11 +57,14 @@ public Cell(bool isExotic, byte level, ReadOnlySpan<byte> content, bool isAugmen
5457 this . IsAugmented = isAugmented ;
5558
5659 this . Refs = refs ? . ToList ( ) . AsReadOnly ( ) ?? new List < Cell > ( ) . AsReadOnly ( ) ;
60+ this . Depth = Refs . Count == 0 ? ( short ) 0 : ( short ) ( Refs . Max ( x => x . Depth ) + 1 ) ;
5761 }
5862
59- public bool IsExotic { get ; set ; }
63+ public bool IsExotic { get ; init ; }
64+
65+ public byte Level { get ; init ; }
6066
61- public byte Level { get ; set ; }
67+ public short Depth { get ; init ; }
6268
6369 public byte [ ] Content { get ; init ; }
6470
@@ -68,6 +74,8 @@ public Cell(bool isExotic, byte level, ReadOnlySpan<byte> content, bool isAugmen
6874
6975 public int BitsCount { get ; protected set ; }
7076
77+ private byte [ ] ? hashValue ;
78+
7179 public static ( byte refCount , bool isExotic , byte level , int dataLength , bool isAugmented ) ParseDescriptors ( byte d1 , byte d2 )
7280 {
7381 var refCount = d1 & 0b111 ;
@@ -101,12 +109,45 @@ public Slice BeginRead()
101109 {
102110 var bits = new bool [ BitsCount ] ;
103111
104- for ( var i = 0 ; i < BitsCount ; i ++ )
112+ for ( var i = 0 ; i < BitsCount ; i ++ )
105113 {
106114 bits [ i ] = ( Content [ i / 8 ] & ( 0b1000_0000 >> ( i & 0b111 ) ) ) != 0 ;
107115 }
108116
109117 return new Slice ( new ArraySegment < bool > ( bits , 0 , BitsCount ) , Refs ) ;
110118 }
119+
120+ public byte [ ] Hash ( )
121+ {
122+ if ( hashValue == null )
123+ {
124+ var bytes = new byte [ 2 + Content . Length + Refs . Count * ( 2 + 32 ) ] ;
125+
126+ var ( d1 , d2 ) = GetDescriptors ( ) ;
127+ bytes [ 0 ] = d1 ;
128+ bytes [ 1 ] = d2 ;
129+ Content . CopyTo ( bytes , 2 ) ;
130+
131+ var pos = 2 + Content . Length ;
132+
133+ Span < byte > depth = stackalloc byte [ 2 ] ;
134+ foreach ( var r in Refs )
135+ {
136+ BinaryPrimitives . WriteInt16BigEndian ( depth , r . Depth ) ;
137+ depth . CopyTo ( bytes . AsSpan ( pos , 2 ) ) ;
138+ pos += 2 ;
139+ }
140+
141+ foreach ( var r in Refs )
142+ {
143+ r . Hash ( ) . CopyTo ( bytes , pos ) ;
144+ pos += 32 ;
145+ }
146+
147+ hashValue = SHA256 . HashData ( bytes ) ;
148+ }
149+
150+ return hashValue ;
151+ }
111152 }
112153}
0 commit comments