@@ -35,6 +35,7 @@ public sealed class Header : IEquatable<Header>, IVerifiable
35
35
private uint index ;
36
36
private byte primaryIndex ;
37
37
private UInt160 nextConsensus ;
38
+ private UInt256 prevStateRoot ;
38
39
39
40
/// <summary>
40
41
/// The witness of the block.
@@ -113,6 +114,15 @@ public UInt160 NextConsensus
113
114
set { nextConsensus = value ; _hash = null ; }
114
115
}
115
116
117
+ /// <summary>
118
+ /// MPT root hash got after the previous block processing.
119
+ /// </summary>
120
+ public UInt256 PrevStateRoot
121
+ {
122
+ get => prevStateRoot ;
123
+ set { prevStateRoot = value ; _hash = null ; }
124
+ }
125
+
116
126
private UInt256 _hash = null ;
117
127
118
128
/// <inheritdoc/>
@@ -137,6 +147,7 @@ public UInt256 Hash
137
147
sizeof ( uint ) + // Index
138
148
sizeof ( byte ) + // PrimaryIndex
139
149
UInt160 . Length + // NextConsensus
150
+ ( version == ( uint ) BlockVersion . V0 ? 0 : UInt256 . Length ) + // PrevStateRoot
140
151
( Witness is null ? 1 : 1 + Witness . Size ) ; // Witness, cannot be null for valid header
141
152
142
153
Witness [ ] IVerifiable . Witnesses
@@ -166,14 +177,16 @@ void IVerifiable.DeserializeUnsigned(ref MemoryReader reader)
166
177
{
167
178
_hash = null ;
168
179
version = reader . ReadUInt32 ( ) ;
169
- if ( version > 0 ) throw new FormatException ( $ "`version`({ version } ) in Header must be 0") ;
180
+ if ( version > ( uint ) BlockVersion . V1 ) throw new FormatException ( $ "`version`({ version } ) in Header must be 0 or 1 ") ;
170
181
prevHash = reader . ReadSerializable < UInt256 > ( ) ;
171
182
merkleRoot = reader . ReadSerializable < UInt256 > ( ) ;
172
183
timestamp = reader . ReadUInt64 ( ) ;
173
184
nonce = reader . ReadUInt64 ( ) ;
174
185
index = reader . ReadUInt32 ( ) ;
175
186
primaryIndex = reader . ReadByte ( ) ;
176
187
nextConsensus = reader . ReadSerializable < UInt160 > ( ) ;
188
+ if ( version == ( uint ) BlockVersion . V1 )
189
+ prevStateRoot = reader . ReadSerializable < UInt256 > ( ) ;
177
190
}
178
191
179
192
public bool Equals ( Header other )
@@ -217,6 +230,8 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer)
217
230
writer . Write ( index ) ;
218
231
writer . Write ( primaryIndex ) ;
219
232
writer . Write ( nextConsensus ) ;
233
+ if ( version == ( uint ) BlockVersion . V1 )
234
+ writer . Write ( prevStateRoot ) ;
220
235
}
221
236
222
237
/// <summary>
@@ -238,13 +253,17 @@ public JObject ToJson(ProtocolSettings settings)
238
253
json [ "primary" ] = primaryIndex ;
239
254
json [ "nextconsensus" ] = nextConsensus . ToAddress ( settings . AddressVersion ) ;
240
255
json [ "witnesses" ] = new JArray ( Witness . ToJson ( ) ) ;
256
+ if ( version == ( uint ) BlockVersion . V1 )
257
+ json [ "previousstateroot" ] = prevStateRoot . ToString ( ) ;
241
258
return json ;
242
259
}
243
260
244
261
internal bool Verify ( ProtocolSettings settings , DataCache snapshot )
245
262
{
246
263
if ( primaryIndex >= settings . ValidatorsCount )
247
264
return false ;
265
+ if ( version != ( uint ) GetExpectedVersion ( settings ) )
266
+ return false ;
248
267
TrimmedBlock prev = NativeContract . Ledger . GetTrimmedBlock ( snapshot , prevHash ) ;
249
268
if ( prev is null ) return false ;
250
269
if ( prev . Index + 1 != index ) return false ;
@@ -258,6 +277,8 @@ internal bool Verify(ProtocolSettings settings, DataCache snapshot, HeaderCache
258
277
{
259
278
Header prev = headerCache . Last ;
260
279
if ( prev is null ) return Verify ( settings , snapshot ) ;
280
+ if ( version != ( uint ) GetExpectedVersion ( settings ) )
281
+ return false ;
261
282
if ( primaryIndex >= settings . ValidatorsCount )
262
283
return false ;
263
284
if ( prev . Hash != prevHash ) return false ;
@@ -266,6 +287,11 @@ internal bool Verify(ProtocolSettings settings, DataCache snapshot, HeaderCache
266
287
return this . VerifyWitness ( settings , snapshot , prev . nextConsensus , Witness , 3_00000000L , out _ ) ;
267
288
}
268
289
290
+ private BlockVersion GetExpectedVersion ( ProtocolSettings settings )
291
+ {
292
+ return settings . IsHardforkEnabled ( Hardfork . HF_Faun , Index ) ? BlockVersion . V1 : BlockVersion . V0 ;
293
+ }
294
+
269
295
public Header Clone ( )
270
296
{
271
297
return new Header ( )
@@ -278,6 +304,7 @@ public Header Clone()
278
304
Index = index ,
279
305
PrimaryIndex = primaryIndex ,
280
306
NextConsensus = nextConsensus ,
307
+ PrevStateRoot = prevStateRoot ,
281
308
Witness = Witness ? . Clone ( ) ,
282
309
_hash = _hash
283
310
} ;
0 commit comments