diff --git a/.gitignore b/.gitignore index 3e25dca32..abb8b256d 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ lcov.info .rusty-hook.toml !/starknet_programs/raw_contract_classes/*.json cairo-*.tar +starknet-pypy-env/ \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 1d0107832..184e4c5c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -663,6 +663,40 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blockifier" +version = "0.2.0-rc0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb4d375ae4ea55963350f296c9c22f245ceff91e7c9edcd61320792901b783f" +dependencies = [ + "ark-ff", + "ark-secp256k1", + "cached", + "cairo-felt", + "cairo-lang-casm", + "cairo-lang-runner", + "cairo-lang-starknet", + "cairo-vm", + "ctor", + "derive_more", + "indexmap 1.9.3", + "itertools 0.10.5", + "keccak", + "log", + "num-bigint", + "num-integer", + "num-traits 0.2.16", + "phf", + "serde", + "serde_json", + "sha3", + "starknet-crypto 0.5.1", + "starknet_api", + "strum", + "strum_macros", + "thiserror", +] + [[package]] name = "brotli" version = "3.3.4" @@ -717,6 +751,42 @@ dependencies = [ "bytes", ] +[[package]] +name = "cached" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b195e4fbc4b6862bbd065b991a34750399c119797efff72492f28a5864de8700" +dependencies = [ + "async-trait", + "cached_proc_macro", + "cached_proc_macro_types", + "futures", + "hashbrown 0.13.2", + "instant", + "once_cell", + "thiserror", + "tokio", +] + +[[package]] +name = "cached_proc_macro" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b48814962d2fd604c50d2b9433c2a41a0ab567779ee2c02f7fba6eca1221f082" +dependencies = [ + "cached_proc_macro_types", + "darling 0.14.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cached_proc_macro_types" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" + [[package]] name = "cairo-felt" version = "0.8.5" @@ -732,9 +802,9 @@ dependencies = [ [[package]] name = "cairo-lang-casm" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb23212923a656f06d49ff2a953d83a40c916dc01802bf43a6a8b230cc1ae5" +checksum = "afc7f7cb89bc3f52c2c738f3e87c8f8773bd3456cae1d322d100d4b0da584f3c" dependencies = [ "cairo-lang-utils", "indoc", @@ -749,9 +819,9 @@ dependencies = [ [[package]] name = "cairo-lang-compiler" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb8e62e8ea8ec8953900c591e8ec8afadeacb5414c66c391e2374cd33e75265" +checksum = "d4f2c54b065f7fd97bf8d5df76cbcbbd01d8a8c319d281796ee20ecc48e16ca8" dependencies = [ "anyhow", "cairo-lang-defs", @@ -766,6 +836,7 @@ dependencies = [ "cairo-lang-sierra-generator", "cairo-lang-syntax", "cairo-lang-utils", + "itertools 0.11.0", "log", "salsa", "smol_str", @@ -774,18 +845,18 @@ dependencies = [ [[package]] name = "cairo-lang-debug" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688919661be70385834619abb6e91b822c2e36ee0d5490efa6a3c708741cb1a9" +checksum = "873ba77d4c3f780c727c7d6c738cded22b3f6d4023e30546dfe14f97a087887e" dependencies = [ "cairo-lang-utils", ] [[package]] name = "cairo-lang-defs" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae52e506409795292e5fa5a06cda8cc705a1b714d31071841827b74453dad3" +checksum = "f5031fff038c27ed43769b73a6f5d41aeaea34df9af862e024c23fbb4f076249" dependencies = [ "cairo-lang-debug", "cairo-lang-diagnostics", @@ -801,9 +872,9 @@ dependencies = [ [[package]] name = "cairo-lang-diagnostics" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f53df12acc714e2fc505fba706c754c0d19d092710b4527dbec489b59589b1" +checksum = "7b6cb1492e5784e1076320a5018ce7584f391b2f3b414bc0a8ab7c289fa118ce" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -814,9 +885,9 @@ dependencies = [ [[package]] name = "cairo-lang-eq-solver" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be26fab051abb2ff8e53cd3bd728db6e85d5b044c6779c0ac202c68613844bbb" +checksum = "c35dddbc63b2a4870891cc74498726aa32bfaa518596352f9bb101411cc4c584" dependencies = [ "cairo-lang-utils", "good_lp", @@ -826,9 +897,9 @@ dependencies = [ [[package]] name = "cairo-lang-filesystem" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22faaa72b212e6dd21a9d1547e86cea65a3cb7c7f4d43be1f7b051e4a1613a46" +checksum = "32ce0b8e66a6085ae157d43b5c162d60166f0027d6f125c50ee74e4dc7916ff6" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", @@ -840,9 +911,9 @@ dependencies = [ [[package]] name = "cairo-lang-lowering" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2160203c5556d680f155e1a24432c77ada4bf04c1701e08cfb8e35d33a717b6" +checksum = "29cc679f501725e03ee703559ed27d084c6f4031bd51ff86378cf845a85ee207" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -859,15 +930,16 @@ dependencies = [ "log", "num-bigint", "num-traits 0.2.16", + "once_cell", "salsa", "smol_str", ] [[package]] name = "cairo-lang-parser" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b25cb9b8be9bf706739030a282d088cb0a2de42e2ec0a21e720ec5bb34a41218" +checksum = "cdcadb046659134466bc7e11961ea8a56969dae8a54d8f985955ce0b95185c7f" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -886,17 +958,17 @@ dependencies = [ [[package]] name = "cairo-lang-plugins" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b685065afc3305b780e9713132a4a747de5f0d71bcf101201474ad0ebfe3f06e" +checksum = "4632790cd4ea11d4849934456a400eae7ed419f6d721f24a6b637df67b7e902f" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", "cairo-lang-filesystem", "cairo-lang-parser", - "cairo-lang-semantic", "cairo-lang-syntax", "cairo-lang-utils", + "indent", "indoc", "itertools 0.11.0", "num-bigint", @@ -906,9 +978,9 @@ dependencies = [ [[package]] name = "cairo-lang-proc-macros" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1a49e58ad1eeefe0b1efc667a6ee544b5f906c6123d6d1e77e0321b4d1db92" +checksum = "170838817fc33ddb65e0a9480526df0b226b148a0fca0a5cd7071be4c6683157" dependencies = [ "cairo-lang-debug", "quote", @@ -917,9 +989,9 @@ dependencies = [ [[package]] name = "cairo-lang-project" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29d3e28ff80fb8fd94f4e6db12c42bacbe6e3ab7a991aa997861b99d0cb2fa2" +checksum = "4162ee976c61fdeb3b621f4a76fd256e46a5c0890f750a3a9d2c9560a3bc1daf" dependencies = [ "cairo-lang-filesystem", "cairo-lang-utils", @@ -931,9 +1003,9 @@ dependencies = [ [[package]] name = "cairo-lang-runner" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abcc2ff6ebb5fbdd9578f3506a6ffab3944da5383e38546ed30eebaa992df01b" +checksum = "11d66ef01350e2e7f7e6b2b43b865da2513a42600082ee1a2975d3af3da7f0ca" dependencies = [ "anyhow", "ark-ff", @@ -968,15 +1040,16 @@ dependencies = [ [[package]] name = "cairo-lang-semantic" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc0538b422abaff683425ceb945d29d956172e2748f28924904226303d07486" +checksum = "13e544fa9a222bf2d007df2b5fc9b21c2a20ab7e17d6fefbcbc193de209451cd" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", "cairo-lang-diagnostics", "cairo-lang-filesystem", "cairo-lang-parser", + "cairo-lang-plugins", "cairo-lang-proc-macros", "cairo-lang-syntax", "cairo-lang-utils", @@ -985,15 +1058,16 @@ dependencies = [ "log", "num-bigint", "num-traits 0.2.16", + "once_cell", "salsa", "smol_str", ] [[package]] name = "cairo-lang-sierra" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b84a986fa30c459447cbe7175243d50ba55e5659d8efc3a867b051ca7a629b0" +checksum = "d5e136b79e95a14ef38a2be91a67ceb85317407d336a5b0d418c33b23c78596a" dependencies = [ "cairo-lang-utils", "const-fnv1a-hash", @@ -1014,9 +1088,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224dad404d483b4c3ea9cb08d94285c2b4755539eaf78dcd5e280bf1a2ca96cb" +checksum = "511ca7708faa7ba8d14ae26e1d60ead2d02028c8f664baf5ecb0fd6a0d1e20f6" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -1028,9 +1102,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1246a3fc5249d5fc7e7d1b0611dd41e6b13e88c4fd4ce5d77708581975baa6a" +checksum = "351a25bc010b910919c01d5c57e937b0c3d330fc30d92702c0cb4061819df8df" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -1042,9 +1116,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-generator" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b4e0a3a883348e262ca84ca085ff402b52dc206278352c0d74db476d76e960" +checksum = "114091bb971c06fd072aca816af1c3f62566cd8a4b1453c786155161a36c7bce" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -1062,15 +1136,16 @@ dependencies = [ "indexmap 2.0.0", "itertools 0.11.0", "num-bigint", + "once_cell", "salsa", "smol_str", ] [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ba03115b3cf4d3fe691f5574ff1a95565f1abc430fba717d6605db11d7e2cd4" +checksum = "fa1c799de62972dfd7112d563000695be94305b6f7d9bedd29f347799bf03e1c" dependencies = [ "assert_matches", "cairo-felt", @@ -1090,9 +1165,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-type-size" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff65da8fd75ab9020159b072817c8a516d859b0b0bc60ab3693681b635339729" +checksum = "d2fe73d9d58aaf9088f6ba802bcf43ce9ca4bd198190cf5bf91caa7d408dd11a" dependencies = [ "cairo-lang-sierra", "cairo-lang-utils", @@ -1100,9 +1175,9 @@ dependencies = [ [[package]] name = "cairo-lang-starknet" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "326f47941e94a8cdbb420a041411df44a4328a5b8190bb5647092499ed4d3fa9" +checksum = "75df624e71e33a31a924e799dd2a9a8284204b41d8db9c51803317bd9edff81f" dependencies = [ "anyhow", "cairo-felt", @@ -1141,9 +1216,9 @@ dependencies = [ [[package]] name = "cairo-lang-syntax" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84885246b2b8626034fe8fe2fc7360f8618b695769413bd8f8b31063c8964d8d" +checksum = "0b1af0ae21f9e539f97cfdf56f5ce0934dae5d87f568fd778c3d624a102f8dbb" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -1158,9 +1233,9 @@ dependencies = [ [[package]] name = "cairo-lang-syntax-codegen" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a87271440bc2624da4b5411db90403302224c39f2cdac4293f52967439238e6c" +checksum = "822ffabf24f6a5506262edcece315260a82d9dfba3abe6548791a6d654563ad0" dependencies = [ "genco", "xshell", @@ -1168,9 +1243,9 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.1.0-rc4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22628c2fcd2d249ed6655a0fb7ba29a668a6b65741016b8ed562bd5ef906778a" +checksum = "f974b6e859f0b09c0f13ec8188c96e9e8bbb5da04214f911dbb5bcda67cb812b" dependencies = [ "indexmap 2.0.0", "itertools 0.11.0", @@ -1410,6 +1485,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctor" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f34ba9a9bcb8645379e9de8cb3ecfcf4d1c85ba66d90deb3259206fa5aa193b" +dependencies = [ + "quote", + "syn 2.0.28", +] + [[package]] name = "ctr" version = "0.9.2" @@ -1419,14 +1504,38 @@ dependencies = [ "cipher", ] +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + [[package]] name = "darling" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.3", + "darling_macro 0.20.3", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", ] [[package]] @@ -1443,13 +1552,24 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote", + "syn 1.0.109", +] + [[package]] name = "darling_macro" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ - "darling_core", + "darling_core 0.20.3", "quote", "syn 2.0.28", ] @@ -1692,6 +1812,20 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.28" @@ -1699,6 +1833,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -1707,6 +1842,12 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + [[package]] name = "futures-macro" version = "0.3.28" @@ -2645,6 +2786,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ + "phf_macros", "phf_shared 0.11.2", ] @@ -2997,6 +3139,25 @@ dependencies = [ "ureq", ] +[[package]] +name = "rpc_state_reader_sn_api" +version = "0.3.1" +dependencies = [ + "blockifier", + "cairo-lang-starknet", + "cairo-lang-utils", + "cairo-vm", + "dotenv", + "flate2", + "serde", + "serde_json", + "serde_with 3.1.0", + "starknet", + "starknet_api", + "thiserror", + "ureq", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -3189,18 +3350,18 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.180" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.180" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e744d7782b686ab3b73267ef05697159cc0e5abbed3f47f9933165e5219036" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", @@ -3309,7 +3470,7 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling", + "darling 0.20.3", "proc-macro2", "quote", "syn 2.0.28", @@ -3321,7 +3482,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65" dependencies = [ - "darling", + "darling 0.20.3", "proc-macro2", "quote", "syn 2.0.28", @@ -3635,9 +3796,9 @@ dependencies = [ [[package]] name = "starknet_api" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfe4732113f66de3d6e9fc77f713b934cfd4b24d43887ca8cbfbe9462ed9119" +checksum = "3f6e445fbd6bf3826dda26fd64aa5311353b4799c9bd1119d6ec1906be4c73bf" dependencies = [ "cairo-lang-starknet", "derive_more", @@ -3713,6 +3874,25 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + [[package]] name = "subtle" version = "2.5.0" @@ -3878,9 +4058,21 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "socket2", + "tokio-macros", "windows-sys", ] +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + [[package]] name = "tokio-rustls" version = "0.24.1" diff --git a/Cargo.toml b/Cargo.toml index ffde854ac..ed427e441 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,11 +11,11 @@ with_mimalloc = ["dep:mimalloc"] cairo_1_tests = [] [workspace] -members = ["cli", "fuzzer", "rpc_state_reader"] +members = ["cli", "fuzzer", "rpc_state_reader", "rpc_state_reader_sn_api"] [workspace.dependencies] cairo-vm = { version = "0.8.5", features = ["cairo-1-hints"] } -starknet_api = "0.3.0" +starknet_api = "0.4.1" num-traits = "0.2.15" starknet = "0.5.0" thiserror = "1.0.32" @@ -44,7 +44,7 @@ serde_json = { version = "1.0", features = [ ] } sha3 = "0.10.1" # TODO: Replace with sha3. We should look how to integrate it correctly to calculate sn_keccak -keccak = "0.1.3" +keccak = "0.1.3" starknet_api = { workspace = true } starknet-crypto = "0.5.1" thiserror = { workspace = true } diff --git a/README.md b/README.md index 1dd623fad..1b754db81 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ### 🦀 Starknet in Rust 🦀 -Starknet library in Rust, featuring [âš¡cairo-vmâš¡](https://github.com/lambdaclass/cairo-vm) +Starknet transaction execution library in Rust, featuring [âš¡cairo-vmâš¡](https://github.com/lambdaclass/cairo-vm) [Report Bug](https://github.com/lambdaclass/starknet_in_rust/issues/new?labels=bug&title=bug%3A+) · [Request Feature](https://github.com/lambdaclass/starknet_in_rust/issues/new?labels=enhancement&title=feat%3A+) @@ -13,8 +13,8 @@ Starknet library in Rust, featuring [âš¡cairo-vmâš¡](https://github.com/lambdacl [![Telegram Chat][tg-badge]][tg-url] [pr-welcome]: https://img.shields.io/static/v1?color=orange&label=PRs&style=flat&message=welcome -[tg-badge]: https://img.shields.io/static/v1?color=green&logo=telegram&label=chat&style=flat&message=join -[tg-url]: https://t.me/starknet_rs +[tg-badge]: https://img.shields.io/endpoint?url=https%3A%2F%2Ftg.sumanjay.workers.dev%2FLambdaStarkNet%2F&logo=telegram&label=chat&color=neon +[tg-url]: https://t.me/LambdaStarkNet diff --git a/bench/internals.rs b/bench/internals.rs index 075f216a2..430dc5446 100644 --- a/bench/internals.rs +++ b/bench/internals.rs @@ -11,13 +11,15 @@ use starknet_in_rust::{ constants::{TRANSACTION_VERSION, VALIDATE_ENTRY_POINT_SELECTOR}, }, hash_utils::calculate_contract_address, - services::api::contract_classes::deprecated_contract_class::ContractClass, + services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::ContractClass, + }, state::in_memory_state_reader::InMemoryStateReader, state::{cached_state::CachedState, state_api::State}, transaction::{declare::Declare, Deploy, DeployAccount, InvokeFunction}, utils::Address, }; -use std::{hint::black_box, sync::Arc}; +use std::{collections::HashMap, hint::black_box, sync::Arc}; lazy_static! { // include_str! doesn't seem to work in CI @@ -61,10 +63,13 @@ fn deploy_account() { const RUNS: usize = 500; let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(Default::default()), None); + let mut state = CachedState::new(state_reader, HashMap::new()); state - .set_contract_class(&CLASS_HASH_BYTES, &CONTRACT_CLASS) + .set_contract_class( + &CLASS_HASH_BYTES, + &CompiledClass::Deprecated(Arc::new(CONTRACT_CLASS.clone())), + ) .unwrap(); let block_context = &Default::default(); @@ -97,7 +102,7 @@ fn declare() { const RUNS: usize = 5; let state_reader = Arc::new(InMemoryStateReader::default()); - let state = CachedState::new(state_reader, Some(Default::default()), None); + let state = CachedState::new(state_reader, HashMap::new()); let block_context = &Default::default(); @@ -129,10 +134,13 @@ fn deploy() { const RUNS: usize = 8; let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(Default::default()), None); + let mut state = CachedState::new(state_reader, HashMap::new()); state - .set_contract_class(&CLASS_HASH_BYTES, &CONTRACT_CLASS) + .set_contract_class( + &CLASS_HASH_BYTES, + &CompiledClass::Deprecated(Arc::new(CONTRACT_CLASS.clone())), + ) .unwrap(); let block_context = &Default::default(); @@ -164,10 +172,13 @@ fn invoke() { const RUNS: usize = 100; let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(Default::default()), None); + let mut state = CachedState::new(state_reader, HashMap::new()); state - .set_contract_class(&CLASS_HASH_BYTES, &CONTRACT_CLASS) + .set_contract_class( + &CLASS_HASH_BYTES, + &CompiledClass::Deprecated(Arc::new(CONTRACT_CLASS.clone())), + ) .unwrap(); let block_context = &Default::default(); diff --git a/cli/src/main.rs b/cli/src/main.rs index f37bdf544..1248123dd 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -23,7 +23,9 @@ use starknet_in_rust::{ hash_utils::calculate_contract_address, parser_errors::ParserError, serde_structs::read_abi, - services::api::contract_classes::deprecated_contract_class::ContractClass, + services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::ContractClass, + }, state::{cached_state::CachedState, state_api::State}, state::{in_memory_state_reader::InMemoryStateReader, ExecutionResourcesManager}, transaction::{error::TransactionError, InvokeFunction}, @@ -110,7 +112,10 @@ fn declare_parser( let contract_class = ContractClass::from_path(&args.contract).map_err(ContractAddressError::Program)?; let class_hash = compute_deprecated_class_hash(&contract_class)?; - cached_state.set_contract_class(&felt_to_hash(&class_hash), &contract_class)?; + cached_state.set_contract_class( + &felt_to_hash(&class_hash), + &CompiledClass::Deprecated(Arc::new(contract_class.clone())), + )?; let tx_hash = calculate_declare_transaction_hash( &contract_class, @@ -313,8 +318,7 @@ pub async fn start_devnet(port: u16) -> Result<(), std::io::Error> { let cached_state = web::Data::new(AppState { cached_state: Mutex::new(CachedState::::new( Arc::new(InMemoryStateReader::default()), - Some(HashMap::new()), - None, + HashMap::new(), )), }); diff --git a/fuzzer/src/main.rs b/fuzzer/src/main.rs index edbfb1cf5..2b14e11b4 100644 --- a/fuzzer/src/main.rs +++ b/fuzzer/src/main.rs @@ -25,6 +25,7 @@ use std::{ path::PathBuf, }; +use starknet_in_rust::services::api::contract_classes::compiled_class::CompiledClass; use std::fs; use std::process::Command; use std::thread; @@ -44,11 +45,11 @@ fn main() { let file_content1 = " %lang starknet from starkware.cairo.common.cairo_builtins import HashBuiltin - + @storage_var func _counter() -> (res: felt) { } - + @external func write_and_read{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res:felt) { _counter.write('"; @@ -116,7 +117,10 @@ fn main() { let address = Address(1111.into()); let class_hash = [1; 32]; - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -126,8 +130,7 @@ fn main() { //* Create state with previous data //* --------------------------------------- - let mut state = - CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* ------------------------------------ //* Create execution entry point diff --git a/rpc_state_reader/src/lib.rs b/rpc_state_reader/src/lib.rs index 280f14aa0..254b26b00 100644 --- a/rpc_state_reader/src/lib.rs +++ b/rpc_state_reader/src/lib.rs @@ -741,7 +741,7 @@ mod transaction_tests { felt::felt_str, state::cached_state::CachedState, }; - use std::sync::Arc; + use std::{collections::HashMap, sync::Arc}; fn test_tx( tx_hash: &str, @@ -754,7 +754,7 @@ mod transaction_tests { // Instantiate the RPC StateReader and the CachedState let block = BlockValue::Number(serde_json::to_value(block_number).unwrap()); let rpc_state = Arc::new(RpcState::new(network, block)); - let mut state = CachedState::new(rpc_state.clone(), None, None); + let mut state = CachedState::new(rpc_state.clone(), HashMap::new()); let fee_token_address = Address(felt_str!( "049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", diff --git a/rpc_state_reader_sn_api/Cargo.toml b/rpc_state_reader_sn_api/Cargo.toml new file mode 100644 index 000000000..ba20520ba --- /dev/null +++ b/rpc_state_reader_sn_api/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "rpc_state_reader_sn_api" +version = "0.3.1" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ureq = { version = "2.7.1", features = ["json"] } +serde = { version = "=1.0.171", features = ["derive"] } +serde_json = { version = "1.0", features = [ + "arbitrary_precision", + "raw_value", +] } +starknet_api = "0.4.1" +cairo-lang-starknet = { workspace = true } +cairo-lang-utils = { workspace = true } +starknet = { workspace = true } +thiserror = { workspace = true } +flate2 = "1.0.25" +serde_with = "3.0.0" +dotenv = "0.15.0" +cairo-vm = "0.8.5" +blockifier = "0.2.0-rc0" diff --git a/rpc_state_reader_sn_api/src/lib.rs b/rpc_state_reader_sn_api/src/lib.rs new file mode 100644 index 000000000..ef1c81d4a --- /dev/null +++ b/rpc_state_reader_sn_api/src/lib.rs @@ -0,0 +1,1032 @@ +use blockifier::execution::contract_class::{ + ContractClass as BlockifierContractClass, ContractClassV0, ContractClassV0Inner, +}; +use cairo_lang_starknet::casm_contract_class::CasmContractClass; +use cairo_lang_starknet::contract_class::{ + ContractClass as SierraContractClass, ContractEntryPoints, +}; +use cairo_vm::types::program::Program; +use cairo_vm::vm::runners::cairo_runner::ExecutionResources as VmExecutionResources; +use core::fmt; +use dotenv::dotenv; +use serde::{Deserialize, Deserializer}; +use serde_json::json; +use starknet::core::types::ContractClass as SNContractClass; +use starknet_api::block::{BlockNumber, BlockTimestamp}; +use starknet_api::core::{ChainId, ClassHash, EntryPointSelector}; +use starknet_api::deprecated_contract_class::EntryPointOffset; +use starknet_api::hash::StarkFelt; +use starknet_api::transaction::{InvokeTransaction, Transaction, TransactionHash}; +use starknet_api::{core::ContractAddress, hash::StarkHash, state::StorageKey}; +use std::collections::HashMap; +use std::env; +use std::fmt::Display; +use std::sync::Arc; +use thiserror::Error; + +/// Starknet chains supported in Infura. +#[derive(Debug, Clone, Copy)] +pub enum RpcChain { + MainNet, + TestNet, + TestNet2, +} + +impl fmt::Display for RpcChain { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + RpcChain::MainNet => write!(f, "starknet-mainnet"), + RpcChain::TestNet => write!(f, "starknet-goerli"), + RpcChain::TestNet2 => write!(f, "starknet-goerli2"), + } + } +} + +/// A [StateReader] that holds all the data in memory. +/// +/// This implementation is uses HTTP requests to call the RPC endpoint, +/// using Infura. +/// In order to use it an Infura API key is necessary. +pub struct RpcState { + /// Enum with one of the supported Infura chains/ + chain: RpcChain, + /// Infura API key. + api_key: String, + /// Struct that holds information on the block where we are going to use to read the state. + block: BlockValue, +} + +#[derive(Debug, Error)] +enum RpcError { + #[error("RPC call failed with error: {0}")] + RpcCall(String), + #[error("Request failed with error: {0}")] + Request(String), +} + +/// Represents the tag of a block value. +#[derive(Copy, Clone)] +pub enum BlockTag { + Latest, + Pending, +} + +impl Display for BlockTag { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let string = match self { + BlockTag::Latest => "latest", + BlockTag::Pending => "pending", + }; + write!(f, "{}", string) + } +} + +/// [`BlockValue`] is an Enum that represent which block we are going to use to retrieve information. +#[allow(dead_code)] +#[derive(Copy, Clone)] +pub enum BlockValue { + /// String one of: ["latest", "pending"] + Tag(BlockTag), + /// Integer + Number(BlockNumber), + /// String with format: 0x{felt252} + Hash(StarkHash), +} + +impl From for BlockValue { + fn from(value: BlockTag) -> Self { + BlockValue::Tag(value) + } +} + +impl From for BlockValue { + fn from(value: BlockNumber) -> Self { + BlockValue::Number(value) + } +} + +impl From for BlockValue { + fn from(value: StarkHash) -> Self { + BlockValue::Hash(value) + } +} + +impl BlockValue { + fn to_value(self) -> Result { + serde_json::to_value(match self { + BlockValue::Tag(block_tag) => block_tag.to_string().into(), + BlockValue::Number(block_number) => json!({ "block_number": block_number }), + BlockValue::Hash(block_hash) => json!({ "block_hash": block_hash }), + }) + } +} + +pub struct RpcBlockInfo { + /// The sequence number of the last block created. + pub block_number: BlockNumber, + /// Timestamp of the beginning of the last block creation attempt. + pub block_timestamp: BlockTimestamp, + /// The sequencer address of this block. + pub sequencer_address: ContractAddress, + /// The transactions of this block. + pub transactions: Vec, +} + +#[derive(Deserialize)] +pub struct RpcResponse { + result: T, +} + +impl RpcState { + pub fn new(chain: RpcChain, block: BlockValue) -> Self { + if env::var("INFURA_API_KEY").is_err() { + dotenv().expect("Missing .env file"); + } + Self { + chain, + api_key: env::var("INFURA_API_KEY") + .expect("Missing API Key in environment: INFURA_API_KEY"), + block, + } + } + + fn rpc_call_result Deserialize<'a>>( + &self, + params: &serde_json::Value, + ) -> Result { + Ok(self.rpc_call::>(params)?.result) + } + + fn rpc_call Deserialize<'a>>( + &self, + params: &serde_json::Value, + ) -> Result { + Self::deserialize_call(self.rpc_call_no_deserialize(params)?.into_json().unwrap()) + } + + fn rpc_call_no_deserialize( + &self, + params: &serde_json::Value, + ) -> Result { + ureq::post(&format!( + "https://{}.infura.io/v3/{}", + self.chain, self.api_key + )) + .set("Content-Type", "application/json") + .set("accept", "application/json") + .send_json(params) + .map_err(|err| RpcError::Request(err.to_string())) + } + + fn deserialize_call Deserialize<'a>>( + response: serde_json::Value, + ) -> Result { + serde_json::from_value(response).map_err(|err| RpcError::RpcCall(err.to_string())) + } +} + +#[derive(Debug)] +pub struct TransactionTrace { + pub validate_invocation: RpcCallInfo, + pub function_invocation: RpcCallInfo, + pub fee_transfer_invocation: RpcCallInfo, + pub signature: Vec, +} + +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] +pub struct RpcExecutionResources { + pub n_steps: usize, + pub n_memory_holes: usize, + pub builtin_instance_counter: HashMap, +} + +#[derive(Debug)] +pub struct RpcCallInfo { + pub execution_resources: VmExecutionResources, + pub retdata: Option>, + pub calldata: Option>, + pub internal_calls: Vec, +} + +#[allow(unused)] +#[derive(Debug, Deserialize)] +pub struct RpcTransactionReceipt { + #[serde(deserialize_with = "actual_fee_deser")] + actual_fee: u128, + block_hash: StarkHash, + block_number: u64, + execution_status: String, + #[serde(rename = "type")] + tx_type: String, +} + +fn actual_fee_deser<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let hex: String = Deserialize::deserialize(deserializer)?; + Ok(u128::from_str_radix(&hex[2..], 16).unwrap()) +} + +impl<'de> Deserialize<'de> for RpcCallInfo { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let value: serde_json::Value = Deserialize::deserialize(deserializer)?; + + // Parse execution_resources + let execution_resources_value = value["execution_resources"].clone(); + + let execution_resources = VmExecutionResources { + n_steps: serde_json::from_value(execution_resources_value["n_steps"].clone()) + .map_err(serde::de::Error::custom)?, + n_memory_holes: serde_json::from_value( + execution_resources_value["n_memory_holes"].clone(), + ) + .map_err(serde::de::Error::custom)?, + builtin_instance_counter: serde_json::from_value( + execution_resources_value["builtin_instance_counter"].clone(), + ) + .map_err(serde::de::Error::custom)?, + }; + + // Parse retdata + let retdata_value = value["result"].clone(); + let retdata = serde_json::from_value(retdata_value).unwrap(); + + // Parse calldata + let calldata_value = value["calldata"].clone(); + let calldata = serde_json::from_value(calldata_value).unwrap(); + + // Parse internal calls + let internal_calls_value = value["internal_calls"].clone(); + let mut internal_calls = vec![]; + + for call in internal_calls_value.as_array().unwrap() { + internal_calls + .push(serde_json::from_value(call.clone()).map_err(serde::de::Error::custom)?); + } + + Ok(RpcCallInfo { + execution_resources, + retdata, + calldata, + internal_calls, + }) + } +} + +impl<'de> Deserialize<'de> for TransactionTrace { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let value: serde_json::Value = Deserialize::deserialize(deserializer)?; + + let validate_invocation = value["validate_invocation"].clone(); + let function_invocation = value["function_invocation"].clone(); + let fee_transfer_invocation = value["fee_transfer_invocation"].clone(); + let signature_value = value["signature"].clone(); + + Ok(TransactionTrace { + validate_invocation: serde_json::from_value(validate_invocation) + .map_err(serde::de::Error::custom)?, + function_invocation: serde_json::from_value(function_invocation) + .map_err(serde::de::Error::custom)?, + fee_transfer_invocation: serde_json::from_value(fee_transfer_invocation) + .map_err(serde::de::Error::custom)?, + signature: serde_json::from_value(signature_value).map_err(serde::de::Error::custom)?, + }) + } +} + +/// Freestanding deserialize method to avoid a new type. +fn deserialize_transaction_json(transaction: serde_json::Value) -> serde_json::Result { + let tx_type: String = serde_json::from_value(transaction["type"].clone())?; + let tx_version: String = serde_json::from_value(transaction["version"].clone())?; + + match tx_type.as_str() { + "INVOKE" => match tx_version.as_str() { + "0x0" => Ok(Transaction::Invoke(InvokeTransaction::V0( + serde_json::from_value(transaction)?, + ))), + "0x1" => Ok(Transaction::Invoke(InvokeTransaction::V1( + serde_json::from_value(transaction)?, + ))), + x => Err(serde::de::Error::custom(format!( + "unimplemented invoke version: {x}" + ))), + }, + x => Err(serde::de::Error::custom(format!( + "unimplemented transaction type deserialization: {x}" + ))), + } +} + +impl RpcState { + /// Requests the transaction trace to the Feeder Gateway API. + /// It's useful for testing the transaction outputs like: + /// - execution resources + /// - actual fee + /// - events + /// - return data + pub fn get_transaction_trace(&self, hash: &TransactionHash) -> TransactionTrace { + let chain_name = self.get_chain_name(); + let response = ureq::get(&format!( + "https://{}.starknet.io/feeder_gateway/get_transaction_trace", + chain_name + )) + .query("transactionHash", &hash.0.to_string()) + .call() + .unwrap(); + + serde_json::from_str(&response.into_string().unwrap()).unwrap() + } + + /// Requests the given transaction to the Feeder Gateway API. + pub fn get_transaction(&self, hash: &TransactionHash) -> Transaction { + let params = ureq::json!({ + "jsonrpc": "2.0", + "method": "starknet_getTransactionByHash", + "params": [hash.to_string()], + "id": 1 + }); + let result = self.rpc_call::(¶ms).unwrap()["result"].clone(); + + match result["type"].as_str().unwrap() { + "INVOKE" => match result["version"].as_str().unwrap() { + "0x0" => Transaction::Invoke(InvokeTransaction::V0( + serde_json::from_value(result).unwrap(), + )), + "0x1" => Transaction::Invoke(InvokeTransaction::V1( + serde_json::from_value(result).unwrap(), + )), + _ => unimplemented!(), + }, + _ => unimplemented!(), + } + } + + /// Gets the gas price of a given block. + pub fn get_gas_price(&self, block_number: u64) -> serde_json::Result { + let chain_name = self.get_chain_name(); + + let response = ureq::get(&format!( + "https://{}.starknet.io/feeder_gateway/get_block", + chain_name + )) + .query("blockNumber", &block_number.to_string()) + .call() + .unwrap(); + + let res: serde_json::Value = response.into_json().expect("should be json"); + + let gas_price_hex = res["gas_price"].as_str().unwrap(); + let gas_price = u128::from_str_radix(gas_price_hex.trim_start_matches("0x"), 16).unwrap(); + Ok(gas_price) + } + + pub fn get_chain_name(&self) -> ChainId { + ChainId(match self.chain { + RpcChain::MainNet => "alpha-mainnet".to_string(), + RpcChain::TestNet => "alpha4".to_string(), + RpcChain::TestNet2 => "alpha4-2".to_string(), + }) + } + + pub fn get_block_info(&self) -> RpcBlockInfo { + let get_block_info_params = ureq::json!({ + "jsonrpc": "2.0", + "method": "starknet_getBlockWithTxs", + "params": [self.block.to_value().unwrap()], + "id": 1 + }); + + let block_info: serde_json::Value = self.rpc_call(&get_block_info_params).unwrap(); + let sequencer_address: StarkFelt = + serde_json::from_value(block_info["result"]["sequencer_address"].clone()).unwrap(); + + let transactions: Vec<_> = block_info["result"]["transactions"] + .as_array() + .unwrap() + .iter() + .filter_map(|result| deserialize_transaction_json(result.clone()).ok()) + .collect(); + + RpcBlockInfo { + block_number: BlockNumber( + block_info["result"]["block_number"] + .to_string() + .parse::() + .unwrap(), + ), + block_timestamp: BlockTimestamp( + block_info["result"]["timestamp"] + .to_string() + .parse::() + .unwrap(), + ), + sequencer_address: ContractAddress(sequencer_address.try_into().unwrap()), + transactions, + } + } + + pub fn get_contract_class( + &self, + class_hash: &starknet_api::core::ClassHash, + ) -> BlockifierContractClass { + let params = ureq::json!({ + "jsonrpc": "2.0", + "method": "starknet_getClass", + "params": [self.block.to_value().unwrap(), class_hash.0.to_string()], + "id": 1 + }); + + let response = self.rpc_call_result(¶ms).unwrap(); + + match response { + SNContractClass::Legacy(compressed_legacy_cc) => { + let as_str = utils::decode_reader(compressed_legacy_cc.program).unwrap(); + let program = Program::from_bytes(as_str.as_bytes(), None).unwrap(); + let entry_points_by_type = utils::map_entry_points_by_type_legacy( + compressed_legacy_cc.entry_points_by_type, + ); + let inner = Arc::new(ContractClassV0Inner { + program, + entry_points_by_type, + }); + BlockifierContractClass::V0(ContractClassV0(inner)) + } + SNContractClass::Sierra(flattened_sierra_cc) => { + let middle_sierra: utils::MiddleSierraContractClass = { + let v = serde_json::to_value(flattened_sierra_cc).unwrap(); + serde_json::from_value(v).unwrap() + }; + let sierra_cc = SierraContractClass { + sierra_program: middle_sierra.sierra_program, + contract_class_version: middle_sierra.contract_class_version, + entry_points_by_type: middle_sierra.entry_points_by_type, + sierra_program_debug_info: None, + abi: None, + }; + let casm_cc = CasmContractClass::from_contract_class(sierra_cc, false).unwrap(); + BlockifierContractClass::V1(casm_cc.try_into().unwrap()) + } + } + } + + pub fn get_class_hash_at(&self, contract_address: &ContractAddress) -> ClassHash { + let params = ureq::json!({ + "jsonrpc": "2.0", + "method": "starknet_getClassHashAt", + "params": [self.block.to_value().unwrap(), contract_address.0.key().clone().to_string()], + "id": 1 + }); + + let hash = self.rpc_call_result(¶ms).unwrap(); + + ClassHash(hash) + } + + pub fn get_nonce_at(&self, contract_address: &ContractAddress) -> StarkFelt { + let params = ureq::json!({ + "jsonrpc": "2.0", + "method": "starknet_getNonce", + "params": [self.block.to_value().unwrap(), contract_address.0.key().clone().to_string()], + "id": 1 + }); + + self.rpc_call_result(¶ms).unwrap() + } + + fn get_storage_at(&self, contract_address: &ContractAddress, key: &StorageKey) -> StarkFelt { + let contract_address = contract_address.0.key(); + let key = key.0.key(); + let params = ureq::json!({ + "jsonrpc": "2.0", + "method": "starknet_getStorageAt", + "params": [contract_address.to_string(), + key.to_string(), self.block.to_value().unwrap()], + "id": 1 + }); + + self.rpc_call_result(¶ms).unwrap() + } + + /// Requests the given transaction to the Feeder Gateway API. + pub fn get_transaction_receipt(&self, hash: &TransactionHash) -> RpcTransactionReceipt { + let params = ureq::json!({ + "jsonrpc": "2.0", + "method": "starknet_getTransactionReceipt", + "params": [hash.to_string()], + "id": 1 + }); + self.rpc_call_result(¶ms).unwrap() + } +} + +mod utils { + use std::io::{self, Read}; + + use cairo_lang_utils::bigint::BigUintAsHex; + use starknet::core::types::{LegacyContractEntryPoint, LegacyEntryPointsByType}; + use starknet_api::deprecated_contract_class::{EntryPoint, EntryPointType}; + + use super::*; + + #[derive(Debug, Deserialize)] + pub struct MiddleSierraContractClass { + pub sierra_program: Vec, + pub contract_class_version: String, + pub entry_points_by_type: ContractEntryPoints, + } + + pub(crate) fn map_entry_points_by_type_legacy( + entry_points_by_type: LegacyEntryPointsByType, + ) -> HashMap> { + let entry_types_to_points = HashMap::from([ + ( + EntryPointType::Constructor, + entry_points_by_type.constructor, + ), + (EntryPointType::External, entry_points_by_type.external), + (EntryPointType::L1Handler, entry_points_by_type.l1_handler), + ]); + + let to_contract_entry_point = |entrypoint: &LegacyContractEntryPoint| -> EntryPoint { + let felt: StarkFelt = StarkHash::new(entrypoint.selector.to_bytes_be()).unwrap(); + EntryPoint { + offset: EntryPointOffset(entrypoint.offset as usize), + selector: EntryPointSelector(felt), + } + }; + + let mut entry_points_by_type_map = HashMap::new(); + for (entry_point_type, entry_points) in entry_types_to_points.into_iter() { + let values = entry_points + .iter() + .map(to_contract_entry_point) + .collect::>(); + entry_points_by_type_map.insert(entry_point_type, values); + } + + entry_points_by_type_map + } + + // Uncompresses a Gz Encoded vector of bytes and returns a string or error + // Here &[u8] implements BufRead + pub(crate) fn decode_reader(bytes: Vec) -> io::Result { + use flate2::bufread; + let mut gz = bufread::GzDecoder::new(&bytes[..]); + let mut s = String::new(); + gz.read_to_string(&mut s)?; + Ok(s) + } +} + +#[cfg(test)] +mod tests { + use starknet_api::{ + core::{ClassHash, PatriciaKey}, + hash::StarkFelt, + stark_felt, + }; + + use super::*; + + /// A utility macro to create a [`PatriciaKey`] from a hex string / unsigned integer representation. + /// Imported from starknet_api + macro_rules! patricia_key { + ($s:expr) => { + PatriciaKey::try_from(StarkHash::try_from($s).unwrap()).unwrap() + }; + } + + /// A utility macro to create a [`ClassHash`] from a hex string / unsigned integer representation. + /// Imported from starknet_api + macro_rules! class_hash { + ($s:expr) => { + ClassHash(StarkHash::try_from($s).unwrap()) + }; + } + + /// A utility macro to create a [`ContractAddress`] from a hex string / unsigned integer + /// representation. + /// Imported from starknet_api + macro_rules! contract_address { + ($s:expr) => { + ContractAddress(patricia_key!($s)) + }; + } + + #[test] + fn test_get_contract_class_cairo1() { + let rpc_state = RpcState::new(RpcChain::MainNet, BlockTag::Latest.into()); + + let class_hash = + class_hash!("0298e56befa6d1446b86ed5b900a9ba51fd2faa683cd6f50e8f833c0fb847216"); + // This belongs to + // https://starkscan.co/class/0x0298e56befa6d1446b86ed5b900a9ba51fd2faa683cd6f50e8f833c0fb847216 + // which is cairo1.0 + + rpc_state.get_contract_class(&class_hash); + } + + #[test] + fn test_get_contract_class_cairo0() { + let rpc_state = RpcState::new(RpcChain::MainNet, BlockTag::Latest.into()); + + let class_hash = + class_hash!("025ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918"); + rpc_state.get_contract_class(&class_hash); + } + + #[test] + fn test_get_class_hash_at() { + let rpc_state = RpcState::new(RpcChain::MainNet, BlockTag::Latest.into()); + let address = + contract_address!("00b081f7ba1efc6fe98770b09a827ae373ef2baa6116b3d2a0bf5154136573a9"); + + assert_eq!( + rpc_state.get_class_hash_at(&address), + class_hash!("025ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918") + ); + } + + #[test] + fn test_get_nonce_at() { + let rpc_state = RpcState::new(RpcChain::TestNet, BlockTag::Latest.into()); + // Contract deployed by xqft which will not be used again, so nonce changes will not break + // this test. + let address = + contract_address!("07185f2a350edcc7ea072888edb4507247de23e710cbd56084c356d265626bea"); + assert_eq!(rpc_state.get_nonce_at(&address), stark_felt!("0x0")); + } + + #[test] + fn test_get_storage_at() { + let rpc_state = RpcState::new(RpcChain::MainNet, BlockTag::Latest.into()); + let address = + contract_address!("00b081f7ba1efc6fe98770b09a827ae373ef2baa6116b3d2a0bf5154136573a9"); + let key = StorageKey(patricia_key!(0u128)); + + assert_eq!(rpc_state.get_storage_at(&address, &key), stark_felt!("0x0")); + } + + #[test] + fn test_get_transaction() { + let rpc_state = RpcState::new(RpcChain::MainNet, BlockTag::Latest.into()); + let tx_hash = TransactionHash(stark_felt!( + "06da92cfbdceac5e5e94a1f40772d6c79d34f011815606742658559ec77b6955" + )); + + rpc_state.get_transaction(&tx_hash); + } + + #[test] + fn test_get_block_info() { + let rpc_state = RpcState::new(RpcChain::MainNet, BlockTag::Latest.into()); + + rpc_state.get_block_info(); + } + + // Tested with the following query to the Feeder Gateway API: + // https://alpha4-2.starknet.io/feeder_gateway/get_transaction_trace?transactionHash=0x019feb888a2d53ffddb7a1750264640afab8e9c23119e648b5259f1b5e7d51bc + #[test] + fn test_get_transaction_trace() { + let rpc_state = RpcState::new(RpcChain::TestNet2, BlockTag::Latest.into()); + + let tx_hash = TransactionHash(stark_felt!( + "19feb888a2d53ffddb7a1750264640afab8e9c23119e648b5259f1b5e7d51bc" + )); + + let tx_trace = rpc_state.get_transaction_trace(&tx_hash); + + assert_eq!( + tx_trace.signature, + vec![ + stark_felt!("ffab1c47d8d5e5b76bdcc4af79e98205716c36b440f20244c69599a91ace58"), + stark_felt!("6aa48a0906c9c1f7381c1a040c043b649eeac1eea08f24a9d07813f6b1d05fe"), + ] + ); + + assert_eq!( + tx_trace.validate_invocation.calldata, + Some(vec![ + stark_felt!("1"), + stark_felt!("690c876e61beda61e994543af68038edac4e1cb1990ab06e52a2d27e56a1232"), + stark_felt!("1f24f689ced5802b706d7a2e28743fe45c7bfa37431c97b1c766e9622b65573"), + stark_felt!("0"), + stark_felt!("9"), + stark_felt!("9"), + stark_felt!("4"), + stark_felt!("4254432d55534443"), + stark_felt!("f02e7324ecbd65ce267"), + stark_felt!("5754492d55534443"), + stark_felt!("8e13050d06d8f514c"), + stark_felt!("4554482d55534443"), + stark_felt!("f0e4a142c3551c149d"), + stark_felt!("4a50592d55534443"), + stark_felt!("38bd34c31a0a5c"), + ]) + ); + assert_eq!(tx_trace.validate_invocation.retdata, Some(vec![])); + assert_eq!( + tx_trace.validate_invocation.execution_resources, + VmExecutionResources { + n_steps: 790, + n_memory_holes: 51, + builtin_instance_counter: HashMap::from([ + ("range_check_builtin".to_string(), 20), + ("ecdsa_builtin".to_string(), 1), + ("pedersen_builtin".to_string(), 2), + ]), + } + ); + assert_eq!(tx_trace.validate_invocation.internal_calls.len(), 1); + + assert_eq!( + tx_trace.function_invocation.calldata, + Some(vec![ + stark_felt!("1"), + stark_felt!("690c876e61beda61e994543af68038edac4e1cb1990ab06e52a2d27e56a1232"), + stark_felt!("1f24f689ced5802b706d7a2e28743fe45c7bfa37431c97b1c766e9622b65573"), + stark_felt!("0"), + stark_felt!("9"), + stark_felt!("9"), + stark_felt!("4"), + stark_felt!("4254432d55534443"), + stark_felt!("f02e7324ecbd65ce267"), + stark_felt!("5754492d55534443"), + stark_felt!("8e13050d06d8f514c"), + stark_felt!("4554482d55534443"), + stark_felt!("f0e4a142c3551c149d"), + stark_felt!("4a50592d55534443"), + stark_felt!("38bd34c31a0a5c"), + ]) + ); + assert_eq!( + tx_trace.function_invocation.retdata, + Some(vec![0u128.into()]) + ); + assert_eq!( + tx_trace.function_invocation.execution_resources, + VmExecutionResources { + n_steps: 2808, + n_memory_holes: 136, + builtin_instance_counter: HashMap::from([ + ("range_check_builtin".to_string(), 49), + ("pedersen_builtin".to_string(), 14), + ]), + } + ); + assert_eq!(tx_trace.function_invocation.internal_calls.len(), 1); + assert_eq!( + tx_trace.function_invocation.internal_calls[0] + .internal_calls + .len(), + 1 + ); + assert_eq!( + tx_trace.function_invocation.internal_calls[0].internal_calls[0] + .internal_calls + .len(), + 7 + ); + + assert_eq!( + tx_trace.fee_transfer_invocation.calldata, + Some(vec![ + stark_felt!("1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8"), + stark_felt!("2b0322a23ba4"), + stark_felt!("0"), + ]) + ); + assert_eq!( + tx_trace.fee_transfer_invocation.retdata, + Some(vec![1u128.into()]) + ); + assert_eq!( + tx_trace.fee_transfer_invocation.execution_resources, + VmExecutionResources { + n_steps: 586, + n_memory_holes: 42, + builtin_instance_counter: HashMap::from([ + ("range_check_builtin".to_string(), 21), + ("pedersen_builtin".to_string(), 4), + ]), + } + ); + assert_eq!(tx_trace.fee_transfer_invocation.internal_calls.len(), 1); + } + + #[test] + fn test_get_transaction_receipt() { + let rpc_state = RpcState::new(RpcChain::MainNet, BlockTag::Latest.into()); + let tx_hash = TransactionHash(stark_felt!( + "06da92cfbdceac5e5e94a1f40772d6c79d34f011815606742658559ec77b6955" + )); + + rpc_state.get_transaction_receipt(&tx_hash); + } +} + +mod blockifier_transaction_tests { + use blockifier::{ + block_context::BlockContext, + execution::contract_class::ContractClass, + state::{ + cached_state::{CachedState, GlobalContractCache}, + state_api::{StateReader, StateResult}, + }, + transaction::{ + account_transaction::AccountTransaction, + objects::TransactionExecutionInfo, + transactions::{ExecutableTransaction, InvokeTransaction}, + }, + }; + use starknet_api::{ + contract_address, + core::{CompiledClassHash, Nonce, PatriciaKey}, + patricia_key, stark_felt, + transaction::TransactionHash, + }; + + use super::*; + + pub struct RpcStateReader(RpcState); + + impl StateReader for RpcStateReader { + fn get_storage_at( + &mut self, + contract_address: ContractAddress, + key: StorageKey, + ) -> StateResult { + Ok(self.0.get_storage_at(&contract_address, &key)) + } + + fn get_nonce_at(&mut self, contract_address: ContractAddress) -> StateResult { + Ok(Nonce(self.0.get_nonce_at(&contract_address))) + } + + fn get_class_hash_at( + &mut self, + contract_address: ContractAddress, + ) -> StateResult { + Ok(self.0.get_class_hash_at(&contract_address)) + } + + /// Returns the contract class of the given class hash. + fn get_compiled_contract_class( + &mut self, + class_hash: &ClassHash, + ) -> StateResult { + Ok(self.0.get_contract_class(class_hash)) + } + + /// Returns the compiled class hash of the given class hash. + fn get_compiled_class_hash( + &mut self, + class_hash: ClassHash, + ) -> StateResult { + Ok(CompiledClassHash( + self.0 + .get_class_hash_at(&ContractAddress(class_hash.0.try_into().unwrap())) + .0, + )) + } + } + + #[allow(unused)] + pub fn execute_tx( + tx_hash: &str, + network: RpcChain, + block_number: BlockNumber, + ) -> ( + TransactionExecutionInfo, + TransactionTrace, + RpcTransactionReceipt, + ) { + let tx_hash = tx_hash.strip_prefix("0x").unwrap(); + + // Instantiate the RPC StateReader and the CachedState + let rpc_reader = RpcStateReader(RpcState::new(network, block_number.into())); + let gas_price = rpc_reader.0.get_gas_price(block_number.0).unwrap(); + + // Get values for block context before giving ownership of the reader + let chain_id = rpc_reader.0.get_chain_name(); + let RpcBlockInfo { + block_number, + block_timestamp, + sequencer_address, + .. + } = rpc_reader.0.get_block_info(); + + // Get transaction before giving ownership of the reader + let tx_hash = TransactionHash(stark_felt!(tx_hash)); + let sn_api_tx = rpc_reader.0.get_transaction(&tx_hash); + + let trace = rpc_reader.0.get_transaction_trace(&tx_hash); + let receipt = rpc_reader.0.get_transaction_receipt(&tx_hash); + + // Create state from RPC reader + let global_cache = GlobalContractCache::default(); + let mut state = CachedState::new(rpc_reader, global_cache); + + let fee_token_address = + contract_address!("049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"); + + const N_STEPS_FEE_WEIGHT: f64 = 0.01; + let vm_resource_fee_cost = Arc::new(HashMap::from([ + ("n_steps".to_string(), N_STEPS_FEE_WEIGHT), + ("output_builtin".to_string(), 0.0), + ("pedersen_builtin".to_string(), N_STEPS_FEE_WEIGHT * 32.0), + ("range_check_builtin".to_string(), N_STEPS_FEE_WEIGHT * 16.0), + ("ecdsa_builtin".to_string(), N_STEPS_FEE_WEIGHT * 2048.0), + ("bitwise_builtin".to_string(), N_STEPS_FEE_WEIGHT * 64.0), + ("ec_op_builtin".to_string(), N_STEPS_FEE_WEIGHT * 1024.0), + ("poseidon_builtin".to_string(), N_STEPS_FEE_WEIGHT * 32.0), + ( + "segment_arena_builtin".to_string(), + N_STEPS_FEE_WEIGHT * 10.0, + ), + ("keccak_builtin".to_string(), N_STEPS_FEE_WEIGHT * 2048.0), // 2**11 + ])); + + let block_context = BlockContext { + chain_id, + block_number, + block_timestamp, + sequencer_address, + fee_token_address, + vm_resource_fee_cost, + gas_price, + invoke_tx_max_n_steps: 1_000_000, + validate_max_n_steps: 1_000_000, + max_recursion_depth: 500, + }; + + // Map starknet_api transaction to blockifier's + let blockifier_tx = match sn_api_tx { + Transaction::Invoke(tx) => { + let invoke = InvokeTransaction { tx, tx_hash }; + AccountTransaction::Invoke(invoke) + } + _ => unimplemented!(), + }; + + ( + blockifier_tx + .execute(&mut state, &block_context, true, true) + .unwrap(), + trace, + receipt, + ) + } + + #[cfg(test)] + mod test { + use blockifier::execution::entry_point::CallInfo; + + use super::*; + + #[test] + fn test_get_gas_price() { + let block = BlockValue::Number(BlockNumber(169928)); + let rpc_state = RpcState::new(RpcChain::MainNet, block); + + let price = rpc_state.get_gas_price(169928).unwrap(); + assert_eq!(price, 22804578690); + } + + #[test] + fn test_recent_tx() { + let (tx_info, trace, receipt) = execute_tx( + "0x05d200ef175ba15d676a68b36f7a7b72c17c17604eda4c1efc2ed5e4973e2c91", + RpcChain::MainNet, + BlockNumber(169928), + ); + + let TransactionExecutionInfo { + execute_call_info, + actual_fee, + .. + } = tx_info; + + let CallInfo { + vm_resources, + inner_calls, + .. + } = execute_call_info.unwrap(); + + assert_eq!(vm_resources, trace.function_invocation.execution_resources); + assert_eq!( + inner_calls.len(), + trace.function_invocation.internal_calls.len() + ); + + assert_eq!(actual_fee.0, receipt.actual_fee); + } + } +} diff --git a/src/bin/fibonacci.rs b/src/bin/fibonacci.rs index b14be188a..df61410cf 100644 --- a/src/bin/fibonacci.rs +++ b/src/bin/fibonacci.rs @@ -5,9 +5,13 @@ use num_traits::Zero; use lazy_static::lazy_static; use starknet_in_rust::{ - services::api::contract_classes::deprecated_contract_class::ContractClass, - state::cached_state::CachedState, state::in_memory_state_reader::InMemoryStateReader, - testing::state::StarknetState, utils::Address, + services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::ContractClass, + }, + state::cached_state::CachedState, + state::in_memory_state_reader::InMemoryStateReader, + testing::state::StarknetState, + utils::Address, }; #[cfg(feature = "with_mimalloc")] @@ -78,17 +82,17 @@ fn create_initial_state() -> CachedState { state_reader .address_to_nonce_mut() .insert(CONTRACT_ADDRESS.clone(), Felt252::zero()); - state_reader - .class_hash_to_contract_class_mut() - .insert(*CONTRACT_CLASS_HASH, CONTRACT_CLASS.clone()); + state_reader.class_hash_to_compiled_class_mut().insert( + *CONTRACT_CLASS_HASH, + CompiledClass::Deprecated(Arc::new(CONTRACT_CLASS.clone())), + ); state_reader .address_to_storage_mut() .insert((CONTRACT_ADDRESS.clone(), [0; 32]), Felt252::zero()); Arc::new(state_reader) }, - Some(HashMap::new()), - None, + HashMap::new(), ); cached_state diff --git a/src/bin/invoke.rs b/src/bin/invoke.rs index afec929fa..f29a78ad0 100644 --- a/src/bin/invoke.rs +++ b/src/bin/invoke.rs @@ -4,9 +4,13 @@ use cairo_vm::felt::{felt_str, Felt252}; use num_traits::Zero; use starknet_in_rust::{ - services::api::contract_classes::deprecated_contract_class::ContractClass, - state::cached_state::CachedState, state::in_memory_state_reader::InMemoryStateReader, - testing::state::StarknetState, utils::Address, + services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::ContractClass, + }, + state::cached_state::CachedState, + state::in_memory_state_reader::InMemoryStateReader, + testing::state::StarknetState, + utils::Address, }; use lazy_static::lazy_static; @@ -92,17 +96,17 @@ fn create_initial_state() -> CachedState { state_reader .address_to_nonce_mut() .insert(CONTRACT_ADDRESS.clone(), Felt252::zero()); - state_reader - .class_hash_to_contract_class_mut() - .insert(*CONTRACT_CLASS_HASH, CONTRACT_CLASS.clone()); + state_reader.class_hash_to_compiled_class_mut().insert( + *CONTRACT_CLASS_HASH, + CompiledClass::Deprecated(Arc::new(CONTRACT_CLASS.clone())), + ); state_reader .address_to_storage_mut() .insert((CONTRACT_ADDRESS.clone(), [0; 32]), Felt252::zero()); Arc::new(state_reader) }, - Some(HashMap::new()), - None, + HashMap::new(), ); cached_state diff --git a/src/bin/invoke_with_cachedstate.rs b/src/bin/invoke_with_cachedstate.rs index e5c7cac2f..4868a0ab4 100644 --- a/src/bin/invoke_with_cachedstate.rs +++ b/src/bin/invoke_with_cachedstate.rs @@ -8,7 +8,9 @@ use starknet_in_rust::{ block_context::{BlockContext, StarknetChainId, StarknetOsConfig}, constants::TRANSACTION_VERSION, }, - services::api::contract_classes::deprecated_contract_class::ContractClass, + services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::ContractClass, + }, state::in_memory_state_reader::InMemoryStateReader, state::{cached_state::CachedState, BlockInfo}, transaction::InvokeFunction, @@ -99,17 +101,17 @@ fn create_initial_state() -> CachedState { state_reader .address_to_nonce_mut() .insert(CONTRACT_ADDRESS.clone(), Felt252::zero()); - state_reader - .class_hash_to_contract_class_mut() - .insert(*CONTRACT_CLASS_HASH, CONTRACT_CLASS.clone()); + state_reader.class_hash_to_compiled_class_mut().insert( + *CONTRACT_CLASS_HASH, + CompiledClass::Deprecated(Arc::new(CONTRACT_CLASS.clone())), + ); state_reader .address_to_storage_mut() .insert((CONTRACT_ADDRESS.clone(), [0; 32]), Felt252::zero()); Arc::new(state_reader) }, - Some(HashMap::new()), - None, + HashMap::new(), ); cached_state diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index 554463471..b16b500a9 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -128,11 +128,8 @@ impl ExecutionEntryPoint { }) } CompiledClass::Casm(contract_class) => { - let mut tmp_state = CachedState::new( - state.state_reader.clone(), - state.contract_classes.clone(), - state.casm_contract_classes.clone(), - ); + let mut tmp_state = + CachedState::new(state.state_reader.clone(), state.contract_classes.clone()); tmp_state.cache = state.cache.clone(); match self._execute( diff --git a/src/lib.rs b/src/lib.rs index 5ee7ec961..004c5afd3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,7 +62,7 @@ pub fn simulate_transaction( ignore_max_fee: bool, skip_nonce_check: bool, ) -> Result, TransactionError> { - let mut cache_state = CachedState::new(Arc::new(state), None, Some(HashMap::new())); + let mut cache_state = CachedState::new(Arc::new(state), HashMap::new()); let mut result = Vec::with_capacity(transactions.len()); for transaction in transactions { let tx_for_simulation = transaction.create_for_simulation( @@ -90,7 +90,7 @@ where T: StateReader, { // This is used as a copy of the original state, we can update this cached state freely. - let mut cached_state = CachedState::::new(Arc::new(state), None, None); + let mut cached_state = CachedState::::new(Arc::new(state), HashMap::new()); let mut result = Vec::with_capacity(transactions.len()); for transaction in transactions { @@ -178,7 +178,7 @@ where T: StateReader, { // This is used as a copy of the original state, we can update this cached state freely. - let mut cached_state = CachedState::::new(Arc::new(state), None, None); + let mut cached_state = CachedState::::new(Arc::new(state), HashMap::new()); // Check if the contract is deployed. cached_state.get_class_hash_at(l1_handler.contract_address())?; @@ -252,6 +252,7 @@ mod test { utils::{Address, ClassHash}, }; + use crate::services::api::contract_classes::compiled_class::CompiledClass; use lazy_static::lazy_static; lazy_static! { @@ -318,7 +319,7 @@ mod test { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -327,7 +328,7 @@ mod test { .address_to_nonce_mut() .insert(address.clone(), nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let calldata = [1.into(), 1.into(), 10.into()].to_vec(); let retdata = call_contract( @@ -379,10 +380,13 @@ mod test { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes - let contract_classes = HashMap::from([(class_hash, contract_class)]); + let contract_classes = HashMap::from([( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + )]); state.set_contract_classes(contract_classes).unwrap(); let mut block_context = BlockContext::default(); @@ -408,7 +412,8 @@ mod test { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); + let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -417,7 +422,7 @@ mod test { .address_to_nonce_mut() .insert(address.clone(), nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let calldata = [1.into(), 1.into(), 10.into()].to_vec(); let invoke = InvokeFunction::new( @@ -484,9 +489,10 @@ mod test { .insert(address.clone(), nonce); // simulate deploy - state_reader - .class_hash_to_contract_class_mut() - .insert(acc_class_hash, contract_class); + state_reader.class_hash_to_compiled_class_mut().insert( + acc_class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let hash = felt_str!( "134328839377938040543570691566621575472567895629741043448357033688476792132" @@ -495,9 +501,10 @@ mod test { state_reader .class_hash_to_compiled_class_hash_mut() .insert(fib_address, class_hash); - state_reader - .casm_contract_classes - .insert(fib_address, casm_contract_class); + state_reader.class_hash_to_compiled_class.insert( + fib_address, + CompiledClass::Casm(Arc::new(casm_contract_class)), + ); let calldata = [ address.0.clone(), @@ -611,9 +618,10 @@ mod test { .insert(address.clone(), nonce); // simulate deploy - state_reader - .class_hash_to_contract_class_mut() - .insert(acc_class_hash, contract_class); + state_reader.class_hash_to_compiled_class_mut().insert( + acc_class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let hash = felt_str!( "134328839377938040543570691566621575472567895629741043448357033688476792132" @@ -622,9 +630,10 @@ mod test { state_reader .class_hash_to_compiled_class_hash_mut() .insert(fib_address, class_hash); - state_reader - .casm_contract_classes - .insert(fib_address, casm_contract_class); + state_reader.class_hash_to_compiled_class.insert( + fib_address, + CompiledClass::Casm(Arc::new(casm_contract_class)), + ); let calldata = [ address.0.clone(), @@ -673,10 +682,13 @@ mod test { #[test] fn test_simulate_deploy() { let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(Default::default()), None); + let mut state = CachedState::new(state_reader, HashMap::new()); state - .set_contract_class(&CLASS_HASH_BYTES, &CONTRACT_CLASS) + .set_contract_class( + &CLASS_HASH_BYTES, + &CompiledClass::Deprecated(Arc::new(CONTRACT_CLASS.clone())), + ) .unwrap(); let block_context = &Default::default(); @@ -712,7 +724,7 @@ mod test { #[test] fn test_simulate_declare() { let state_reader = Arc::new(InMemoryStateReader::default()); - let state = CachedState::new(state_reader, Some(Default::default()), None); + let state = CachedState::new(state_reader, HashMap::new()); let block_context = &Default::default(); @@ -749,10 +761,13 @@ mod test { #[test] fn test_simulate_invoke() { let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(Default::default()), None); + let mut state = CachedState::new(state_reader, HashMap::new()); state - .set_contract_class(&CLASS_HASH_BYTES, &CONTRACT_CLASS) + .set_contract_class( + &CLASS_HASH_BYTES, + &CompiledClass::Deprecated(Arc::new(CONTRACT_CLASS.clone())), + ) .unwrap(); let block_context = Default::default(); @@ -810,10 +825,13 @@ mod test { #[test] fn test_simulate_deploy_account() { let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(Default::default()), None); + let mut state = CachedState::new(state_reader, HashMap::new()); state - .set_contract_class(&CLASS_HASH_BYTES, &CONTRACT_CLASS) + .set_contract_class( + &CLASS_HASH_BYTES, + &CompiledClass::Deprecated(Arc::new(CONTRACT_CLASS.clone())), + ) .unwrap(); let block_context = &Default::default(); @@ -931,13 +949,16 @@ mod test { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let mut block_context = BlockContext::default(); @@ -960,7 +981,7 @@ mod test { #[test] fn test_deploy_and_invoke_simulation() { let state_reader = Arc::new(InMemoryStateReader::default()); - let state = CachedState::new(state_reader, Some(Default::default()), None); + let state = CachedState::new(state_reader, HashMap::new()); let block_context = &Default::default(); diff --git a/src/services/api/contract_classes/deprecated_contract_class.rs b/src/services/api/contract_classes/deprecated_contract_class.rs index 2736bbca4..a1ef5c367 100644 --- a/src/services/api/contract_classes/deprecated_contract_class.rs +++ b/src/services/api/contract_classes/deprecated_contract_class.rs @@ -265,9 +265,7 @@ mod tests { felt::{felt_str, PRIME_STR}, serde::deserialize_program::BuiltinName, }; - use starknet_api::deprecated_contract_class::{ - FunctionAbiEntry, FunctionAbiEntryType, FunctionAbiEntryWithType, TypedParameter, - }; + use starknet_api::deprecated_contract_class::{FunctionAbiEntry, TypedParameter}; #[test] fn deserialize_contract_class() { @@ -333,34 +331,28 @@ mod tests { // This specific contract compiles with --no_debug_info let res = ContractClass::from_path("starknet_programs/fibonacci.json"); let contract_class = res.expect("should be able to read file"); - - let expected_abi = Some(vec![ContractClassAbiEntry::Function( - FunctionAbiEntryWithType { - r#type: FunctionAbiEntryType::Function, - entry: FunctionAbiEntry { - name: "fib".to_string(), - inputs: vec![ - TypedParameter { - name: "first_element".to_string(), - r#type: "felt".to_string(), - }, - TypedParameter { - name: "second_element".to_string(), - r#type: "felt".to_string(), - }, - TypedParameter { - name: "n".to_string(), - r#type: "felt".to_string(), - }, - ], - outputs: vec![TypedParameter { - name: "res".to_string(), - r#type: "felt".to_string(), - }], - state_mutability: None, + let expected_abi = Some(vec![ContractClassAbiEntry::Function(FunctionAbiEntry { + name: "fib".to_string(), + inputs: vec![ + TypedParameter { + name: "first_element".to_string(), + r#type: "felt".to_string(), + }, + TypedParameter { + name: "second_element".to_string(), + r#type: "felt".to_string(), + }, + TypedParameter { + name: "n".to_string(), + r#type: "felt".to_string(), }, - }, - )]); + ], + outputs: vec![TypedParameter { + name: "res".to_string(), + r#type: "felt".to_string(), + }], + state_mutability: None, + })]); assert_eq!(contract_class.abi, expected_abi); } diff --git a/src/state/cached_state.rs b/src/state/cached_state.rs index 8b2298de8..f451d5e97 100644 --- a/src/state/cached_state.rs +++ b/src/state/cached_state.rs @@ -4,13 +4,10 @@ use super::{ }; use crate::{ core::errors::state_errors::StateError, - services::api::contract_classes::{ - compiled_class::CompiledClass, deprecated_contract_class::ContractClass, - }, + services::api::contract_classes::compiled_class::CompiledClass, state::StateDiff, utils::{subtract_mappings, to_cache_state_storage_mapping, Address, ClassHash}, }; -use cairo_lang_starknet::casm_contract_class::CasmContractClass; use cairo_vm::felt::Felt252; use getset::{Getters, MutGetters}; use num_traits::Zero; @@ -19,11 +16,9 @@ use std::{ sync::Arc, }; -// K: class_hash V: ContractClass -pub type ContractClassCache = HashMap; -pub type CasmClassCache = HashMap; +pub type ContractClassCache = HashMap; -pub const UNINITIALIZED_CLASS_HASH: &ClassHash = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; +pub const UNINITIALIZED_CLASS_HASH: &ClassHash = &[0u8; 32]; /// Represents a cached state of contract classes with optional caches. #[derive(Default, Clone, Debug, Eq, Getters, MutGetters, PartialEq)] @@ -32,38 +27,29 @@ pub struct CachedState { #[getset(get = "pub", get_mut = "pub")] pub(crate) cache: StateCache, #[get = "pub"] - pub(crate) contract_classes: Option, - #[get = "pub"] - pub(crate) casm_contract_classes: Option, + pub(crate) contract_classes: ContractClassCache, } impl CachedState { /// Constructor, creates a new cached state. - pub fn new( - state_reader: Arc, - contract_class_cache: Option, - casm_class_cache: Option, - ) -> Self { + pub fn new(state_reader: Arc, contract_classes: ContractClassCache) -> Self { Self { cache: StateCache::default(), - contract_classes: contract_class_cache, state_reader, - casm_contract_classes: casm_class_cache, + contract_classes, } } /// Creates a CachedState for testing purposes. pub fn new_for_testing( state_reader: Arc, - contract_classes: Option, cache: StateCache, - casm_contract_classes: Option, + contract_classes: ContractClassCache, ) -> Self { Self { cache, contract_classes, state_reader, - casm_contract_classes, } } @@ -72,20 +58,12 @@ impl CachedState { &mut self, contract_classes: ContractClassCache, ) -> Result<(), StateError> { - if self.contract_classes.is_some() { + if !self.contract_classes.is_empty() { return Err(StateError::AssignedContractClassCache); } - self.contract_classes = Some(contract_classes); + self.contract_classes = contract_classes; Ok(()) } - - /// Returns the casm classes. - #[allow(dead_code)] - pub(crate) fn get_casm_classes(&mut self) -> Result<&CasmClassCache, StateError> { - self.casm_contract_classes - .as_ref() - .ok_or(StateError::MissingCasmClassCache) - } } impl StateReader for CachedState { @@ -172,36 +150,21 @@ impl StateReader for CachedState { if class_hash == UNINITIALIZED_CLASS_HASH { return Err(StateError::UninitiaizedClassHash); } + // I: FETCHING FROM CACHE - // I: DEPRECATED CONTRACT CLASS - // deprecated contract classes dont have compiled class hashes, so we only have one case - if let Some(compiled_class) = self - .contract_classes - .as_ref() - .and_then(|x| x.get(class_hash)) - { - return Ok(CompiledClass::Deprecated(Arc::new(compiled_class.clone()))); - } - // I: CASM CONTRACT CLASS : COMPILED_CLASS_HASH - if let Some(compiled_class) = self - .casm_contract_classes - .as_ref() - .and_then(|x| x.get(class_hash)) - { - return Ok(CompiledClass::Casm(Arc::new(compiled_class.clone()))); + if let Some(compiled_class) = self.contract_classes.get(class_hash) { + return Ok(compiled_class.clone()); } + // I: CASM CONTRACT CLASS : CLASS_HASH if let Some(compiled_class_hash) = self.cache.class_hash_to_compiled_class_hash.get(class_hash) { - if let Some(casm_class) = &mut self - .casm_contract_classes - .as_ref() - .and_then(|m| m.get(compiled_class_hash)) - { - return Ok(CompiledClass::Casm(Arc::new(casm_class.clone()))); + if let Some(casm_class) = self.contract_classes.get(compiled_class_hash) { + return Ok(casm_class.clone()); } } + // II: FETCHING FROM STATE_READER self.state_reader.get_contract_class(class_hash) } @@ -212,17 +175,11 @@ impl State for CachedState { fn set_contract_class( &mut self, class_hash: &ClassHash, - contract_class: &ContractClass, + contract_class: &CompiledClass, ) -> Result<(), StateError> { - match self.contract_classes.as_mut() { - Some(x) => { - x.insert(*class_hash, contract_class.clone()); - } - None => { - self.contract_classes = Some(HashMap::new()); - self.set_contract_class(class_hash, contract_class)?; - } - } + self.contract_classes + .insert(*class_hash, contract_class.clone()); + Ok(()) } @@ -285,20 +242,6 @@ impl State for CachedState { Ok(()) } - fn set_compiled_class( - &mut self, - compiled_class_hash: &Felt252, - casm_class: CasmContractClass, - ) -> Result<(), StateError> { - let compiled_class_hash = compiled_class_hash.to_be_bytes(); - - self.casm_contract_classes - .as_mut() - .ok_or(StateError::MissingCasmClassCache)? - .insert(compiled_class_hash, casm_class); - Ok(()) - } - fn set_compiled_class_hash( &mut self, class_hash: &Felt252, @@ -437,48 +380,35 @@ impl State for CachedState { if class_hash == UNINITIALIZED_CLASS_HASH { return Err(StateError::UninitiaizedClassHash); } + // I: FETCHING FROM CACHE - // I: DEPRECATED CONTRACT CLASS // deprecated contract classes dont have compiled class hashes, so we only have one case - if let Some(compiled_class) = self - .contract_classes - .as_ref() - .and_then(|x| x.get(class_hash)) - { - return Ok(CompiledClass::Deprecated(Arc::new(compiled_class.clone()))); - } - // I: CASM CONTRACT CLASS : COMPILED_CLASS_HASH - if let Some(compiled_class) = self - .casm_contract_classes - .as_ref() - .and_then(|x| x.get(class_hash)) - { - return Ok(CompiledClass::Casm(Arc::new(compiled_class.clone()))); + if let Some(compiled_class) = self.contract_classes.get(class_hash) { + return Ok(compiled_class.clone()); } + // I: CASM CONTRACT CLASS : CLASS_HASH if let Some(compiled_class_hash) = self.cache.class_hash_to_compiled_class_hash.get(class_hash) { - if let Some(casm_class) = &mut self - .casm_contract_classes - .as_ref() - .and_then(|m| m.get(compiled_class_hash)) - { - return Ok(CompiledClass::Casm(Arc::new(casm_class.clone()))); + if let Some(casm_class) = self.contract_classes.get(compiled_class_hash) { + return Ok(casm_class.clone()); } } + // II: FETCHING FROM STATE_READER let contract = self.state_reader.get_contract_class(class_hash)?; match contract { - CompiledClass::Casm(ref class) => { + CompiledClass::Casm(ref casm_class) => { // We call this method instead of state_reader's in order to update the cache's class_hash_initial_values map let compiled_class_hash = self.get_compiled_class_hash(class_hash)?; - self.casm_contract_classes - .as_mut() - .and_then(|m| m.insert(compiled_class_hash, class.as_ref().clone())); + self.set_contract_class( + &compiled_class_hash, + &CompiledClass::Casm(casm_class.clone()), + )?; } CompiledClass::Deprecated(ref contract) => { - self.set_contract_class(class_hash, &contract.clone())? + self.set_contract_class(class_hash, &CompiledClass::Deprecated(contract.clone()))? } } Ok(contract) @@ -489,7 +419,10 @@ impl State for CachedState { mod tests { use super::*; - use crate::state::in_memory_state_reader::InMemoryStateReader; + use crate::{ + services::api::contract_classes::deprecated_contract_class::ContractClass, + state::in_memory_state_reader::InMemoryStateReader, + }; use num_traits::One; @@ -503,7 +436,6 @@ mod tests { HashMap::new(), HashMap::new(), HashMap::new(), - HashMap::new(), ); let contract_address = Address(4242.into()); @@ -522,7 +454,7 @@ mod tests { .address_to_storage_mut() .insert(storage_entry, storage_value); - let mut cached_state = CachedState::new(Arc::new(state_reader), None, None); + let mut cached_state = CachedState::new(Arc::new(state_reader), HashMap::new()); assert_eq!( cached_state.get_class_hash_at(&contract_address).unwrap(), @@ -545,20 +477,18 @@ mod tests { HashMap::new(), HashMap::new(), HashMap::new(), - HashMap::new(), ); let contract_class = ContractClass::from_path("starknet_programs/raw_contract_classes/class_with_abi.json") .unwrap(); state_reader - .class_hash_to_contract_class - .insert([1; 32], contract_class); + .class_hash_to_compiled_class + .insert([1; 32], CompiledClass::Deprecated(Arc::new(contract_class))); - let mut cached_state = CachedState::new(Arc::new(state_reader), None, None); + let mut cached_state = CachedState::new(Arc::new(state_reader), HashMap::new()); cached_state.set_contract_classes(HashMap::new()).unwrap(); - assert!(cached_state.contract_classes.is_some()); assert_eq!( cached_state.get_contract_class(&[1; 32]).unwrap(), @@ -573,7 +503,7 @@ mod tests { #[test] fn cached_state_storage_test() { let mut cached_state = - CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let storage_entry: StorageEntry = (Address(31.into()), [0; 32]); let value = Felt252::new(10); @@ -595,7 +525,7 @@ mod tests { let contract_address = Address(32123.into()); - let mut cached_state = CachedState::new(state_reader, None, None); + let mut cached_state = CachedState::new(state_reader, HashMap::new()); assert!(cached_state .deploy_contract(contract_address, [10; 32]) @@ -611,7 +541,7 @@ mod tests { let storage_key = [18; 32]; let value = Felt252::new(912); - let mut cached_state = CachedState::new(state_reader, None, None); + let mut cached_state = CachedState::new(state_reader, HashMap::new()); // set storage_key cached_state.set_storage_at(&(contract_address.clone(), storage_key), value.clone()); @@ -629,27 +559,6 @@ mod tests { assert_eq!(new_result.unwrap(), new_value); } - /// This test ensures that an error is thrown when trying to set contract classes twice. - #[test] - fn set_contract_classes_twice_error_test() { - let state_reader = InMemoryStateReader::new( - HashMap::new(), - HashMap::new(), - HashMap::new(), - HashMap::new(), - HashMap::new(), - HashMap::new(), - ); - let mut cached_state = CachedState::new(Arc::new(state_reader), None, None); - - cached_state.set_contract_classes(HashMap::new()).unwrap(); - let result = cached_state - .set_contract_classes(HashMap::new()) - .unwrap_err(); - - assert_matches!(result, StateError::AssignedContractClassCache); - } - /// This test ensures that an error is thrown if a contract address is out of range. #[test] fn deploy_contract_address_out_of_range_error_test() { @@ -659,12 +568,11 @@ mod tests { HashMap::new(), HashMap::new(), HashMap::new(), - HashMap::new(), ); let contract_address = Address(0.into()); - let mut cached_state = CachedState::new(Arc::new(state_reader), None, None); + let mut cached_state = CachedState::new(Arc::new(state_reader), HashMap::new()); let result = cached_state .deploy_contract(contract_address.clone(), [10; 32]) @@ -685,12 +593,11 @@ mod tests { HashMap::new(), HashMap::new(), HashMap::new(), - HashMap::new(), ); let contract_address = Address(42.into()); - let mut cached_state = CachedState::new(Arc::new(state_reader), None, None); + let mut cached_state = CachedState::new(Arc::new(state_reader), HashMap::new()); cached_state .deploy_contract(contract_address.clone(), [10; 32]) @@ -714,12 +621,11 @@ mod tests { HashMap::new(), HashMap::new(), HashMap::new(), - HashMap::new(), ); let contract_address = Address(32123.into()); - let mut cached_state = CachedState::new(Arc::new(state_reader), None, None); + let mut cached_state = CachedState::new(Arc::new(state_reader), HashMap::new()); cached_state .deploy_contract(contract_address.clone(), [10; 32]) @@ -744,12 +650,11 @@ mod tests { HashMap::new(), HashMap::new(), HashMap::new(), - HashMap::new(), ); let address_one = Address(Felt252::one()); - let mut cached_state = CachedState::new(Arc::new(state_reader), None, None); + let mut cached_state = CachedState::new(Arc::new(state_reader), HashMap::new()); let state_diff = StateDiff { address_to_class_hash: HashMap::from([( @@ -784,7 +689,7 @@ mod tests { #[test] fn count_actual_storage_changes_test() { let state_reader = InMemoryStateReader::default(); - let mut cached_state = CachedState::new(Arc::new(state_reader), None, None); + let mut cached_state = CachedState::new(Arc::new(state_reader), HashMap::new()); let address_one = Address(1.into()); let address_two = Address(2.into()); diff --git a/src/state/in_memory_state_reader.rs b/src/state/in_memory_state_reader.rs index de9b3e827..7a7f1c372 100644 --- a/src/state/in_memory_state_reader.rs +++ b/src/state/in_memory_state_reader.rs @@ -1,19 +1,15 @@ use crate::{ core::errors::state_errors::StateError, - services::api::contract_classes::{ - compiled_class::CompiledClass, deprecated_contract_class::ContractClass, - }, + services::api::contract_classes::compiled_class::CompiledClass, state::{ - cached_state::{CasmClassCache, UNINITIALIZED_CLASS_HASH}, - state_api::StateReader, - state_cache::StorageEntry, + cached_state::UNINITIALIZED_CLASS_HASH, state_api::StateReader, state_cache::StorageEntry, }, utils::{Address, ClassHash, CompiledClassHash}, }; use cairo_vm::felt::Felt252; use getset::{Getters, MutGetters}; use num_traits::Zero; -use std::{collections::HashMap, sync::Arc}; +use std::collections::HashMap; /// A [StateReader] that holds all the data in memory. /// @@ -28,9 +24,7 @@ pub struct InMemoryStateReader { #[getset(get_mut = "pub")] pub address_to_storage: HashMap, #[getset(get_mut = "pub")] - pub class_hash_to_contract_class: HashMap, - #[getset(get_mut = "pub")] - pub(crate) casm_contract_classes: CasmClassCache, + pub class_hash_to_compiled_class: HashMap, #[getset(get_mut = "pub")] pub(crate) class_hash_to_compiled_class_hash: HashMap, } @@ -49,16 +43,14 @@ impl InMemoryStateReader { address_to_class_hash: HashMap, address_to_nonce: HashMap, address_to_storage: HashMap, - class_hash_to_contract_class: HashMap, - casm_contract_classes: CasmClassCache, + class_hash_to_compiled_class: HashMap, class_hash_to_compiled_class_hash: HashMap, ) -> Self { Self { address_to_class_hash, address_to_nonce, address_to_storage, - class_hash_to_contract_class, - casm_contract_classes, + class_hash_to_compiled_class, class_hash_to_compiled_class_hash, } } @@ -79,13 +71,10 @@ impl InMemoryStateReader { &self, compiled_class_hash: &CompiledClassHash, ) -> Result { - if let Some(compiled_class) = self.casm_contract_classes.get(compiled_class_hash) { - return Ok(CompiledClass::Casm(Arc::new(compiled_class.clone()))); + match self.class_hash_to_compiled_class.get(compiled_class_hash) { + Some(compiled_class) => Ok(compiled_class.clone()), + None => Err(StateError::NoneCompiledClass(*compiled_class_hash)), } - if let Some(compiled_class) = self.class_hash_to_contract_class.get(compiled_class_hash) { - return Ok(CompiledClass::Deprecated(Arc::new(compiled_class.clone()))); - } - Err(StateError::NoneCompiledClass(*compiled_class_hash)) } } @@ -127,9 +116,10 @@ impl StateReader for InMemoryStateReader { fn get_contract_class(&self, class_hash: &ClassHash) -> Result { // Deprecated contract classes dont have a compiled_class_hash, we dont need to fetch it - if let Some(compiled_class) = self.class_hash_to_contract_class.get(class_hash) { - return Ok(CompiledClass::Deprecated(Arc::new(compiled_class.clone()))); + if let Some(compiled_class) = self.class_hash_to_compiled_class.get(class_hash) { + return Ok(compiled_class.clone()); } + let compiled_class_hash = self.get_compiled_class_hash(class_hash)?; if compiled_class_hash != *UNINITIALIZED_CLASS_HASH { let compiled_class = self.get_compiled_class(&compiled_class_hash)?; @@ -143,6 +133,8 @@ impl StateReader for InMemoryStateReader { #[cfg(test)] mod tests { use super::*; + use crate::services::api::contract_classes::deprecated_contract_class::ContractClass; + use std::sync::Arc; #[test] fn get_contract_state_test() { @@ -152,7 +144,6 @@ mod tests { HashMap::new(), HashMap::new(), HashMap::new(), - HashMap::new(), ); let contract_address = Address(37810.into()); @@ -190,7 +181,6 @@ mod tests { HashMap::new(), HashMap::new(), HashMap::new(), - HashMap::new(), ); let contract_class_key = [0; 32]; @@ -198,9 +188,10 @@ mod tests { ContractClass::from_path("starknet_programs/raw_contract_classes/class_with_abi.json") .unwrap(); - state_reader - .class_hash_to_contract_class - .insert([0; 32], contract_class.clone()); + state_reader.class_hash_to_compiled_class.insert( + [0; 32], + CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ); assert_eq!( state_reader .get_contract_class(&contract_class_key) diff --git a/src/state/mod.rs b/src/state/mod.rs index 8b6ace0cc..3920165a8 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -166,7 +166,7 @@ impl StateDiff { where T: StateReader + Clone, { - let mut cache_state = CachedState::new(state_reader, None, None); + let mut cache_state = CachedState::new(state_reader, HashMap::new()); let cache_storage_mapping = to_cache_state_storage_mapping(&self.storage_updates); cache_state.cache_mut().set_initial_values( @@ -240,7 +240,7 @@ mod test { use crate::{ state::in_memory_state_reader::InMemoryStateReader, state::{ - cached_state::{CachedState, ContractClassCache}, + cached_state::CachedState, state_api::StateReader, state_cache::{StateCache, StorageEntry}, }, @@ -263,7 +263,7 @@ mod test { .address_to_nonce .insert(contract_address, nonce); - let cached_state = CachedState::new(Arc::new(state_reader), None, None); + let cached_state = CachedState::new(Arc::new(state_reader), HashMap::new()); let diff = StateDiff::from_cached_state(cached_state).unwrap(); @@ -323,7 +323,8 @@ mod test { .address_to_nonce .insert(contract_address.clone(), nonce); - let cached_state_original = CachedState::new(Arc::new(state_reader.clone()), None, None); + let cached_state_original = + CachedState::new(Arc::new(state_reader.clone()), HashMap::new()); let diff = StateDiff::from_cached_state(cached_state_original.clone()).unwrap(); @@ -370,12 +371,8 @@ mod test { storage_writes, HashMap::new(), ); - let cached_state = CachedState::new_for_testing( - Arc::new(state_reader), - Some(ContractClassCache::new()), - cache, - None, - ); + let cached_state = + CachedState::new_for_testing(Arc::new(state_reader), cache, HashMap::new()); let mut diff = StateDiff::from_cached_state(cached_state).unwrap(); diff --git a/src/state/state_api.rs b/src/state/state_api.rs index 27ffa8599..885eee4be 100644 --- a/src/state/state_api.rs +++ b/src/state/state_api.rs @@ -1,13 +1,10 @@ use super::state_cache::StorageEntry; use crate::{ core::errors::state_errors::StateError, - services::api::contract_classes::{ - compiled_class::CompiledClass, deprecated_contract_class::ContractClass, - }, + services::api::contract_classes::compiled_class::CompiledClass, state::StateDiff, utils::{Address, ClassHash, CompiledClassHash}, }; -use cairo_lang_starknet::casm_contract_class::CasmContractClass; use cairo_vm::felt::Felt252; pub trait StateReader { @@ -30,7 +27,7 @@ pub trait State { fn set_contract_class( &mut self, class_hash: &ClassHash, - contract_class: &ContractClass, + contract_class: &CompiledClass, ) -> Result<(), StateError>; fn deploy_contract( @@ -49,12 +46,6 @@ pub trait State { class_hash: ClassHash, ) -> Result<(), StateError>; - fn set_compiled_class( - &mut self, - compiled_class_hash: &Felt252, - casm_class: CasmContractClass, - ) -> Result<(), StateError>; - fn set_compiled_class_hash( &mut self, class_hash: &Felt252, diff --git a/src/syscalls/deprecated_syscall_handler.rs b/src/syscalls/deprecated_syscall_handler.rs index 6b1653a32..31c187627 100644 --- a/src/syscalls/deprecated_syscall_handler.rs +++ b/src/syscalls/deprecated_syscall_handler.rs @@ -279,6 +279,7 @@ mod tests { use std::sync::Arc; use super::*; + use crate::services::api::contract_classes::compiled_class::CompiledClass; use crate::services::api::contract_classes::deprecated_contract_class::EntryPointType; use crate::{ add_segments, allocate_selector, any_box, @@ -782,7 +783,7 @@ mod tests { ] ); - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let mut hint_processor = SyscallHintProcessor::new( DeprecatedBLSyscallHandler::default_with(&mut state), RunResources::default(), @@ -818,7 +819,7 @@ mod tests { let hint_data = HintProcessorData::new_default(GET_CONTRACT_ADDRESS.to_string(), ids_data); // invoke syscall - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let mut hint_processor = SyscallHintProcessor::new( DeprecatedBLSyscallHandler::default_with(&mut state), RunResources::default(), @@ -860,7 +861,7 @@ mod tests { let hint_data = HintProcessorData::new_default(GET_TX_SIGNATURE.to_string(), ids_data); // invoke syscall - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let mut syscall_handler_hint_processor = SyscallHintProcessor::new( DeprecatedBLSyscallHandler::default_with(&mut state), RunResources::default(), @@ -899,7 +900,7 @@ mod tests { ); } - /// Tests the correct behavior of a storage read operation within a blockchain. + /// Tests the correct behavior of a storage read operation within a blockchain. #[test] fn test_bl_storage_read_hint_ok() { let mut vm = vm!(); @@ -928,7 +929,7 @@ mod tests { let hint_data = HintProcessorData::new_default(STORAGE_READ.to_string(), ids_data); - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let mut syscall_handler_hint_processor = SyscallHintProcessor::new( DeprecatedBLSyscallHandler::default_with(&mut state), RunResources::default(), @@ -963,7 +964,7 @@ mod tests { assert_matches!(get_big_int(&vm, relocatable!(2, 2)), Ok(response) if response == storage_value ); } - /// Tests the correct behavior of a storage write operation within a blockchain. + /// Tests the correct behavior of a storage write operation within a blockchain. #[test] fn test_bl_storage_write_hint_ok() { let mut vm = vm!(); @@ -993,7 +994,7 @@ mod tests { let hint_data = HintProcessorData::new_default(STORAGE_WRITE.to_string(), ids_data); - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let mut syscall_handler_hint_processor = SyscallHintProcessor::new( DeprecatedBLSyscallHandler::default_with(&mut state), RunResources::default(), @@ -1032,7 +1033,7 @@ mod tests { assert_eq!(write, Felt252::new(45)); } - /// Tests the correct behavior of a deploy operation within a blockchain. + /// Tests the correct behavior of a deploy operation within a blockchain. #[test] fn test_bl_deploy_ok() { let mut vm = vm!(); @@ -1067,7 +1068,7 @@ mod tests { let hint_data = HintProcessorData::new_default(DEPLOY.to_string(), ids_data); // Create SyscallHintProcessor - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let mut syscall_handler_hint_processor = SyscallHintProcessor::new( DeprecatedBLSyscallHandler::default_with(&mut state), RunResources::default(), @@ -1086,7 +1087,10 @@ mod tests { .syscall_handler .starknet_storage_state .state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); // Execute Deploy hint @@ -1123,7 +1127,7 @@ mod tests { ); } - /// Tests the correct behavior of a storage deploy and invoke operations within a blockchain. + /// Tests the correct behavior of a storage deploy and invoke operations within a blockchain. #[test] fn test_deploy_and_invoke() { /* @@ -1165,7 +1169,7 @@ mod tests { ); // Create SyscallHintProcessor - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let mut syscall_handler_hint_processor = SyscallHintProcessor::new( DeprecatedBLSyscallHandler::default_with(&mut state), RunResources::default(), @@ -1185,7 +1189,10 @@ mod tests { .syscall_handler .starknet_storage_state .state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); // Execute Deploy hint diff --git a/src/syscalls/deprecated_syscall_response.rs b/src/syscalls/deprecated_syscall_response.rs index 85e3e9cc1..bc7d3523f 100644 --- a/src/syscalls/deprecated_syscall_response.rs +++ b/src/syscalls/deprecated_syscall_response.rs @@ -309,7 +309,7 @@ impl DeprecatedWriteSyscallResponse for DeprecatedStorageReadResponse { #[cfg(test)] mod tests { - use std::sync::Arc; + use std::{collections::HashMap, sync::Arc}; use super::*; use crate::{ @@ -330,7 +330,7 @@ mod tests { #[test] fn write_get_caller_address_response() { // Initialize a VM and syscall handler - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let syscall = DeprecatedBLSyscallHandler::default_with(&mut state); let mut vm = vm!(); diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index eab540352..97dbf7cb8 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -10,7 +10,9 @@ use crate::{ execution::{ execution_entry_point::ExecutionEntryPoint, CallType, TransactionExecutionContext, }, - services::api::contract_classes::deprecated_contract_class::ContractClass, + services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::ContractClass, + }, state::{ cached_state::CachedState, in_memory_state_reader::InMemoryStateReader, @@ -58,8 +60,11 @@ fn test_erc20_cairo2() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); - contract_class_cache.insert(erc20_class_hash, test_contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); + contract_class_cache.insert( + erc20_class_hash, + CompiledClass::Casm(Arc::new(test_contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -70,7 +75,7 @@ fn test_erc20_cairo2() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let name_ = Felt252::from_bytes_be(b"some-token"); let symbol_ = Felt252::from_bytes_be(b"my-super-awesome-token"); @@ -137,7 +142,10 @@ fn test_erc20_cairo2() { serde_json::from_slice(program_data_account).unwrap(); state - .set_compiled_class(&felt_str!("1"), contract_class_account) + .set_contract_class( + &felt_str!("1").to_be_bytes(), + &CompiledClass::Casm(Arc::new(contract_class_account)), + ) .unwrap(); let contract_address_salt = @@ -176,7 +184,10 @@ fn test_erc20_cairo2() { serde_json::from_slice(program_data_account).unwrap(); state - .set_compiled_class(&felt_str!("1"), contract_class_account) + .set_contract_class( + &felt_str!("1").to_be_bytes(), + &CompiledClass::Casm(Arc::new(contract_class_account)), + ) .unwrap(); let contract_address_salt = felt_str!("123123123123123"); diff --git a/src/testing/mod.rs b/src/testing/mod.rs index 7772aae10..018082643 100644 --- a/src/testing/mod.rs +++ b/src/testing/mod.rs @@ -14,7 +14,9 @@ use crate::{ block_context::{BlockContext, StarknetChainId, StarknetOsConfig}, constants::DEFAULT_CAIRO_RESOURCE_FEE_WEIGHTS, }, - services::api::contract_classes::deprecated_contract_class::ContractClass, + services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::ContractClass, + }, state::{ cached_state::CachedState, in_memory_state_reader::InMemoryStateReader, state_cache::StorageEntry, BlockInfo, @@ -149,14 +151,14 @@ pub fn create_account_tx_test_state( state_reader.address_to_storage_mut().extend(stored); } for (class_hash, contract_class) in class_hash_to_class { - state_reader - .class_hash_to_contract_class_mut() - .insert(class_hash, contract_class); + state_reader.class_hash_to_compiled_class_mut().insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); } Arc::new(state_reader) }, - Some(HashMap::new()), - Some(HashMap::new()), + HashMap::new(), ); Ok((block_context, cached_state)) diff --git a/src/testing/state.rs b/src/testing/state.rs index 28c1ef84a..8158786ce 100644 --- a/src/testing/state.rs +++ b/src/testing/state.rs @@ -1,5 +1,6 @@ use super::{state_error::StarknetStateError, type_utils::ExecutionInfo}; use crate::execution::execution_entry_point::ExecutionResult; +use crate::services::api::contract_classes::compiled_class::CompiledClass; use crate::services::api::contract_classes::deprecated_contract_class::EntryPointType; use crate::{ definitions::{block_context::BlockContext, constants::TRANSACTION_VERSION}, @@ -40,7 +41,7 @@ impl StarknetState { let block_context = context.unwrap_or_default(); let state_reader = Arc::new(InMemoryStateReader::default()); - let state = CachedState::new(state_reader, Some(HashMap::new()), Some(HashMap::new())); + let state = CachedState::new(state_reader, HashMap::new()); let l2_to_l1_messages = HashMap::new(); let l2_to_l1_messages_log = Vec::new(); @@ -201,8 +202,10 @@ impl StarknetState { let contract_hash = deploy.contract_hash; let mut tx = Transaction::Deploy(deploy); - self.state - .set_contract_class(&contract_hash, &contract_class)?; + self.state.set_contract_class( + &contract_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + )?; let tx_execution_info = self.execute_tx(&mut tx, remaining_gas)?; Ok((contract_address, tx_execution_info)) @@ -330,6 +333,7 @@ mod tests { }, execution::{CallType, OrderedL2ToL1Message}, hash_utils::calculate_contract_address, + services::api::contract_classes::compiled_class::CompiledClass, state::state_cache::StorageEntry, utils::{calculate_sn_keccak, felt_to_hash}, }; @@ -399,11 +403,10 @@ mod tests { starknet_state .state .contract_classes - .unwrap() .get(&class_hash) .unwrap() .to_owned(), - contract_class + CompiledClass::Deprecated(Arc::new(contract_class)) ); } @@ -419,7 +422,10 @@ mod tests { // hack store account contract let hash = compute_deprecated_class_hash(&contract_class).unwrap(); let class_hash = felt_to_hash(&hash); - contract_class_cache.insert(class_hash, contract_class.clone()); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ); // store sender_address let sender_address = Address(1.into()); @@ -440,11 +446,12 @@ mod tests { state_reader .address_to_storage_mut() .insert(storage_entry.clone(), storage.clone()); - state_reader - .class_hash_to_contract_class_mut() - .insert(class_hash, contract_class.clone()); + state_reader.class_hash_to_compiled_class_mut().insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ); - let state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* -------------------------------------------- //* Create starknet state with previous data @@ -468,7 +475,10 @@ mod tests { starknet_state .state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); // -------------------------------------------- diff --git a/src/transaction/declare.rs b/src/transaction/declare.rs index abb20c0b7..ce93bc4b1 100644 --- a/src/transaction/declare.rs +++ b/src/transaction/declare.rs @@ -29,6 +29,8 @@ use num_traits::Zero; use super::fee::charge_fee; use super::{verify_version, Transaction}; +use crate::services::api::contract_classes::compiled_class::CompiledClass; +use std::sync::Arc; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// Represents an internal transaction in the StarkNet network that is a declaration of a Cairo @@ -281,7 +283,10 @@ impl Declare { self.skip_fee_transfer, )?; - state.set_contract_class(&self.class_hash, &self.contract_class)?; + state.set_contract_class( + &self.class_hash, + &CompiledClass::Deprecated(Arc::new(self.contract_class.clone())), + )?; tx_exec_info.set_fee_info(actual_fee, fee_transfer_info); @@ -332,7 +337,9 @@ mod tests { transaction_type::TransactionType, }, execution::CallType, - services::api::contract_classes::deprecated_contract_class::ContractClass, + services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::ContractClass, + }, state::cached_state::CachedState, state::in_memory_state_reader::InMemoryStateReader, utils::{felt_to_hash, Address}, @@ -353,7 +360,10 @@ mod tests { let hash = compute_deprecated_class_hash(&contract_class).unwrap(); let class_hash = hash.to_be_bytes(); - contract_class_cache.insert(class_hash, contract_class.clone()); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ); // store sender_address let sender_address = Address(1.into()); @@ -369,7 +379,7 @@ mod tests { .address_to_nonce_mut() .insert(sender_address, Felt252::new(1)); - let mut state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* --------------------------------------- //* Test declare with previous data @@ -510,7 +520,10 @@ mod tests { let hash = compute_deprecated_class_hash(&contract_class).unwrap(); let class_hash = felt_to_hash(&hash); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); // store sender_address let sender_address = Address(1.into()); @@ -526,7 +539,7 @@ mod tests { .address_to_nonce_mut() .insert(sender_address, Felt252::new(1)); - let _state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let _state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* --------------------------------------- //* Test declare with previous data @@ -573,7 +586,10 @@ mod tests { let hash = compute_deprecated_class_hash(&contract_class).unwrap(); let class_hash = felt_to_hash(&hash); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); // store sender_address let sender_address = Address(1.into()); @@ -589,7 +605,7 @@ mod tests { .address_to_nonce_mut() .insert(sender_address, Felt252::new(1)); - let _state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let _state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* --------------------------------------- //* Test declare with previous data @@ -635,7 +651,10 @@ mod tests { let hash = compute_deprecated_class_hash(&contract_class).unwrap(); let class_hash = felt_to_hash(&hash); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); // store sender_address let sender_address = Address(1.into()); @@ -651,7 +670,7 @@ mod tests { .address_to_nonce_mut() .insert(sender_address, Felt252::zero()); - let mut state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* --------------------------------------- //* Test declare with previous data @@ -711,7 +730,10 @@ mod tests { let hash = compute_deprecated_class_hash(&contract_class).unwrap(); let class_hash = felt_to_hash(&hash); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); // store sender_address let sender_address = Address(1.into()); @@ -727,7 +749,7 @@ mod tests { .address_to_nonce_mut() .insert(sender_address, Felt252::zero()); - let mut state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* --------------------------------------- //* Test declare with previous data @@ -774,7 +796,7 @@ mod tests { let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(contract_class_cache), None); + let mut state = CachedState::new(state_reader, contract_class_cache); // There are no account contracts in the state, so the transaction should fail let fib_contract_class = @@ -815,7 +837,10 @@ mod tests { let hash = compute_deprecated_class_hash(&contract_class).unwrap(); let class_hash = felt_to_hash(&hash); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); // store sender_address let sender_address = Address(1.into()); @@ -831,7 +856,7 @@ mod tests { .address_to_nonce_mut() .insert(sender_address, Felt252::zero()); - let mut state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* --------------------------------------- //* Test declare with previous data diff --git a/src/transaction/declare_v2.rs b/src/transaction/declare_v2.rs index 0b80174c5..577c0738b 100644 --- a/src/transaction/declare_v2.rs +++ b/src/transaction/declare_v2.rs @@ -5,6 +5,7 @@ use crate::definitions::constants::QUERY_VERSION_BASE; use crate::execution::execution_entry_point::ExecutionResult; use crate::services::api::contract_classes::deprecated_contract_class::EntryPointType; +use crate::services::api::contract_classes::compiled_class::CompiledClass; use crate::state::cached_state::CachedState; use crate::{ core::transaction_hash::calculate_declare_v2_transaction_hash, @@ -26,6 +27,7 @@ use cairo_lang_starknet::casm_contract_class::CasmContractClass; use cairo_lang_starknet::contract_class::ContractClass as SierraContractClass; use cairo_vm::felt::Felt252; use num_traits::Zero; +use std::sync::Arc; /// Represents a declare transaction in the starknet network. /// Declare creates a blueprint of a contract class that is used to deploy instances of the contract @@ -372,7 +374,10 @@ impl DeclareV2 { )); } state.set_compiled_class_hash(&self.sierra_class_hash, &self.compiled_class_hash)?; - state.set_compiled_class(&self.compiled_class_hash, casm_class)?; + state.set_contract_class( + &self.compiled_class_hash.to_be_bytes(), + &CompiledClass::Casm(Arc::new(casm_class)), + )?; Ok(()) } @@ -510,7 +515,7 @@ mod tests { // crate state to store casm contract class let casm_contract_class_cache = HashMap::new(); let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, None, Some(casm_contract_class_cache)); + let mut state = CachedState::new(state_reader, casm_contract_class_cache); // call compile and store assert!(internal_declare @@ -579,7 +584,7 @@ mod tests { // crate state to store casm contract class let casm_contract_class_cache = HashMap::new(); let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, None, Some(casm_contract_class_cache)); + let mut state = CachedState::new(state_reader, casm_contract_class_cache); // call compile and store assert!(internal_declare @@ -650,7 +655,7 @@ mod tests { // crate state to store casm contract class let casm_contract_class_cache = HashMap::new(); let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, None, Some(casm_contract_class_cache)); + let mut state = CachedState::new(state_reader, casm_contract_class_cache); // call compile and store assert!(internal_declare @@ -719,7 +724,7 @@ mod tests { // crate state to store casm contract class let casm_contract_class_cache = HashMap::new(); let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, None, Some(casm_contract_class_cache)); + let mut state = CachedState::new(state_reader, casm_contract_class_cache); // call compile and store assert!(internal_declare @@ -789,7 +794,7 @@ mod tests { // crate state to store casm contract class let casm_contract_class_cache = HashMap::new(); let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, None, Some(casm_contract_class_cache)); + let mut state = CachedState::new(state_reader, casm_contract_class_cache); let expected_err = format!( "Invalid compiled class, expected class hash: {}, but received: {}", diff --git a/src/transaction/deploy.rs b/src/transaction/deploy.rs index 23606ca65..b65e8559e 100644 --- a/src/transaction/deploy.rs +++ b/src/transaction/deploy.rs @@ -151,18 +151,7 @@ impl Deploy { state: &mut CachedState, block_context: &BlockContext, ) -> Result { - match self.contract_class.clone() { - CompiledClass::Casm(contract_class) => { - state.set_compiled_class( - &Felt252::from_bytes_be(&self.contract_hash), - contract_class.as_ref().clone(), - )?; - } - CompiledClass::Deprecated(contract_class) => { - state.set_contract_class(&self.contract_hash, &contract_class)?; - } - } - + state.set_contract_class(&self.contract_hash, &self.contract_class)?; state.deploy_contract(self.contract_address.clone(), self.contract_hash)?; if self.constructor_entry_points_empty(self.contract_class.clone())? { @@ -172,10 +161,10 @@ impl Deploy { self.invoke_constructor(state, block_context) } } + /// Executes the contract without constructor /// ## Parameters /// - state: A state that implements the [`State`] and [`StateReader`] traits. - pub fn handle_empty_constructor( &self, state: &mut S, @@ -328,7 +317,7 @@ mod tests { fn invoke_constructor_test() { // Instantiate CachedState let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(Default::default()), None); + let mut state = CachedState::new(state_reader, HashMap::new()); // Set contract_class let contract_class = @@ -376,7 +365,7 @@ mod tests { fn invoke_constructor_no_calldata_should_fail() { // Instantiate CachedState let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(Default::default()), None); + let mut state = CachedState::new(state_reader, HashMap::new()); let contract_class = ContractClass::from_path("starknet_programs/constructor.json").unwrap(); @@ -386,7 +375,10 @@ mod tests { let class_hash_bytes = class_hash.to_be_bytes(); state - .set_contract_class(&class_hash_bytes, &contract_class) + .set_contract_class( + &class_hash_bytes, + &CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ) .unwrap(); let internal_deploy = @@ -402,7 +394,7 @@ mod tests { fn deploy_contract_without_constructor_should_fail() { // Instantiate CachedState let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, Some(Default::default()), None); + let mut state = CachedState::new(state_reader, HashMap::new()); let contract_path = "starknet_programs/amm.json"; let contract_class = ContractClass::from_path(contract_path).unwrap(); @@ -413,7 +405,10 @@ mod tests { class_hash_bytes.copy_from_slice(&class_hash.to_bytes_be()); state - .set_contract_class(&class_hash_bytes, &contract_class) + .set_contract_class( + &class_hash_bytes, + &CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ) .unwrap(); let internal_deploy = Deploy::new( diff --git a/src/transaction/deploy_account.rs b/src/transaction/deploy_account.rs index 2833004e1..44d03785d 100644 --- a/src/transaction/deploy_account.rs +++ b/src/transaction/deploy_account.rs @@ -383,9 +383,54 @@ impl DeployAccount { } } +// ---------------------------------- +// Try from starknet api +// ---------------------------------- + +impl TryFrom for DeployAccount { + type Error = SyscallHandlerError; + + fn try_from( + value: starknet_api::transaction::DeployAccountTransaction, + ) -> Result { + let max_fee = value.max_fee.0; + let version = Felt252::from_bytes_be(value.version.0.bytes()); + let nonce = Felt252::from_bytes_be(value.nonce.0.bytes()); + let class_hash: [u8; 32] = value.class_hash.0.bytes().try_into().unwrap(); + let contract_address_salt = Felt252::from_bytes_be(value.contract_address_salt.0.bytes()); + + let signature = value + .signature + .0 + .iter() + .map(|f| Felt252::from_bytes_be(f.bytes())) + .collect(); + let constructor_calldata = value + .constructor_calldata + .0 + .as_ref() + .iter() + .map(|f| Felt252::from_bytes_be(f.bytes())) + .collect(); + + let chain_id = Felt252::zero(); + + DeployAccount::new( + class_hash, + max_fee, + version, + nonce, + constructor_calldata, + signature, + contract_address_salt, + chain_id, + ) + } +} + #[cfg(test)] mod tests { - use std::{path::PathBuf, sync::Arc}; + use std::{collections::HashMap, path::PathBuf, sync::Arc}; use super::*; use crate::{ @@ -406,11 +451,7 @@ mod tests { let class_hash = felt_to_hash(&hash); let block_context = BlockContext::default(); - let mut _state = CachedState::new( - Arc::new(InMemoryStateReader::default()), - Some(Default::default()), - None, - ); + let mut _state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let internal_deploy = DeployAccount::new( class_hash, @@ -442,11 +483,7 @@ mod tests { let class_hash = felt_to_hash(&hash); let block_context = BlockContext::default(); - let mut state = CachedState::new( - Arc::new(InMemoryStateReader::default()), - Some(Default::default()), - None, - ); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let internal_deploy = DeployAccount::new( class_hash, @@ -473,7 +510,9 @@ mod tests { .unwrap(); let class_hash = internal_deploy.class_hash(); - state.set_contract_class(class_hash, &contract).unwrap(); + state + .set_contract_class(class_hash, &CompiledClass::Deprecated(Arc::new(contract))) + .unwrap(); internal_deploy.execute(&mut state, &block_context).unwrap(); assert_matches!( internal_deploy_error @@ -494,11 +533,7 @@ mod tests { let class_hash = felt_to_hash(&hash); let block_context = BlockContext::default(); - let mut state = CachedState::new( - Arc::new(InMemoryStateReader::default()), - Some(Default::default()), - None, - ); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let internal_deploy = DeployAccount::new( class_hash, @@ -513,7 +548,9 @@ mod tests { .unwrap(); let class_hash = internal_deploy.class_hash(); - state.set_contract_class(class_hash, &contract).unwrap(); + state + .set_contract_class(class_hash, &CompiledClass::Deprecated(Arc::new(contract))) + .unwrap(); internal_deploy.execute(&mut state, &block_context).unwrap(); } } diff --git a/src/transaction/fee.rs b/src/transaction/fee.rs index 12d9ec686..818c62a54 100644 --- a/src/transaction/fee.rs +++ b/src/transaction/fee.rs @@ -196,7 +196,7 @@ mod tests { #[test] fn test_charge_fee_v0_actual_fee_exceeds_max_fee_should_return_error() { - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let mut tx_execution_context = TransactionExecutionContext::default(); let mut block_context = BlockContext::default(); block_context.starknet_os_config.gas_price = 1; @@ -222,7 +222,7 @@ mod tests { #[test] fn test_charge_fee_v1_actual_fee_exceeds_max_fee_should_return_error() { - let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), None, None); + let mut state = CachedState::new(Arc::new(InMemoryStateReader::default()), HashMap::new()); let mut tx_execution_context = TransactionExecutionContext { version: 1.into(), ..Default::default() diff --git a/src/transaction/invoke_function.rs b/src/transaction/invoke_function.rs index f4ec8a579..f532cd04b 100644 --- a/src/transaction/invoke_function.rs +++ b/src/transaction/invoke_function.rs @@ -20,7 +20,7 @@ use crate::{ use crate::services::api::contract_classes::deprecated_contract_class::EntryPointType; use cairo_vm::felt::Felt252; use getset::Getters; -use num_traits::Zero; +use num_traits::{One, Zero}; use super::{fee::charge_fee, Transaction}; @@ -397,12 +397,106 @@ pub(crate) fn preprocess_invoke_function_fields( } } +// ---------------------------------- +// Try from starknet api +// ---------------------------------- + +fn convert_invoke_v0( + value: starknet_api::transaction::InvokeTransactionV0, +) -> Result { + let contract_address = Address(Felt252::from_bytes_be( + value.contract_address.0.key().bytes(), + )); + let max_fee = value.max_fee.0; + let entry_point_selector = Felt252::from_bytes_be(value.entry_point_selector.0.bytes()); + let version = Felt252::zero(); + let nonce = None; + let chain_id = Felt252::zero(); + + let signature = value + .signature + .0 + .iter() + .map(|f| Felt252::from_bytes_be(f.bytes())) + .collect(); + let calldata = value + .calldata + .0 + .as_ref() + .iter() + .map(|f| Felt252::from_bytes_be(f.bytes())) + .collect(); + + InvokeFunction::new( + contract_address, + entry_point_selector, + max_fee, + version, + calldata, + signature, + chain_id, + nonce, + ) +} + +fn convert_invoke_v1( + value: starknet_api::transaction::InvokeTransactionV1, +) -> Result { + let contract_address = Address(Felt252::from_bytes_be(value.sender_address.0.key().bytes())); + let max_fee = value.max_fee.0; + let version = Felt252::one(); + let nonce = Felt252::from_bytes_be(value.nonce.0.bytes()); + let chain_id = Felt252::zero(); + let entry_point_selector = EXECUTE_ENTRY_POINT_SELECTOR.clone(); + + let signature = value + .signature + .0 + .iter() + .map(|f| Felt252::from_bytes_be(f.bytes())) + .collect(); + let calldata = value + .calldata + .0 + .as_ref() + .iter() + .map(|f| Felt252::from_bytes_be(f.bytes())) + .collect(); + + InvokeFunction::new( + contract_address, + entry_point_selector, + max_fee, + version, + calldata, + signature, + chain_id, + Some(nonce), + ) +} + +impl TryFrom for InvokeFunction { + type Error = TransactionError; + + fn try_from( + value: starknet_api::transaction::InvokeTransaction, + ) -> Result { + match value { + starknet_api::transaction::InvokeTransaction::V0(v0) => convert_invoke_v0(v0), + starknet_api::transaction::InvokeTransaction::V1(v1) => convert_invoke_v1(v1), + } + } +} + #[cfg(test)] mod tests { use super::*; use crate::{ - services::api::contract_classes::deprecated_contract_class::ContractClass, - state::cached_state::CachedState, state::in_memory_state_reader::InMemoryStateReader, + services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::ContractClass, + }, + state::cached_state::CachedState, + state::in_memory_state_reader::InMemoryStateReader, utils::calculate_sn_keccak, }; use cairo_lang_starknet::casm_contract_class::CasmContractClass; @@ -449,13 +543,16 @@ mod tests { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let result = internal_invoke_function @@ -518,13 +615,16 @@ mod tests { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let result = internal_invoke_function @@ -583,13 +683,16 @@ mod tests { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let expected_error = @@ -642,13 +745,16 @@ mod tests { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let result = internal_invoke_function @@ -707,13 +813,16 @@ mod tests { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let expected_error = @@ -766,13 +875,16 @@ mod tests { skip_nonce_check: false, }; - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let block_context = BlockContext::default(); @@ -823,13 +935,16 @@ mod tests { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let mut block_context = BlockContext::default(); @@ -881,13 +996,16 @@ mod tests { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); internal_invoke_function @@ -944,13 +1062,16 @@ mod tests { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let expected_error = @@ -1087,13 +1208,9 @@ mod tests { let mut casm_contract_class_cache = HashMap::new(); - casm_contract_class_cache.insert(class_hash, contract_class); + casm_contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); - let mut state = CachedState::new( - Arc::new(state_reader), - None, - Some(casm_contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), casm_contract_class_cache); let state_before_execution = state.clone(); diff --git a/src/transaction/l1_handler.rs b/src/transaction/l1_handler.rs index 9b479a340..4f84c910d 100644 --- a/src/transaction/l1_handler.rs +++ b/src/transaction/l1_handler.rs @@ -211,7 +211,9 @@ mod test { sync::Arc, }; - use crate::services::api::contract_classes::deprecated_contract_class::EntryPointType; + use crate::services::api::contract_classes::{ + compiled_class::CompiledClass, deprecated_contract_class::EntryPointType, + }; use cairo_vm::{ felt::{felt_str, Felt252}, vm::runners::cairo_runner::ExecutionResources, @@ -266,13 +268,16 @@ mod test { .address_to_nonce .insert(contract_address, nonce); - let mut state = CachedState::new(Arc::new(state_reader), None, None); + let mut state = CachedState::new(Arc::new(state_reader), HashMap::new()); // Initialize state.contract_classes state.set_contract_classes(HashMap::new()).unwrap(); state - .set_contract_class(&class_hash, &contract_class) + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let mut block_context = BlockContext::default(); diff --git a/tests/cairo_1_syscalls.rs b/tests/cairo_1_syscalls.rs index 1f32b20e6..9e7cc02a3 100644 --- a/tests/cairo_1_syscalls.rs +++ b/tests/cairo_1_syscalls.rs @@ -65,7 +65,7 @@ fn storage_write_read() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -75,7 +75,7 @@ fn storage_write_read() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let block_context = BlockContext::default(); let mut tx_execution_context = TransactionExecutionContext::new( @@ -204,7 +204,7 @@ fn library_call() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -226,7 +226,10 @@ fn library_call() { let lib_class_hash: ClassHash = [2; 32]; let lib_nonce = Felt252::zero(); - contract_class_cache.insert(lib_class_hash, lib_contract_class); + contract_class_cache.insert( + lib_class_hash, + CompiledClass::Casm(Arc::new(lib_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(lib_address.clone(), lib_class_hash); @@ -235,7 +238,7 @@ fn library_call() { .insert(lib_address, lib_nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [25.into(), Felt252::from_bytes_be(&lib_class_hash)].to_vec(); @@ -361,7 +364,7 @@ fn call_contract_storage_write_read() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -392,7 +395,10 @@ fn call_contract_storage_write_read() { let simple_wallet_class_hash: ClassHash = [2; 32]; let simple_wallet_nonce = Felt252::zero(); - contract_class_cache.insert(simple_wallet_class_hash, simple_wallet_contract_class); + contract_class_cache.insert( + simple_wallet_class_hash, + CompiledClass::Casm(Arc::new(simple_wallet_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(simple_wallet_address.clone(), simple_wallet_class_hash); @@ -401,7 +407,7 @@ fn call_contract_storage_write_read() { .insert(simple_wallet_address.clone(), simple_wallet_nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let block_context = BlockContext::default(); let mut tx_execution_context = TransactionExecutionContext::new( @@ -547,7 +553,7 @@ fn emit_event() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -557,7 +563,7 @@ fn emit_event() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [].to_vec(); @@ -659,8 +665,11 @@ fn deploy_cairo1_from_cairo1() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); - contract_class_cache.insert(test_class_hash, test_contract_class.clone()); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); + contract_class_cache.insert( + test_class_hash, + CompiledClass::Casm(Arc::new(test_contract_class.clone())), + ); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -671,7 +680,7 @@ fn deploy_cairo1_from_cairo1() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // arguments of deploy contract let calldata: Vec<_> = [test_felt_hash, salt].to_vec(); @@ -750,15 +759,17 @@ fn deploy_cairo0_from_cairo1_without_constructor() { let entrypoint_selector = &entrypoints.external.get(0).unwrap().selector; // Create state reader with class hash data - let mut casm_contract_class_cache = HashMap::new(); let mut contract_class_cache = HashMap::new(); let address = Address(1111.into()); let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - casm_contract_class_cache.insert(class_hash, contract_class); - contract_class_cache.insert(test_class_hash, test_contract_class.clone()); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); + contract_class_cache.insert( + test_class_hash, + CompiledClass::Deprecated(Arc::new(test_contract_class.clone())), + ); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -769,11 +780,7 @@ fn deploy_cairo0_from_cairo1_without_constructor() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(contract_class_cache), - Some(casm_contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // arguments of deploy contract let calldata: Vec<_> = [test_felt_hash, salt].to_vec(); @@ -850,7 +857,6 @@ fn deploy_cairo0_from_cairo1_with_constructor() { let entrypoint_selector = &entrypoints.external.get(0).unwrap().selector; // Create state reader with class hash data - let mut casm_contract_class_cache = HashMap::new(); let mut contract_class_cache = HashMap::new(); let address = Address(1111.into()); @@ -858,8 +864,11 @@ fn deploy_cairo0_from_cairo1_with_constructor() { let nonce = Felt252::zero(); // simulate contract declare - casm_contract_class_cache.insert(class_hash, contract_class); - contract_class_cache.insert(test_class_hash, test_contract_class.clone()); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); + contract_class_cache.insert( + test_class_hash, + CompiledClass::Deprecated(Arc::new(test_contract_class.clone())), + ); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -870,11 +879,7 @@ fn deploy_cairo0_from_cairo1_with_constructor() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(contract_class_cache), - Some(casm_contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // arguments of deploy contract let calldata: Vec<_> = [test_felt_hash, salt, address.0.clone(), Felt252::zero()].to_vec(); @@ -953,15 +958,17 @@ fn deploy_cairo0_and_invoke() { let entrypoint_selector = &entrypoints.external.get(0).unwrap().selector; // Create state reader with class hash data - let mut casm_contract_class_cache = HashMap::new(); let mut contract_class_cache = HashMap::new(); let address = Address(1111.into()); let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - casm_contract_class_cache.insert(class_hash, contract_class); - contract_class_cache.insert(test_class_hash, test_contract_class.clone()); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); + contract_class_cache.insert( + test_class_hash, + CompiledClass::Deprecated(Arc::new(test_contract_class.clone())), + ); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -972,11 +979,7 @@ fn deploy_cairo0_and_invoke() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state: CachedState<_> = CachedState::new( - Arc::new(state_reader), - Some(contract_class_cache), - Some(casm_contract_class_cache), - ); + let mut state: CachedState<_> = CachedState::new(Arc::new(state_reader), contract_class_cache); // arguments of deploy contract let calldata: Vec<_> = [test_felt_hash, salt].to_vec(); @@ -1085,7 +1088,7 @@ fn test_send_message_to_l1_syscall() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -1096,7 +1099,7 @@ fn test_send_message_to_l1_syscall() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // RUN SEND_MSG // Create an execution entry point @@ -1179,7 +1182,7 @@ fn test_get_execution_info() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -1189,7 +1192,7 @@ fn test_get_execution_info() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let block_context = BlockContext::default(); let mut tx_execution_context = TransactionExecutionContext::new( @@ -1274,7 +1277,10 @@ fn replace_class_internal() { let class_hash_a: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash_a, contract_class_a); + contract_class_cache.insert( + class_hash_a, + CompiledClass::Casm(Arc::new(contract_class_a)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -1292,10 +1298,13 @@ fn replace_class_internal() { let class_hash_b: ClassHash = [2; 32]; - contract_class_cache.insert(class_hash_b, contract_class_b.clone()); + contract_class_cache.insert( + class_hash_b, + CompiledClass::Casm(Arc::new(contract_class_b.clone())), + ); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Run upgrade entrypoint and check that the storage was updated with the new contract class // Create an execution entry point @@ -1370,7 +1379,10 @@ fn replace_class_contract_call() { let class_hash_a: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash_a, contract_class_a); + contract_class_cache.insert( + class_hash_a, + CompiledClass::Casm(Arc::new(contract_class_a)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -1391,7 +1403,10 @@ fn replace_class_contract_call() { let class_hash_b: ClassHash = [2; 32]; - contract_class_cache.insert(class_hash_b, contract_class_b); + contract_class_cache.insert( + class_hash_b, + CompiledClass::Casm(Arc::new(contract_class_b)), + ); // SET GET_NUMBER_WRAPPER @@ -1408,7 +1423,10 @@ fn replace_class_contract_call() { let wrapper_address = Address(Felt252::from(2)); let wrapper_class_hash: ClassHash = [3; 32]; - contract_class_cache.insert(wrapper_class_hash, wrapper_contract_class); + contract_class_cache.insert( + wrapper_class_hash, + CompiledClass::Casm(Arc::new(wrapper_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(wrapper_address.clone(), wrapper_class_hash); @@ -1417,7 +1435,7 @@ fn replace_class_contract_call() { .insert(wrapper_address, nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // INITIALIZE STARKNET CONFIG let block_context = BlockContext::default(); @@ -1537,7 +1555,10 @@ fn replace_class_contract_call_same_transaction() { let class_hash_a: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash_a, contract_class_a); + contract_class_cache.insert( + class_hash_a, + CompiledClass::Casm(Arc::new(contract_class_a)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -1558,7 +1579,10 @@ fn replace_class_contract_call_same_transaction() { let class_hash_b: ClassHash = [2; 32]; - contract_class_cache.insert(class_hash_b, contract_class_b); + contract_class_cache.insert( + class_hash_b, + CompiledClass::Casm(Arc::new(contract_class_b)), + ); // SET GET_NUMBER_WRAPPER @@ -1574,7 +1598,10 @@ fn replace_class_contract_call_same_transaction() { let wrapper_address = Address(Felt252::from(2)); let wrapper_class_hash: ClassHash = [3; 32]; - contract_class_cache.insert(wrapper_class_hash, wrapper_contract_class); + contract_class_cache.insert( + wrapper_class_hash, + CompiledClass::Casm(Arc::new(wrapper_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(wrapper_address.clone(), wrapper_class_hash); @@ -1583,7 +1610,7 @@ fn replace_class_contract_call_same_transaction() { .insert(wrapper_address, nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // INITIALIZE STARKNET CONFIG let block_context = BlockContext::default(); @@ -1645,14 +1672,16 @@ fn call_contract_upgrade_cairo_0_to_cairo_1_same_transaction() { let contract_class_c = ContractClass::from_path("starknet_programs/get_number_c.json").unwrap(); // Create state reader with class hash data - let mut casm_contract_class_cache = HashMap::new(); - let mut deprecated_contract_class_cache = HashMap::new(); + let mut contract_class_cache = HashMap::new(); let address = Address(Felt252::one()); let class_hash_c: ClassHash = Felt252::one().to_be_bytes(); let nonce = Felt252::zero(); - deprecated_contract_class_cache.insert(class_hash_c, contract_class_c); + contract_class_cache.insert( + class_hash_c, + CompiledClass::Deprecated(Arc::new(contract_class_c)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -1673,7 +1702,10 @@ fn call_contract_upgrade_cairo_0_to_cairo_1_same_transaction() { let class_hash_b: ClassHash = Felt252::from(2).to_be_bytes(); - casm_contract_class_cache.insert(class_hash_b, contract_class_b); + contract_class_cache.insert( + class_hash_b, + CompiledClass::Casm(Arc::new(contract_class_b)), + ); // SET GET_NUMBER_WRAPPER @@ -1689,7 +1721,10 @@ fn call_contract_upgrade_cairo_0_to_cairo_1_same_transaction() { let wrapper_address = Address(Felt252::from(2)); let wrapper_class_hash: ClassHash = [3; 32]; - casm_contract_class_cache.insert(wrapper_class_hash, wrapper_contract_class); + contract_class_cache.insert( + wrapper_class_hash, + CompiledClass::Casm(Arc::new(wrapper_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(wrapper_address.clone(), wrapper_class_hash); @@ -1698,11 +1733,7 @@ fn call_contract_upgrade_cairo_0_to_cairo_1_same_transaction() { .insert(wrapper_address, nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(deprecated_contract_class_cache), - Some(casm_contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // INITIALIZE STARKNET CONFIG let block_context = BlockContext::default(); @@ -1762,14 +1793,16 @@ fn call_contract_downgrade_cairo_1_to_cairo_0_same_transaction() { let contract_class_c = ContractClass::from_path("starknet_programs/get_number_c.json").unwrap(); // Create state reader with class hash data - let mut casm_contract_class_cache = HashMap::new(); - let mut deprecated_contract_class_cache = HashMap::new(); + let mut contract_class_cache = HashMap::new(); let address = Address(Felt252::one()); let class_hash_c: ClassHash = Felt252::one().to_be_bytes(); let nonce = Felt252::zero(); - deprecated_contract_class_cache.insert(class_hash_c, contract_class_c); + contract_class_cache.insert( + class_hash_c, + CompiledClass::Deprecated(Arc::new(contract_class_c)), + ); // SET GET_NUMBER_B @@ -1783,7 +1816,10 @@ fn call_contract_downgrade_cairo_1_to_cairo_0_same_transaction() { let class_hash_b: ClassHash = Felt252::from(2).to_be_bytes(); - casm_contract_class_cache.insert(class_hash_b, contract_class_b); + contract_class_cache.insert( + class_hash_b, + CompiledClass::Casm(Arc::new(contract_class_b)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -1806,7 +1842,10 @@ fn call_contract_downgrade_cairo_1_to_cairo_0_same_transaction() { let wrapper_address = Address(Felt252::from(2)); let wrapper_class_hash: ClassHash = [3; 32]; - casm_contract_class_cache.insert(wrapper_class_hash, wrapper_contract_class); + contract_class_cache.insert( + wrapper_class_hash, + CompiledClass::Casm(Arc::new(wrapper_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(wrapper_address.clone(), wrapper_class_hash); @@ -1815,11 +1854,7 @@ fn call_contract_downgrade_cairo_1_to_cairo_0_same_transaction() { .insert(wrapper_address, nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(deprecated_contract_class_cache), - Some(casm_contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // INITIALIZE STARKNET CONFIG let block_context = BlockContext::default(); @@ -1879,14 +1914,16 @@ fn call_contract_replace_class_cairo_0() { let contract_class_c = ContractClass::from_path("starknet_programs/get_number_c.json").unwrap(); // Create state reader with class hash data - let mut casm_contract_class_cache = HashMap::new(); - let mut deprecated_contract_class_cache = HashMap::new(); + let mut contract_class_cache = HashMap::new(); let address = Address(Felt252::one()); let class_hash_c: ClassHash = Felt252::one().to_be_bytes(); let nonce = Felt252::zero(); - deprecated_contract_class_cache.insert(class_hash_c, contract_class_c); + contract_class_cache.insert( + class_hash_c, + CompiledClass::Deprecated(Arc::new(contract_class_c)), + ); // SET GET_NUMBER_B @@ -1896,7 +1933,10 @@ fn call_contract_replace_class_cairo_0() { let class_hash_d: ClassHash = Felt252::from(2).to_be_bytes(); - deprecated_contract_class_cache.insert(class_hash_d, contract_class_d); + contract_class_cache.insert( + class_hash_d, + CompiledClass::Deprecated(Arc::new(contract_class_d)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -1919,7 +1959,10 @@ fn call_contract_replace_class_cairo_0() { let wrapper_address = Address(Felt252::from(2)); let wrapper_class_hash: ClassHash = [3; 32]; - casm_contract_class_cache.insert(wrapper_class_hash, wrapper_contract_class); + contract_class_cache.insert( + wrapper_class_hash, + CompiledClass::Casm(Arc::new(wrapper_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(wrapper_address.clone(), wrapper_class_hash); @@ -1928,11 +1971,7 @@ fn call_contract_replace_class_cairo_0() { .insert(wrapper_address, nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(deprecated_contract_class_cache), - Some(casm_contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // INITIALIZE STARKNET CONFIG let block_context = BlockContext::default(); @@ -1998,7 +2037,7 @@ fn test_out_of_gas_failure() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2008,7 +2047,7 @@ fn test_out_of_gas_failure() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [].to_vec(); @@ -2075,7 +2114,7 @@ fn deploy_syscall_failure_uninitialized_class_hash() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2085,7 +2124,7 @@ fn deploy_syscall_failure_uninitialized_class_hash() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [Felt252::zero()].to_vec(); @@ -2151,7 +2190,7 @@ fn deploy_syscall_failure_in_constructor() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2167,10 +2206,13 @@ fn deploy_syscall_failure_in_constructor() { let f_c_program_data = include_bytes!("../starknet_programs/cairo1/failing_constructor.casm"); let f_c_contract_class: CasmContractClass = serde_json::from_slice(f_c_program_data).unwrap(); let f_c_class_hash = Felt252::one(); - contract_class_cache.insert(f_c_class_hash.to_be_bytes(), f_c_contract_class); + contract_class_cache.insert( + f_c_class_hash.to_be_bytes(), + CompiledClass::Casm(Arc::new(f_c_contract_class)), + ); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [f_c_class_hash].to_vec(); @@ -2238,7 +2280,7 @@ fn storage_read_no_value() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2248,7 +2290,7 @@ fn storage_read_no_value() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let block_context = BlockContext::default(); let mut tx_execution_context = TransactionExecutionContext::new( @@ -2309,7 +2351,7 @@ fn storage_read_unavailable_address_domain() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2319,7 +2361,7 @@ fn storage_read_unavailable_address_domain() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let block_context = BlockContext::default(); let mut tx_execution_context = TransactionExecutionContext::new( @@ -2383,7 +2425,7 @@ fn storage_write_unavailable_address_domain() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2393,7 +2435,7 @@ fn storage_write_unavailable_address_domain() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let block_context = BlockContext::default(); let mut tx_execution_context = TransactionExecutionContext::new( @@ -2455,7 +2497,7 @@ fn library_call_failure() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2476,7 +2518,10 @@ fn library_call_failure() { let lib_class_hash: ClassHash = [2; 32]; let lib_nonce = Felt252::zero(); - contract_class_cache.insert(lib_class_hash, lib_contract_class); + contract_class_cache.insert( + lib_class_hash, + CompiledClass::Casm(Arc::new(lib_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(lib_address.clone(), lib_class_hash); @@ -2485,7 +2530,7 @@ fn library_call_failure() { .insert(lib_address, lib_nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [25.into(), Felt252::from_bytes_be(&lib_class_hash)].to_vec(); @@ -2564,7 +2609,7 @@ fn send_messages_to_l1_different_contract_calls() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2585,7 +2630,10 @@ fn send_messages_to_l1_different_contract_calls() { let send_msg_class_hash: ClassHash = [2; 32]; let send_msg_nonce = Felt252::zero(); - contract_class_cache.insert(send_msg_class_hash, send_msg_contract_class); + contract_class_cache.insert( + send_msg_class_hash, + CompiledClass::Casm(Arc::new(send_msg_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(send_msg_address.clone(), send_msg_class_hash); @@ -2594,7 +2642,7 @@ fn send_messages_to_l1_different_contract_calls() { .insert(send_msg_address, send_msg_nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [25.into(), 50.into(), 75.into()].to_vec(); @@ -2679,13 +2727,12 @@ fn send_messages_to_l1_different_contract_calls_cairo1_to_cairo0() { // Create state reader with class hash data let mut contract_class_cache = HashMap::new(); - let mut deprecated_contract_class_cache = HashMap::new(); let address = Address(1111.into()); let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2703,7 +2750,10 @@ fn send_messages_to_l1_different_contract_calls_cairo1_to_cairo0() { let send_msg_class_hash: ClassHash = [2; 32]; let send_msg_nonce = Felt252::zero(); - deprecated_contract_class_cache.insert(send_msg_class_hash, send_msg_contract_class); + contract_class_cache.insert( + send_msg_class_hash, + CompiledClass::Deprecated(Arc::new(send_msg_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(send_msg_address.clone(), send_msg_class_hash); @@ -2712,11 +2762,7 @@ fn send_messages_to_l1_different_contract_calls_cairo1_to_cairo0() { .insert(send_msg_address, send_msg_nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(deprecated_contract_class_cache), - Some(contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [25.into(), 50.into(), 75.into()].to_vec(); @@ -2796,13 +2842,15 @@ fn send_messages_to_l1_different_contract_calls_cairo0_to_cairo1() { // Create state reader with class hash data let mut contract_class_cache = HashMap::new(); - let mut deprecated_contract_class_cache = HashMap::new(); let address = Address(1111.into()); let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - deprecated_contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2823,7 +2871,10 @@ fn send_messages_to_l1_different_contract_calls_cairo0_to_cairo1() { let send_msg_class_hash: ClassHash = [2; 32]; let send_msg_nonce = Felt252::zero(); - contract_class_cache.insert(send_msg_class_hash, send_msg_contract_class); + contract_class_cache.insert( + send_msg_class_hash, + CompiledClass::Casm(Arc::new(send_msg_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(send_msg_address.clone(), send_msg_class_hash); @@ -2832,11 +2883,7 @@ fn send_messages_to_l1_different_contract_calls_cairo0_to_cairo1() { .insert(send_msg_address, send_msg_nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(deprecated_contract_class_cache), - Some(contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [25.into(), 50.into(), 75.into()].to_vec(); @@ -2920,7 +2967,7 @@ fn keccak_syscall() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -2930,7 +2977,7 @@ fn keccak_syscall() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); let block_context = BlockContext::default(); let mut tx_execution_context = TransactionExecutionContext::new( diff --git a/tests/complex_contracts/amm_contracts/amm.rs b/tests/complex_contracts/amm_contracts/amm.rs index bbab48eb9..6f987ed64 100644 --- a/tests/complex_contracts/amm_contracts/amm.rs +++ b/tests/complex_contracts/amm_contracts/amm.rs @@ -54,11 +54,7 @@ fn swap(calldata: &[Felt252], call_config: &mut CallConfig) -> Result { pub state: &'a mut CachedState, @@ -156,7 +161,10 @@ pub fn deploy( )?, }; let class_hash = internal_deploy.class_hash(); - state.set_contract_class(&class_hash, &contract_class)?; + state.set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + )?; let tx_execution_info = internal_deploy.apply(state, block_context)?; diff --git a/tests/delegate_call.rs b/tests/delegate_call.rs index f3705c533..f9d2c7b57 100644 --- a/tests/delegate_call.rs +++ b/tests/delegate_call.rs @@ -2,6 +2,7 @@ use cairo_vm::felt::Felt252; use num_traits::{One, Zero}; +use starknet_in_rust::services::api::contract_classes::compiled_class::CompiledClass; use starknet_in_rust::EntryPointType; use starknet_in_rust::{ definitions::{block_context::BlockContext, constants::TRANSACTION_VERSION}, @@ -33,7 +34,10 @@ fn delegate_call() { let address = Address(Felt252::one()); // const CONTRACT_ADDRESS = 1; let class_hash = [2; 32]; - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -64,7 +68,10 @@ fn delegate_call() { let address = Address(1111.into()); let class_hash = [1; 32]; - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(address.clone(), class_hash); @@ -76,7 +83,7 @@ fn delegate_call() { //* Create state with previous data //* --------------------------------------- - let mut state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* ------------------------------------ //* Create execution entry point diff --git a/tests/delegate_l1_handler.rs b/tests/delegate_l1_handler.rs index a62b46181..fdc91ee81 100644 --- a/tests/delegate_l1_handler.rs +++ b/tests/delegate_l1_handler.rs @@ -2,6 +2,7 @@ use cairo_vm::felt::{felt_str, Felt252}; use num_traits::{One, Zero}; +use starknet_in_rust::services::api::contract_classes::compiled_class::CompiledClass; use starknet_in_rust::EntryPointType; use starknet_in_rust::{ definitions::{block_context::BlockContext, constants::TRANSACTION_VERSION}, @@ -34,7 +35,10 @@ fn delegate_l1_handler() { let address = Address(Felt252::one()); // const CONTRACT_ADDRESS = 1; let class_hash = [2; 32]; - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -59,7 +63,10 @@ fn delegate_l1_handler() { let address = Address(1111.into()); let class_hash = [1; 32]; - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(address.clone(), class_hash); @@ -71,7 +78,7 @@ fn delegate_l1_handler() { //* Create state with previous data //* --------------------------------------- - let mut state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* ------------------------------------ //* Create execution entry point diff --git a/tests/deploy_account.rs b/tests/deploy_account.rs index f0d5636a8..6da3256af 100644 --- a/tests/deploy_account.rs +++ b/tests/deploy_account.rs @@ -4,7 +4,6 @@ use cairo_vm::{ }; use lazy_static::lazy_static; use num_traits::Zero; -use starknet_in_rust::EntryPointType; use starknet_in_rust::{ core::contract_address::compute_deprecated_class_hash, definitions::{ @@ -20,7 +19,13 @@ use starknet_in_rust::{ utils::Address, CasmContractClass, }; -use std::{collections::HashSet, sync::Arc}; +use starknet_in_rust::{ + services::api::contract_classes::compiled_class::CompiledClass, EntryPointType, +}; +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, +}; lazy_static! { static ref TEST_ACCOUNT_COMPILED_CONTRACT_CLASS_HASH: Felt252 = felt_str!("1"); @@ -29,7 +34,7 @@ lazy_static! { #[test] fn internal_deploy_account() { let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, None, None); + let mut state = CachedState::new(state_reader, HashMap::new()); state.set_contract_classes(Default::default()).unwrap(); @@ -40,7 +45,10 @@ fn internal_deploy_account() { let class_hash_bytes = class_hash.to_be_bytes(); state - .set_contract_class(&class_hash_bytes, &contract_class) + .set_contract_class( + &class_hash_bytes, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) .unwrap(); let contract_address_salt = @@ -109,7 +117,7 @@ fn internal_deploy_account() { #[test] fn internal_deploy_account_cairo1() { let state_reader = Arc::new(InMemoryStateReader::default()); - let mut state = CachedState::new(state_reader, None, Some(Default::default())); + let mut state = CachedState::new(state_reader, HashMap::default()); state.set_contract_classes(Default::default()).unwrap(); @@ -120,9 +128,9 @@ fn internal_deploy_account_cairo1() { let contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); state - .set_compiled_class( - &TEST_ACCOUNT_COMPILED_CONTRACT_CLASS_HASH.clone(), - contract_class, + .set_contract_class( + &TEST_ACCOUNT_COMPILED_CONTRACT_CLASS_HASH.to_be_bytes(), + &CompiledClass::Casm(Arc::new(contract_class)), ) .unwrap(); diff --git a/tests/fibonacci.rs b/tests/fibonacci.rs index 17f44906c..827c7935d 100644 --- a/tests/fibonacci.rs +++ b/tests/fibonacci.rs @@ -6,6 +6,7 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use cairo_vm::{felt::Felt252, vm::runners::builtin_runner::RANGE_CHECK_BUILTIN_NAME}; use num_traits::Zero; use starknet_in_rust::definitions::block_context::BlockContext; +use starknet_in_rust::services::api::contract_classes::compiled_class::CompiledClass; use starknet_in_rust::EntryPointType; use starknet_in_rust::{ definitions::constants::TRANSACTION_VERSION, @@ -50,7 +51,10 @@ fn integration_test() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -63,7 +67,7 @@ fn integration_test() { //* Create state with previous data //* --------------------------------------- - let mut state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* ------------------------------------ //* Create execution entry point @@ -151,7 +155,7 @@ fn integration_test_cairo1() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -161,7 +165,7 @@ fn integration_test_cairo1() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new(Arc::new(state_reader), None, Some(contract_class_cache)); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [0.into(), 1.into(), 12.into()].to_vec(); diff --git a/tests/increase_balance.rs b/tests/increase_balance.rs index 7aec0336b..141583e7b 100644 --- a/tests/increase_balance.rs +++ b/tests/increase_balance.rs @@ -3,6 +3,7 @@ use cairo_vm::felt::Felt252; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use num_traits::Zero; +use starknet_in_rust::services::api::contract_classes::compiled_class::CompiledClass; use starknet_in_rust::EntryPointType; use starknet_in_rust::{ definitions::{block_context::BlockContext, constants::TRANSACTION_VERSION}, @@ -53,7 +54,10 @@ fn hello_starknet_increase_balance() { let storage_entry: StorageEntry = (address.clone(), [1; 32]); let storage = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -69,7 +73,7 @@ fn hello_starknet_increase_balance() { //* Create state with previous data //* --------------------------------------- - let mut state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* ------------------------------------ //* Create execution entry point diff --git a/tests/internal_calls.rs b/tests/internal_calls.rs index 62ed69d71..97de33e63 100644 --- a/tests/internal_calls.rs +++ b/tests/internal_calls.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use cairo_vm::felt::Felt252; use num_traits::Zero; +use starknet_in_rust::services::api::contract_classes::compiled_class::CompiledClass; use starknet_in_rust::EntryPointType; use starknet_in_rust::{ definitions::{block_context::BlockContext, constants::TRANSACTION_VERSION}, @@ -15,6 +16,7 @@ use starknet_in_rust::{ state::{in_memory_state_reader::InMemoryStateReader, ExecutionResourcesManager}, utils::{calculate_sn_keccak, Address, ClassHash}, }; +use std::collections::HashMap; #[test] fn test_internal_calls() { @@ -47,8 +49,10 @@ fn test_internal_calls() { let mut state = CachedState::new( Arc::new(state_reader), - Some([([0x01; 32], contract_class)].into_iter().collect()), - None, + HashMap::from([( + [0x01; 32], + CompiledClass::Deprecated(Arc::new(contract_class)), + )]), ); let entry_point_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"a")); diff --git a/tests/internals.rs b/tests/internals.rs index 26595c01b..94f845e36 100644 --- a/tests/internals.rs +++ b/tests/internals.rs @@ -41,7 +41,7 @@ use starknet_in_rust::{ execution::{CallInfo, CallType, OrderedEvent, TransactionExecutionInfo}, state::in_memory_state_reader::InMemoryStateReader, state::{ - cached_state::{CachedState, ContractClassCache}, + cached_state::CachedState, state_api::{State, StateReader}, state_cache::StateCache, state_cache::StorageEntry, @@ -188,14 +188,14 @@ fn create_account_tx_test_state( state_reader.address_to_storage_mut().extend(stored); } for (class_hash, contract_class) in class_hash_to_class { - state_reader - .class_hash_to_contract_class_mut() - .insert(class_hash, contract_class); + state_reader.class_hash_to_compiled_class_mut().insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); } Arc::new(state_reader) }, - Some(HashMap::new()), - Some(HashMap::new()), + HashMap::new(), ); Ok((block_context, cached_state)) @@ -204,38 +204,37 @@ fn create_account_tx_test_state( fn expected_state_before_tx() -> CachedState { let in_memory_state_reader = initial_in_memory_state_reader(); - let state_cache = ContractClassCache::new(); - - CachedState::new( - Arc::new(in_memory_state_reader), - Some(state_cache), - Some(HashMap::new()), - ) + CachedState::new(Arc::new(in_memory_state_reader), HashMap::new()) } fn expected_state_after_tx(fee: u128) -> CachedState { let in_memory_state_reader = initial_in_memory_state_reader(); - let contract_classes_cache = ContractClassCache::from([ + let contract_classes_cache = HashMap::from([ ( felt_to_hash(&TEST_CLASS_HASH.clone()), - ContractClass::from_path(TEST_CONTRACT_PATH).unwrap(), + CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(TEST_CONTRACT_PATH).unwrap(), + )), ), ( felt_to_hash(&TEST_ACCOUNT_CONTRACT_CLASS_HASH.clone()), - ContractClass::from_path(ACCOUNT_CONTRACT_PATH).unwrap(), + CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(ACCOUNT_CONTRACT_PATH).unwrap(), + )), ), ( felt_to_hash(&TEST_ERC20_CONTRACT_CLASS_HASH.clone()), - ContractClass::from_path(ERC20_CONTRACT_PATH).unwrap(), + CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(ERC20_CONTRACT_PATH).unwrap(), + )), ), ]); CachedState::new_for_testing( Arc::new(in_memory_state_reader), - Some(contract_classes_cache), state_cache_after_invoke_tx(fee), - Some(HashMap::new()), + contract_classes_cache, ) } @@ -372,19 +371,24 @@ fn initial_in_memory_state_reader() -> InMemoryStateReader { HashMap::from([ ( felt_to_hash(&TEST_ERC20_CONTRACT_CLASS_HASH), - ContractClass::from_path(ERC20_CONTRACT_PATH).unwrap(), + CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(ERC20_CONTRACT_PATH).unwrap(), + )), ), ( felt_to_hash(&TEST_ACCOUNT_CONTRACT_CLASS_HASH), - ContractClass::from_path(ACCOUNT_CONTRACT_PATH).unwrap(), + CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(ACCOUNT_CONTRACT_PATH).unwrap(), + )), ), ( felt_to_hash(&TEST_CLASS_HASH), - ContractClass::from_path(TEST_CONTRACT_PATH).unwrap(), + CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(TEST_CONTRACT_PATH).unwrap(), + )), ), ]), HashMap::new(), - HashMap::new(), ) } @@ -524,10 +528,6 @@ fn test_create_account_tx_test_state() { &state.contract_classes(), &expected_initial_state.contract_classes() ); - assert_eq!( - &state.casm_contract_classes(), - &expected_initial_state.casm_contract_classes() - ); assert_eq!( &state.state_reader.address_to_class_hash, &expected_initial_state.state_reader.address_to_class_hash @@ -542,21 +542,21 @@ fn test_create_account_tx_test_state() { ); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17 @@ -874,10 +874,6 @@ fn test_declare_tx() { &state.contract_classes(), &expected_initial_state.contract_classes() ); - assert_eq!( - &state.casm_contract_classes(), - &expected_initial_state.casm_contract_classes() - ); assert_eq!( &state.state_reader.address_to_class_hash, &expected_initial_state.state_reader.address_to_class_hash @@ -892,21 +888,21 @@ fn test_declare_tx() { ); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17 @@ -962,10 +958,6 @@ fn test_declarev2_tx() { &state.contract_classes(), &expected_initial_state.contract_classes() ); - assert_eq!( - &state.casm_contract_classes(), - &expected_initial_state.casm_contract_classes() - ); assert_eq!( &state.state_reader.address_to_class_hash, &expected_initial_state.state_reader.address_to_class_hash @@ -980,21 +972,21 @@ fn test_declarev2_tx() { ); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17 @@ -1308,10 +1300,6 @@ fn test_invoke_tx_state() { &state.contract_classes(), &expected_initial_state.contract_classes() ); - assert_eq!( - &state.casm_contract_classes(), - &expected_initial_state.casm_contract_classes() - ); assert_eq!( &state.state_reader.address_to_class_hash, &expected_initial_state.state_reader.address_to_class_hash @@ -1326,21 +1314,21 @@ fn test_invoke_tx_state() { ); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17 @@ -1362,10 +1350,6 @@ fn test_invoke_tx_state() { let expected_final_state = expected_state_after_tx(result.actual_fee); assert_eq!(&state.cache(), &expected_final_state.cache()); - assert_eq!( - &state.casm_contract_classes(), - &expected_final_state.casm_contract_classes() - ); assert_eq!( &state.state_reader.address_to_class_hash, &expected_final_state.state_reader.address_to_class_hash @@ -1389,10 +1373,6 @@ fn test_invoke_with_declarev2_tx() { &state.contract_classes(), &expected_initial_state.contract_classes() ); - assert_eq!( - &state.casm_contract_classes(), - &expected_initial_state.casm_contract_classes() - ); assert_eq!( &state.state_reader.address_to_class_hash, &expected_initial_state.state_reader.address_to_class_hash @@ -1407,21 +1387,21 @@ fn test_invoke_with_declarev2_tx() { ); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16 ])); assert!(&state .state_reader - .class_hash_to_contract_class + .class_hash_to_compiled_class .contains_key(&[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17 @@ -1488,19 +1468,11 @@ fn test_deploy_account() { assert_eq!(&state.cache(), &state_before.cache()); assert_eq!(&state.contract_classes(), &state_before.contract_classes()); - assert_eq!( - &state.casm_contract_classes(), - &state_before.casm_contract_classes() - ); let tx_info = deploy_account_tx .execute(&mut state, &block_context) .unwrap(); - assert_eq!( - state.casm_contract_classes(), - state_after.casm_contract_classes() - ); assert_eq!(state.cache(), state_after.cache()); let expected_validate_call_info = expected_validate_call_info( @@ -1599,22 +1571,26 @@ fn expected_deploy_account_states() -> ( HashMap::from([ ( felt_to_hash(&0x110.into()), - ContractClass::from_path(TEST_CONTRACT_PATH).unwrap(), + CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(TEST_CONTRACT_PATH).unwrap(), + )), ), ( felt_to_hash(&0x111.into()), - ContractClass::from_path(ACCOUNT_CONTRACT_PATH).unwrap(), + CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(ACCOUNT_CONTRACT_PATH).unwrap(), + )), ), ( felt_to_hash(&0x1010.into()), - ContractClass::from_path(ERC20_CONTRACT_PATH).unwrap(), + CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(ERC20_CONTRACT_PATH).unwrap(), + )), ), ]), HashMap::new(), - HashMap::new(), )), - Some(ContractClassCache::new()), - Some(HashMap::new()), + HashMap::new(), ); state_before.set_storage_at( &( @@ -1712,13 +1688,17 @@ fn expected_deploy_account_states() -> ( state_after .set_contract_class( &felt_to_hash(&0x1010.into()), - &ContractClass::from_path(ERC20_CONTRACT_PATH).unwrap(), + &CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(ERC20_CONTRACT_PATH).unwrap(), + )), ) .unwrap(); state_after .set_contract_class( &felt_to_hash(&0x111.into()), - &ContractClass::from_path(ACCOUNT_CONTRACT_PATH).unwrap(), + &CompiledClass::Deprecated(Arc::new( + ContractClass::from_path(ACCOUNT_CONTRACT_PATH).unwrap(), + )), ) .unwrap(); @@ -2034,7 +2014,7 @@ fn test_library_call_with_declare_v2() { .insert(address.clone(), nonce); state - .set_compiled_class(&Felt252::from_bytes_be(&class_hash), contract_class) + .set_contract_class(&class_hash, &CompiledClass::Casm(Arc::new(contract_class))) .unwrap(); let create_execute_extrypoint = |selector: &BigUint, diff --git a/tests/multi_syscall_test.rs b/tests/multi_syscall_test.rs index 7aa7890d7..9f75e7925 100644 --- a/tests/multi_syscall_test.rs +++ b/tests/multi_syscall_test.rs @@ -1,6 +1,7 @@ use cairo_lang_starknet::casm_contract_class::CasmContractClass; use cairo_vm::felt::Felt252; use num_traits::{Num, Zero}; +use starknet_in_rust::services::api::contract_classes::compiled_class::CompiledClass; use starknet_in_rust::utils::calculate_sn_keccak; use starknet_in_rust::EntryPointType; use starknet_in_rust::{ @@ -28,7 +29,7 @@ fn test_multiple_syscall() { let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(class_hash, CompiledClass::Casm(Arc::new(contract_class))); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -38,11 +39,7 @@ fn test_multiple_syscall() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - None, - Some(contract_class_cache.clone()), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache.clone()); // Create an execution entry point let calldata = [].to_vec(); diff --git a/tests/storage.rs b/tests/storage.rs index 19d03359e..f13bc141c 100644 --- a/tests/storage.rs +++ b/tests/storage.rs @@ -1,6 +1,7 @@ use cairo_vm::felt::Felt252; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use num_traits::Zero; +use starknet_in_rust::services::api::contract_classes::compiled_class::CompiledClass; use starknet_in_rust::EntryPointType; use starknet_in_rust::{ definitions::{block_context::BlockContext, constants::TRANSACTION_VERSION}, @@ -50,7 +51,10 @@ fn integration_storage_test() { let storage_entry = (address.clone(), [90; 32]); let storage_value = Felt252::new(10902); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -66,7 +70,7 @@ fn integration_storage_test() { //* Create state with previous data //* --------------------------------------- - let mut state = CachedState::new(Arc::new(state_reader), Some(contract_class_cache), None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); //* ------------------------------------ //* Create execution entry point diff --git a/tests/syscalls.rs b/tests/syscalls.rs index 23ee0b2e0..03bfd188f 100644 --- a/tests/syscalls.rs +++ b/tests/syscalls.rs @@ -10,7 +10,6 @@ use cairo_vm::{ }, }; use num_traits::{Num, One, Zero}; -use starknet_in_rust::EntryPointType; use starknet_in_rust::{ definitions::{ block_context::{BlockContext, StarknetChainId}, @@ -20,16 +19,17 @@ use starknet_in_rust::{ execution_entry_point::ExecutionEntryPoint, CallInfo, CallType, L2toL1MessageInfo, OrderedEvent, OrderedL2ToL1Message, TransactionExecutionContext, }, - services::api::contract_classes::{ - compiled_class::CompiledClass, deprecated_contract_class::ContractClass, - }, + services::api::contract_classes::deprecated_contract_class::ContractClass, state::{ - cached_state::{CachedState, ContractClassCache}, + cached_state::CachedState, state_api::{State, StateReader}, }, state::{in_memory_state_reader::InMemoryStateReader, ExecutionResourcesManager}, utils::{calculate_sn_keccak, felt_to_hash, Address, ClassHash}, }; +use starknet_in_rust::{ + services::api::contract_classes::compiled_class::CompiledClass, EntryPointType, +}; use std::{ collections::{HashMap, HashSet}, iter::empty, @@ -85,19 +85,23 @@ fn test_contract<'a>( state_reader .address_to_nonce_mut() .insert(contract_address.clone(), nonce); - state_reader - .class_hash_to_contract_class_mut() - .insert(class_hash, contract_class); + state_reader.class_hash_to_compiled_class_mut().insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut storage_entries = Vec::new(); let contract_class_cache = { - let mut contract_class_cache = ContractClassCache::new(); + let mut contract_class_cache = HashMap::new(); for (class_hash, contract_path, contract_address) in extra_contracts { let contract_class = ContractClass::from_path(contract_path) .expect("Could not load extra contract from JSON"); - contract_class_cache.insert(class_hash, contract_class.clone()); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ); if let Some((contract_address, data)) = contract_address { storage_entries.extend( @@ -108,15 +112,16 @@ fn test_contract<'a>( state_reader .address_to_class_hash_mut() .insert(contract_address.clone(), class_hash); - state_reader - .class_hash_to_contract_class_mut() - .insert(class_hash, contract_class.clone()); + state_reader.class_hash_to_compiled_class_mut().insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ); } } - Some(contract_class_cache) + contract_class_cache }; - let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache, None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); storage_entries .into_iter() .for_each(|(a, b, c)| state.set_storage_at(&(a, b), c)); @@ -1079,7 +1084,6 @@ fn deploy_cairo1_from_cairo0_with_constructor() { let test_contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); // Create state reader with class hash data - let mut casm_contract_class_cache = HashMap::new(); let mut contract_class_cache = HashMap::new(); let address = Address(1111.into()); @@ -1087,8 +1091,14 @@ fn deploy_cairo1_from_cairo0_with_constructor() { let nonce = Felt252::zero(); // simulate contract declare - casm_contract_class_cache.insert(test_class_hash, test_contract_class.clone()); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + test_class_hash, + CompiledClass::Casm(Arc::new(test_contract_class.clone())), + ); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -1099,11 +1109,7 @@ fn deploy_cairo1_from_cairo0_with_constructor() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(contract_class_cache), - Some(casm_contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // arguments of deploy contract let calldata: Vec<_> = [test_felt_hash, salt, Felt252::one()].to_vec(); @@ -1180,7 +1186,6 @@ fn deploy_cairo1_from_cairo0_without_constructor() { let test_contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); // Create state reader with class hash data - let mut casm_contract_class_cache = HashMap::new(); let mut contract_class_cache = HashMap::new(); let address = Address(1111.into()); @@ -1188,8 +1193,14 @@ fn deploy_cairo1_from_cairo0_without_constructor() { let nonce = Felt252::zero(); // simulate contract declare - casm_contract_class_cache.insert(test_class_hash, test_contract_class.clone()); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + test_class_hash, + CompiledClass::Casm(Arc::new(test_contract_class.clone())), + ); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -1200,11 +1211,7 @@ fn deploy_cairo1_from_cairo0_without_constructor() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(contract_class_cache), - Some(casm_contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // arguments of deploy contract let calldata: Vec<_> = [test_felt_hash, salt].to_vec(); @@ -1283,7 +1290,6 @@ fn deploy_cairo1_and_invoke() { let test_contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); // Create state reader with class hash data - let mut casm_contract_class_cache = HashMap::new(); let mut contract_class_cache = HashMap::new(); let address = Address(1111.into()); @@ -1291,8 +1297,14 @@ fn deploy_cairo1_and_invoke() { let nonce = Felt252::zero(); // simulate contract declare - casm_contract_class_cache.insert(test_class_hash, test_contract_class.clone()); - contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + test_class_hash, + CompiledClass::Casm(Arc::new(test_contract_class.clone())), + ); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -1303,11 +1315,7 @@ fn deploy_cairo1_and_invoke() { .insert(address.clone(), nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(contract_class_cache), - Some(casm_contract_class_cache), - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // arguments of deploy contract let calldata: Vec<_> = [test_felt_hash, salt].to_vec(); @@ -1408,13 +1416,16 @@ fn send_messages_to_l1_different_contract_calls() { .to_owned(); // Create state reader with class hash data - let mut deprecated_contract_class_cache = HashMap::new(); + let mut contract_class_cache = HashMap::new(); let address = Address(1111.into()); let class_hash: ClassHash = [1; 32]; let nonce = Felt252::zero(); - deprecated_contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut state_reader = InMemoryStateReader::default(); state_reader .address_to_class_hash_mut() @@ -1432,7 +1443,10 @@ fn send_messages_to_l1_different_contract_calls() { let send_msg_class_hash: ClassHash = [2; 32]; let send_msg_nonce = Felt252::zero(); - deprecated_contract_class_cache.insert(send_msg_class_hash, send_msg_contract_class); + contract_class_cache.insert( + send_msg_class_hash, + CompiledClass::Deprecated(Arc::new(send_msg_contract_class)), + ); state_reader .address_to_class_hash_mut() .insert(send_msg_address.clone(), send_msg_class_hash); @@ -1441,11 +1455,7 @@ fn send_messages_to_l1_different_contract_calls() { .insert(send_msg_address, send_msg_nonce); // Create state from the state_reader and contract cache. - let mut state = CachedState::new( - Arc::new(state_reader), - Some(deprecated_contract_class_cache), - None, - ); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); // Create an execution entry point let calldata = [25.into(), 50.into(), 75.into()].to_vec(); diff --git a/tests/syscalls_errors.rs b/tests/syscalls_errors.rs index 17d85bb1f..1e9433e93 100644 --- a/tests/syscalls_errors.rs +++ b/tests/syscalls_errors.rs @@ -10,10 +10,7 @@ use starknet_in_rust::{ execution_entry_point::ExecutionEntryPoint, CallType, TransactionExecutionContext, }, services::api::contract_classes::deprecated_contract_class::ContractClass, - state::{ - cached_state::{CachedState, ContractClassCache}, - state_api::State, - }, + state::{cached_state::CachedState, state_api::State}, state::{in_memory_state_reader::InMemoryStateReader, ExecutionResourcesManager}, utils::{calculate_sn_keccak, Address, ClassHash}, }; @@ -21,6 +18,8 @@ use std::path::Path; use std::sync::Arc; use assert_matches::assert_matches; +use starknet_in_rust::services::api::contract_classes::compiled_class::CompiledClass; +use std::collections::HashMap; #[allow(clippy::too_many_arguments)] fn test_contract<'a>( @@ -63,19 +62,23 @@ fn test_contract<'a>( state_reader .address_to_nonce_mut() .insert(contract_address.clone(), nonce); - state_reader - .class_hash_to_contract_class_mut() - .insert(class_hash, contract_class); + state_reader.class_hash_to_compiled_class_mut().insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class)), + ); let mut storage_entries = Vec::new(); let contract_class_cache = { - let mut contract_class_cache = ContractClassCache::new(); + let mut contract_class_cache = HashMap::new(); for (class_hash, contract_path, contract_address) in extra_contracts { let contract_class = ContractClass::from_path(contract_path) .expect("Could not load extra contract from JSON"); - contract_class_cache.insert(class_hash, contract_class.clone()); + contract_class_cache.insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ); if let Some((contract_address, data)) = contract_address { storage_entries.extend(data.into_iter().map(|(name, value)| { @@ -89,15 +92,16 @@ fn test_contract<'a>( state_reader .address_to_class_hash_mut() .insert(contract_address.clone(), class_hash); - state_reader - .class_hash_to_contract_class_mut() - .insert(class_hash, contract_class.clone()); + state_reader.class_hash_to_compiled_class_mut().insert( + class_hash, + CompiledClass::Deprecated(Arc::new(contract_class.clone())), + ); } } - Some(contract_class_cache) + contract_class_cache }; - let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache, None); + let mut state = CachedState::new(Arc::new(state_reader), contract_class_cache); storage_entries .into_iter() .for_each(|(a, b, c)| state.set_storage_at(&(a, b), c));