@@ -16,12 +16,24 @@ type StateUpdate struct {
1616}
1717
1818type StateDiff struct {
19- StorageDiffs map [felt.Felt ]map [felt.Felt ]* felt.Felt // addr -> {key -> value, ...}
20- Nonces map [felt.Felt ]* felt.Felt // addr -> nonce
21- DeployedContracts map [felt.Felt ]* felt.Felt // addr -> class hash
22- DeclaredV0Classes []* felt.Felt // class hashes
23- DeclaredV1Classes map [felt.Felt ]* felt.Felt // class hash -> compiled class hash
24- ReplacedClasses map [felt.Felt ]* felt.Felt // addr -> class hash
19+ // todo(rdr): replace felt.Felt for the right types (felt.Address to felt.What? to felt.What?)
20+ // felt.What? means I'm not sure which type, but if it doesn't exist, create it.
21+ StorageDiffs map [felt.Felt ]map [felt.Felt ]* felt.Felt // addr -> {key -> value, ...}
22+ // todo(rdr): felt.Address to felt.Nonce (`Nonce` is a new type that should be created?)
23+ Nonces map [felt.Felt ]* felt.Felt
24+ // todo(rdr): felt.Addr to felt.ClassHash (do we know if it will be `SierraClassHash or
25+ // `CasmClassHash`)
26+ DeployedContracts map [felt.Felt ]* felt.Felt
27+ // todo(rdr): an array of felt.ClassHash, or perhaps, felt.DeprecatedCairoClassHash
28+ // Also, change the name from `DeclaredV0Classes` to `DeprecatedDeclaredClasses`
29+ DeclaredV0Classes []* felt.Felt
30+ // todo(rdr): felt.SierraClassHash to felt.CasmClassHash
31+ DeclaredV1Classes map [felt.Felt ]* felt.Felt // class hash -> compiled class hash
32+ // todo(rdr): felt.Address to (felt.SierraClassHash or felt.CasmClassHash, I'm unsure)
33+ ReplacedClasses map [felt.Felt ]* felt.Felt // addr -> class hash
34+ // Sierra Class definitions which had their compiled class hash definition (CASM)
35+ // migrated from poseidon hash to blake2s hash (Starknet 0.14.1)
36+ MigratedClasses map [felt.SierraClassHash ]felt.CasmClassHash
2537}
2638
2739func (d * StateDiff ) Length () uint64 {
@@ -35,50 +47,61 @@ func (d *StateDiff) Length() uint64 {
3547 length += len (d .DeclaredV0Classes )
3648 length += len (d .DeclaredV1Classes )
3749 length += len (d .ReplacedClasses )
50+ length += len (d .MigratedClasses )
3851
3952 return uint64 (length )
4053}
4154
4255func (d * StateDiff ) Merge (incoming * StateDiff ) {
43- mergeStorageDiffs := func (oldMap , newMap map [felt.Felt ]map [felt.Felt ]* felt.Felt ) {
44- for addr , newAddrStorage := range newMap {
45- if oldAddrStorage , exists := oldMap [addr ]; exists {
46- maps .Copy (oldAddrStorage , newAddrStorage )
47- } else {
48- oldMap [addr ] = maps .Clone (newAddrStorage )
49- }
56+ // Merge storage diffs
57+ for addr , newAddrStorage := range incoming .StorageDiffs {
58+ if oldAddrStorage , exists := d .StorageDiffs [addr ]; exists {
59+ maps .Copy (oldAddrStorage , newAddrStorage )
60+ } else {
61+ d .StorageDiffs [addr ] = maps .Clone (newAddrStorage )
5062 }
5163 }
64+
65+ // Merge everything else
5266 maps .Copy (d .Nonces , incoming .Nonces )
5367 maps .Copy (d .DeployedContracts , incoming .DeployedContracts )
5468 maps .Copy (d .DeclaredV1Classes , incoming .DeclaredV1Classes )
5569 maps .Copy (d .ReplacedClasses , incoming .ReplacedClasses )
56- mergeStorageDiffs (d .StorageDiffs , incoming .StorageDiffs )
70+ maps . Copy (d .MigratedClasses , incoming .MigratedClasses )
5771 d .DeclaredV0Classes = append (d .DeclaredV0Classes , incoming .DeclaredV0Classes ... )
5872}
5973
60- var starknetStateDiff0 = new (felt.Felt ).SetBytes ([]byte ("STARKNET_STATE_DIFF0" ))
74+ // todo(rdr): Is this global variable justified?
75+ var starknetStateDiff0 = felt.FromBytes [felt.Felt ]([]byte ("STARKNET_STATE_DIFF0" ))
6176
6277func (d * StateDiff ) Hash () * felt.Felt {
6378 digest := new (crypto.PoseidonDigest )
6479
65- digest .Update (starknetStateDiff0 )
80+ digest .Update (& starknetStateDiff0 )
6681
6782 // updated_contracts = deployedContracts + replacedClasses
6883 // Digest: [number_of_updated_contracts, address_0, class_hash_0, address_1, class_hash_1, ...].
6984 updatedContractsDigest (d .DeployedContracts , d .ReplacedClasses , digest )
7085
7186 // declared classes
72- // Digest: [number_of_declared_classes, class_hash_0, compiled_class_hash_0, class_hash_1, compiled_class_hash_1,
73- // ...].
74- declaredClassesDigest (d .DeclaredV1Classes , digest )
87+ // Digest: [
88+ // number_of_declared_classes,
89+ // class_hash_0, compiled_class_hash_0,
90+ // class_hash_1, compiled_class_hash_1,
91+ // ...
92+ // ] + [
93+ // migrated_class_hash_0, migrated_compiled_class_hash_0,
94+ // migrated_class_hash_1, migrated_compiled_class_hash_1,
95+ // ...
96+ // ]
97+ declaredClassesDigest (d .DeclaredV1Classes , d .MigratedClasses , digest )
7598
7699 // deprecated_declared_classes
77100 // Digest: [number_of_old_declared_classes, class_hash_0, class_hash_1, ...].
78101 deprecatedDeclaredClassesDigest (d .DeclaredV0Classes , digest )
79102
80103 // Placeholder values
81- digest .Update (new ( felt.Felt ). SetUint64 ( 1 ), new ( felt.Felt ). SetUint64 ( 0 ) )
104+ digest .Update (& felt .One , & felt .Zero )
82105
83106 // storage_diffs
84107 // Digest: [
@@ -89,12 +112,23 @@ func (d *StateDiff) Hash() *felt.Felt {
89112 storageDiffDigest (d .StorageDiffs , digest )
90113
91114 // nonces
92- // Digest: [number_of_updated_contracts nonces, contract_address_0, nonce_0, contract_address_1, nonce_1, ...]
115+ // Digest: [
116+ // number_of_updated_contracts nonces,
117+ // contract_address_0, nonce_0,
118+ // contract_address_1, nonce_1,
119+ // ...,
120+ // ]
93121 noncesDigest (d .Nonces , digest )
94122
95123 /*Poseidon(
96- "STARKNET_STATE_DIFF0", deployed_contracts_and_replaced_classes, declared_classes, deprecated_declared_classes,
97- 1, 0, storage_diffs, nonces
124+ "STARKNET_STATE_DIFF0",
125+ deployed_contracts_and_replaced_classes,
126+ declared_classes,
127+ deprecated_declared_classes,
128+ 1,
129+ 0,
130+ storage_diffs,
131+ nonces
98132 )*/
99133 return digest .Finish ()
100134}
@@ -114,8 +148,9 @@ func (d *StateDiff) Commitment() *felt.Felt {
114148 hash_of_declared_classes = hash([number_of_declared_classes, class_hash_1, compiled_class_hash_1,
115149 class_hash_2, compiled_class_hash_2, ...])
116150 */
151+ // todo(rdr): check if commitment is like this too
117152 hashOfDeclaredClasses := new (crypto.PoseidonDigest )
118- declaredClassesDigest (d .DeclaredV1Classes , hashOfDeclaredClasses )
153+ declaredClassesDigest (d .DeclaredV1Classes , d . MigratedClasses , hashOfDeclaredClasses )
119154
120155 /*
121156 hash_of_old_declared_classes = hash([number_of_old_declared_classes, class_hash_1, class_hash_2, ...])
@@ -173,13 +208,36 @@ func updatedContractsDigest(deployedContracts, replacedClasses map[felt.Felt]*fe
173208 }
174209}
175210
176- func declaredClassesDigest (declaredV1Classes map [felt.Felt ]* felt.Felt , digest * crypto.PoseidonDigest ) {
177- numOfDeclaredClasses := uint64 (len (declaredV1Classes ))
178- digest .Update (new (felt.Felt ).SetUint64 (numOfDeclaredClasses ))
211+ func declaredClassesDigest (
212+ declaredClasses map [felt.Felt ]* felt.Felt ,
213+ migratedClasses map [felt.SierraClassHash ]felt.CasmClassHash ,
214+ digest * crypto.PoseidonDigest ,
215+ ) {
216+ mapsLen := len (declaredClasses ) + len (migratedClasses )
217+ numOfDeclaredClasses := felt.FromUint64 [felt.Felt ](uint64 (mapsLen ))
218+ digest .Update (& numOfDeclaredClasses )
219+
220+ // Sorting the two keys without actually modifying `declaredClasses` or `migratedClasses`
221+ // to avoid the memory overhead of creating a new map since we **mustn't** mutate them
222+ keys := make ([]felt.Felt , mapsLen )
223+ index := 0
224+ for key := range declaredClasses {
225+ keys [index ] = key
226+ index += 1
227+ }
228+ for key := range migratedClasses {
229+ // todo(rdr): we shouldn't need to convert the key to a felt here but the right fix
230+ // includes a bigger refactor
231+ keys [index ] = felt .Felt (key )
232+ index += 1
233+ }
234+ slices .SortFunc (keys , func (a felt.Felt , b felt.Felt ) int { return a .Cmp (& b ) })
179235
180- sortedDeclaredV1ClassHashes := sortedFeltKeys (declaredV1Classes )
236+ // todo(rdr): Is it more performant to do multiple calls to `diget.Update`, or
237+ // pre-store all the values and make a single call to `digest.Update`?
238+ sortedDeclaredV1ClassHashes := sortedFeltKeys (declaredClasses )
181239 for _ , classHash := range sortedDeclaredV1ClassHashes {
182- digest .Update (& classHash , declaredV1Classes [classHash ])
240+ digest .Update (& classHash , declaredClasses [classHash ])
183241 }
184242}
185243
@@ -191,7 +249,10 @@ func deprecatedDeclaredClassesDigest(declaredV0Classes []*felt.Felt, digest *cry
191249 digest .Update (declaredV0Classes ... )
192250}
193251
194- func storageDiffDigest (storageDiffs map [felt.Felt ]map [felt.Felt ]* felt.Felt , digest * crypto.PoseidonDigest ) {
252+ func storageDiffDigest (
253+ storageDiffs map [felt.Felt ]map [felt.Felt ]* felt.Felt ,
254+ digest * crypto.PoseidonDigest ,
255+ ) {
195256 numOfStorageDiffs := uint64 (len (storageDiffs ))
196257 digest .Update (new (felt.Felt ).SetUint64 (numOfStorageDiffs ))
197258
@@ -226,5 +287,6 @@ func EmptyStateDiff() StateDiff {
226287 DeclaredV0Classes : []* felt.Felt {},
227288 DeclaredV1Classes : make (map [felt.Felt ]* felt.Felt ),
228289 ReplacedClasses : make (map [felt.Felt ]* felt.Felt ),
290+ MigratedClasses : make (map [felt.SierraClassHash ]felt.CasmClassHash ),
229291 }
230292}
0 commit comments