diff --git a/Cargo.lock b/Cargo.lock index fc867b8211..3fd474fa1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,7 +142,7 @@ dependencies = [ "ark-std", "derivative", "digest 0.10.7", - "itertools", + "itertools 0.10.5", "num-bigint", "num-traits 0.2.15", "paste", @@ -328,9 +328,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "a6a1de45611fdb535bfde7b7de4fd54f4fd2b17b1737c0a59b69bf9b92074b8c" dependencies = [ "async-trait", "axum-core", @@ -619,9 +619,9 @@ dependencies = [ [[package]] name = "cairo-felt" -version = "0.6.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eec837cac4e5e5a7f7abd6fb26c1d91cf0a588cf394367a7111a9549cabaa0b9" +checksum = "0f8de851723a7d13ed8b0b588a78ffa6b38d8e1f3eb4b6e71a96376510e5504a" dependencies = [ "lazy_static", "num-bigint", @@ -632,9 +632,9 @@ dependencies = [ [[package]] name = "cairo-lang-casm" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65519f6686244c4ba6be09c6ef3d8146d1d4d5c87cbb6693671117c0ae2a5b01" +checksum = "8c3b6b34b912d2b95084ee7fbd4b85c36105adf63c2bd521c4c38d625300488f" dependencies = [ "cairo-lang-utils", "indoc", @@ -649,9 +649,9 @@ dependencies = [ [[package]] name = "cairo-lang-compiler" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5a8463717f788a132f1573fb1ad6368edd1f41bfdef6f4d143368b3816a1f9" +checksum = "b1fdc25d854fdefed50357497a372449e8260518d0d1d8e3fe919e6df34d42a1" dependencies = [ "anyhow", "cairo-lang-defs", @@ -674,18 +674,18 @@ dependencies = [ [[package]] name = "cairo-lang-debug" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec1fd38b6ae840897d86788a6c81332b903e37f438470c2c2558f79a6ceb9d9" +checksum = "cbdd66e992e76847d92fbd693450b908945bdf78d341b11f5d72d6c14273afd1" dependencies = [ "cairo-lang-utils", ] [[package]] name = "cairo-lang-defs" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e91660f00c69d9d322032a82f8d426463d5eeb84cf614fb6ae3cb9eeb87a50" +checksum = "ad00621f022382bdab293f642f175e95bbaf343d42b9eab0a1f823f926808099" dependencies = [ "cairo-lang-debug", "cairo-lang-diagnostics", @@ -693,41 +693,42 @@ dependencies = [ "cairo-lang-parser", "cairo-lang-syntax", "cairo-lang-utils", - "indexmap 1.9.3", - "itertools", + "indexmap 2.0.0", + "itertools 0.11.0", "salsa", "smol_str", ] [[package]] name = "cairo-lang-diagnostics" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2c525de1fe9c3e877a75826414246f5d9502712a11cb7bd02a27f916573b2b" +checksum = "cc8531cfa24bc9751092ac180d0c5afa4fe4c115548d8ed3c483797cc5612d34" dependencies = [ + "cairo-lang-debug", "cairo-lang-filesystem", "cairo-lang-utils", - "itertools", + "itertools 0.11.0", "salsa", ] [[package]] name = "cairo-lang-eq-solver" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8794b6c3c8b76bd04a59a73c490260fb6877ed1780b53d632a5fa6576335d33c" +checksum = "24e826a4314d86cd2770dca08c0780a7a2130cb451c1456eef28890d893cac82" dependencies = [ "cairo-lang-utils", "good_lp", - "indexmap 1.9.3", - "itertools", + "indexmap 2.0.0", + "itertools 0.11.0", ] [[package]] name = "cairo-lang-filesystem" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a690a34a6b8ead64ee489e1ee0c0922bc11636259b2dffd64eb17921c1e8ee5" +checksum = "cd3ba56ffff9c8e8bc011d8f9b93a66a7218667f77f7e5901f6eb3192c48350e" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", @@ -739,9 +740,9 @@ dependencies = [ [[package]] name = "cairo-lang-lowering" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35834c45f88863183fe575b4de20935389cdfba2178b4c6b677bd4a022f841d6" +checksum = "c1009e0130f2a936ce00472356d1bbdf131eb1bd95904efc8ad02204aebf3ac8" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -753,8 +754,8 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "id-arena", - "indexmap 1.9.3", - "itertools", + "indexmap 2.0.0", + "itertools 0.11.0", "log", "num-bigint", "num-traits 0.2.15", @@ -764,9 +765,9 @@ dependencies = [ [[package]] name = "cairo-lang-parser" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "334b94f038c8c583002523b4b17adcedcac355f50f6a5b13373c2da58dcabc4c" +checksum = "59e96a998c0d873e2e9cdf574882a063e8695a627ad19c4b9357db767bbdb64c" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -774,7 +775,7 @@ dependencies = [ "cairo-lang-syntax-codegen", "cairo-lang-utils", "colored", - "itertools", + "itertools 0.11.0", "log", "num-bigint", "num-traits 0.2.15", @@ -785,9 +786,9 @@ dependencies = [ [[package]] name = "cairo-lang-plugins" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fa6b03b252d501c11e9ecfa5cee009191fce232aafd2b19da521de770a41bf" +checksum = "35998a2921161b64f268ce6293b351ddbfea127f2632b378ebe68f22ce7f262b" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", @@ -797,41 +798,42 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "indoc", - "itertools", + "itertools 0.11.0", + "num-bigint", "salsa", "smol_str", ] [[package]] name = "cairo-lang-proc-macros" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f927a0a2a84d4fc0400fb6fcb8b7948863a497b194cef0952cef03107af3b087" +checksum = "991981359e104160e13d2a3503467b4de44b75b38c566102c304ecd02f396a61" dependencies = [ "cairo-lang-debug", "quote", - "syn 1.0.109", + "syn 2.0.26", ] [[package]] name = "cairo-lang-project" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cfe69dc1e2f225964fc2b10637a8238bfa3b256fbe4b30cfcec31ad0270728e" +checksum = "20948110870e2fdfdacb3c8ade01d7726973f00eede80ffe1613d80dea6edba7" dependencies = [ "cairo-lang-filesystem", "cairo-lang-utils", "serde", "smol_str", "thiserror", - "toml 0.4.10", + "toml", ] [[package]] name = "cairo-lang-semantic" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852484f7908ba89d1423b95dd465f1e66560793f2c6505a4a52fabffa2d82fa4" +checksum = "c3738e1d1cc5b3cd696b8534dfdbf274695f76bf68c000f406b91f38bee9931e" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -842,7 +844,7 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "id-arena", - "itertools", + "itertools 0.11.0", "log", "num-bigint", "num-traits 0.2.15", @@ -852,17 +854,17 @@ dependencies = [ [[package]] name = "cairo-lang-sierra" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d80a2fbb25c54d71135e5603e8c3f2882e06b072ea1ebd6a3163e18a03e958f" +checksum = "fc3d4aa91e7597e70023ff1b5e331053ef5c0cd7c74c4e8e4141b9454487c7b8" dependencies = [ "cairo-lang-utils", "const-fnv1a-hash", "convert_case 0.6.0", "derivative", - "itertools", - "lalrpop 0.19.12", - "lalrpop-util 0.19.12", + "itertools 0.11.0", + "lalrpop", + "lalrpop-util", "num-bigint", "num-traits 0.2.15", "regex", @@ -875,35 +877,37 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2b7a53b741b8f4a72aef86ed54a15974d6e5389fa91740225f33ef7bbaafcc" +checksum = "84aec8f04ddf903c1d48940b60fbb760ba483c6eac58bbb21d4b3163e03cf7c5" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", + "cairo-lang-sierra-type-size", "cairo-lang-utils", - "itertools", + "itertools 0.11.0", "thiserror", ] [[package]] name = "cairo-lang-sierra-gas" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b101112c0e2a2101b3d1f66a300f06be1c183245e4a7de9739a9c8c564c60936" +checksum = "365f895f6c6d828eaf992b6dad7f41493827d65e4eafa0de5014af013e22ade7" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", + "cairo-lang-sierra-type-size", "cairo-lang-utils", - "itertools", + "itertools 0.11.0", "thiserror", ] [[package]] name = "cairo-lang-sierra-generator" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e34636a12e1fd393e9600aec5eac0c1b2ba3ddf4c5e47559bed3d14b81ac289" +checksum = "2b52fe30efab4d85c388bb18b423bafcbd9b6a117fdacdc77e647dfd4f257017" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -918,8 +922,8 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "id-arena", - "indexmap 1.9.3", - "itertools", + "indexmap 2.0.0", + "itertools 0.11.0", "num-bigint", "salsa", "smol_str", @@ -927,9 +931,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7127b5b2f6c08e745f4332aac4bfefd007e2b94d7fc4581447ff1df48f63cf00" +checksum = "0d66ffe7a758f18092e013bea5e7eba8fa7a3e314f66c80ed9056a533deb6eb3" dependencies = [ "assert_matches", "cairo-felt", @@ -937,20 +941,31 @@ dependencies = [ "cairo-lang-sierra", "cairo-lang-sierra-ap-change", "cairo-lang-sierra-gas", + "cairo-lang-sierra-type-size", "cairo-lang-utils", "indoc", - "itertools", + "itertools 0.11.0", "log", "num-bigint", "num-traits 0.2.15", "thiserror", ] +[[package]] +name = "cairo-lang-sierra-type-size" +version = "2.1.0-rc0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5a7ff4858d2f8f5d075cbe60758dcc019eaabadf695480db5a1fec05a2172b" +dependencies = [ + "cairo-lang-sierra", + "cairo-lang-utils", +] + [[package]] name = "cairo-lang-starknet" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2603ecb84110869254287c1c440f14ddc5dafa8b913ce0a66cda201564cad62" +checksum = "d21f8c2a7654262df386c1cf6cdffe614d35d01e2c8bc37e5b30c0ffc05c9a78" dependencies = [ "anyhow", "cairo-felt", @@ -972,8 +987,9 @@ dependencies = [ "cairo-lang-utils", "convert_case 0.6.0", "genco", + "indent", "indoc", - "itertools", + "itertools 0.11.0", "log", "num-bigint", "num-integer", @@ -988,9 +1004,9 @@ dependencies = [ [[package]] name = "cairo-lang-syntax" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02676702b628792b3437b391b87cb915480a111037d253a5e995d6a952f59515" +checksum = "f5b464ac5257455a773d00569aef590a156f4e60d940ce6bca1d27f8fa1d26f6" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -1005,9 +1021,9 @@ dependencies = [ [[package]] name = "cairo-lang-syntax-codegen" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955668038c14f09e16d708feb4416ab37b657e8d345c09f3c9d48c02a1dcb616" +checksum = "c108224d2b83d3c912bdb52f62953e5e7983a05de857a2e93f7a8ebc813921b0" dependencies = [ "genco", "xshell", @@ -1015,12 +1031,12 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.0.2" +version = "2.1.0-rc0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d38012d7e208df96a5cccb87122dfe8ae02eba2690d29a3d735979c9fb8dde7" +checksum = "a42999459cdd0fae64986fdfb3b7fb8e7488ad733d83f81424d1f498a97ebfd1" dependencies = [ - "indexmap 1.9.3", - "itertools", + "indexmap 2.0.0", + "itertools 0.11.0", "num-bigint", "num-integer", "num-traits 0.2.15", @@ -1146,9 +1162,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.12" +version = "4.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73" +checksum = "8f644d0dac522c8b05ddc39aaaccc5b136d5dc4ff216610c5641e3be5becf56c" dependencies = [ "clap_builder", "clap_derive 4.3.12", @@ -1157,9 +1173,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.12" +version = "4.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd" +checksum = "af410122b9778e024f9e0fb35682cc09cc3f85cad5e8d3ba8f47a9702df6e73d" dependencies = [ "anstream", "anstyle", @@ -1872,7 +1888,7 @@ dependencies = [ "serde", "serde_json", "syn 2.0.26", - "toml 0.7.6", + "toml", "walkdir", ] @@ -2477,7 +2493,7 @@ dependencies = [ "futures", "gumdrop", "http", - "itertools", + "itertools 0.10.5", "lazy_static", "log", "num-format", @@ -2832,6 +2848,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "indent" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f1a0777d972970f204fdf8ef319f1f4f8459131636d7e3c96c5d59570d0fa6" + [[package]] name = "indenter" version = "0.3.3" @@ -2857,6 +2879,7 @@ checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", "hashbrown 0.14.0", + "serde", ] [[package]] @@ -2949,6 +2972,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -3139,7 +3171,7 @@ dependencies = [ "anyhow", "base64 0.21.2", "bytecount", - "clap 4.3.12", + "clap 4.3.15", "fancy-regex", "fraction", "getrandom", @@ -3156,7 +3188,7 @@ dependencies = [ "serde_json", "time 0.3.23", "url", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -3182,28 +3214,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "lalrpop" -version = "0.19.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" -dependencies = [ - "ascii-canvas", - "bit-set", - "diff", - "ena", - "is-terminal", - "itertools", - "lalrpop-util 0.19.12", - "petgraph", - "regex", - "regex-syntax 0.6.29", - "string_cache", - "term", - "tiny-keccak", - "unicode-xid", -] - [[package]] name = "lalrpop" version = "0.20.0" @@ -3215,9 +3225,10 @@ dependencies = [ "diff", "ena", "is-terminal", - "itertools", - "lalrpop-util 0.20.0", + "itertools 0.10.5", + "lalrpop-util", "petgraph", + "pico-args", "regex", "regex-syntax 0.7.4", "string_cache", @@ -3228,19 +3239,13 @@ dependencies = [ [[package]] name = "lalrpop-util" -version = "0.19.12" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed" +checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" dependencies = [ "regex", ] -[[package]] -name = "lalrpop-util" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" - [[package]] name = "lazy_static" version = "1.4.0" @@ -4236,9 +4241,9 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "path-clean" -version = "0.1.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd" +checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" [[package]] name = "path-slash" @@ -4351,6 +4356,12 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" version = "1.1.2" @@ -4425,7 +4436,7 @@ checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "float-cmp", - "itertools", + "itertools 0.10.5", "normalize-line-endings", "predicates-core", "regex", @@ -4544,7 +4555,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2aa5feb83bf4b2c8919eaf563f51dbab41183de73ba2353c0e03cd7b6bd892" dependencies = [ "chrono", - "itertools", + "itertools 0.10.5", "once_cell", "regex", ] @@ -5099,9 +5110,9 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scrypt" @@ -5127,9 +5138,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -5268,9 +5279,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.23" +version = "0.9.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da6075b41c7e3b079e5f246eb6094a44850d3a4c25a67c581c80796c80134012" +checksum = "bd5f51e3fdb5b9cdd1577e1cb7a733474191b1aca6a72c2e50913241632c1180" dependencies = [ "indexmap 2.0.0", "itoa", @@ -5468,9 +5479,9 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c792fe9fae2a2f716846f214ca10d5a1e21133e0bf36cef34bcc4a852467b21" dependencies = [ - "itertools", - "lalrpop 0.20.0", - "lalrpop-util 0.20.0", + "itertools 0.10.5", + "lalrpop", + "lalrpop-util", "phf", "thiserror", "unicode-xid", @@ -5576,8 +5587,7 @@ dependencies = [ [[package]] name = "starknet_api" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee34bfc3126f9aff7eb88be9fb71eed9b8d184448c6c14f51febd312bba2856" +source = "git+https://github.com/starkware-libs/starknet-api?rev=ecc9b6946ef13003da202838e4124a9ad2efabb0#ecc9b6946ef13003da202838e4124a9ad2efabb0" dependencies = [ "cairo-lang-starknet", "derive_more", @@ -6057,15 +6067,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" -dependencies = [ - "serde", -] - [[package]] name = "toml" version = "0.7.6" @@ -6359,9 +6360,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" [[package]] name = "valuable" diff --git a/Cargo.toml b/Cargo.toml index 1114bc1ba1..cbecb13a66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,9 +33,9 @@ async-trait = "0.1.56" axum = "0.6.12" base64 = "0.13.0" byteorder = "1.4.3" -cairo-lang-starknet = "2.0.0-rc1" -cairo-lang-casm = "2.0.0-rc1" -cairo-lang-utils = "2.0.0-rc1" +cairo-lang-starknet = "2.1.0-rc0" +cairo-lang-casm = "2.1.0-rc0" +cairo-lang-utils = "2.1.0-rc0" camelpaste = "0.1.0" clap = "3.2.19" const_format = "0.2.30" @@ -76,7 +76,7 @@ serde = "1.0.130" serde_json = "1.0.81" serde_yaml = "0.9.16" simple_logger = "4.0.0" -starknet_api = "0.2.0" +starknet_api = { git = "https://github.com/starkware-libs/starknet-api", rev = "ecc9b6946ef13003da202838e4124a9ad2efabb0" } tempfile = "3.3.0" thiserror = "1.0.31" tokio = "1.18.2" diff --git a/crates/papyrus_gateway/Cargo.toml b/crates/papyrus_gateway/Cargo.toml index fc146d212f..3aac13db1e 100644 --- a/crates/papyrus_gateway/Cargo.toml +++ b/crates/papyrus_gateway/Cargo.toml @@ -15,7 +15,7 @@ jsonrpsee = { workspace = true, features = ["full"] } metrics.workspace = true papyrus_common = { path = "../papyrus_common"} papyrus_proc_macros = { path = "../papyrus_proc_macros"} -papyrus_storage = { path = "../papyrus_storage" } +papyrus_storage = { path = "../papyrus_storage", version = "0.0.1" } starknet_writer_client = { path = "../starknet_writer_client" } serde = { workspace = true, features = ["derive"] } serde_json.workspace = true diff --git a/crates/papyrus_gateway/src/v0_3_0/api/api_impl.rs b/crates/papyrus_gateway/src/v0_3_0/api/api_impl.rs index 5971aa1f5e..d057ba492c 100644 --- a/crates/papyrus_gateway/src/v0_3_0/api/api_impl.rs +++ b/crates/papyrus_gateway/src/v0_3_0/api/api_impl.rs @@ -207,13 +207,9 @@ impl JsonRpcV0_3_0Server for JsonRpcServerV0_3_0Impl { let block_number = transaction_index.0; let status = get_block_status(&txn, block_number)?; - let header: BlockHeader = - get_block_header_by_number(&txn, block_number).map_err(internal_server_error)?; - - let transaction = txn - .get_transaction(transaction_index) + let block_hash = get_block_header_by_number::<_, BlockHeader>(&txn, block_number) .map_err(internal_server_error)? - .ok_or_else(|| ErrorObjectOwned::from(JsonRpcError::TransactionHashNotFound))?; + .block_hash; let thin_tx_output = txn .get_transaction_output(transaction_index) @@ -228,12 +224,13 @@ impl JsonRpcV0_3_0Server for JsonRpcServerV0_3_0Impl { let output = TransactionOutput::from_thin_transaction_output(thin_tx_output, events); Ok(TransactionReceiptWithStatus { - receipt: TransactionReceipt::from_transaction_output( - output, - &transaction, - header.block_hash, + receipt: TransactionReceipt { + transaction_hash, + r#type: output.r#type(), + block_hash, block_number, - ), + output, + }, status: status.into(), }) } diff --git a/crates/papyrus_gateway/src/v0_3_0/api/test.rs b/crates/papyrus_gateway/src/v0_3_0/api/test.rs index 737a7ad513..770831e27f 100644 --- a/crates/papyrus_gateway/src/v0_3_0/api/test.rs +++ b/crates/papyrus_gateway/src/v0_3_0/api/test.rs @@ -571,21 +571,22 @@ async fn get_transaction_receipt() { .commit() .unwrap(); - let transaction = block.body.transactions.index(0); + let transaction_hash = block.body.transactions.index(0).transaction_hash(); let output = TransactionOutput::from(block.body.transaction_outputs.index(0).clone()); let expected_receipt = TransactionReceiptWithStatus { - receipt: TransactionReceipt::from_transaction_output( + receipt: TransactionReceipt { + transaction_hash, + r#type: output.r#type(), + block_hash: block.header.block_hash, + block_number: block.header.block_number, output, - transaction, - block.header.block_hash, - block.header.block_number, - ), + }, status: TransactionStatus::AcceptedOnL2, }; let res = module .call::<_, TransactionReceiptWithStatus>( "starknet_V0_3_0_getTransactionReceipt", - [transaction.transaction_hash()], + [transaction_hash], ) .await .unwrap(); @@ -608,7 +609,7 @@ async fn get_transaction_receipt() { let res = module .call::<_, TransactionReceiptWithStatus>( "starknet_V0_3_0_getTransactionReceipt", - [transaction.transaction_hash()], + [transaction_hash], ) .await .unwrap(); diff --git a/crates/papyrus_gateway/src/v0_3_0/transaction.rs b/crates/papyrus_gateway/src/v0_3_0/transaction.rs index f07af99b56..4567a5da5f 100644 --- a/crates/papyrus_gateway/src/v0_3_0/transaction.rs +++ b/crates/papyrus_gateway/src/v0_3_0/transaction.rs @@ -299,54 +299,7 @@ pub struct TransactionReceiptWithStatus { } #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -#[serde(untagged)] -pub enum TransactionReceipt { - Deploy(DeployTransactionReceipt), - Common(CommonTransactionReceipt), -} - -impl TransactionReceipt { - pub fn from_transaction_output( - output: TransactionOutput, - transaction: &starknet_api::transaction::Transaction, - block_hash: BlockHash, - block_number: BlockNumber, - ) -> Self { - let common = CommonTransactionReceipt { - transaction_hash: transaction.transaction_hash(), - r#type: output.r#type(), - block_hash, - block_number, - output, - }; - - match transaction { - starknet_api::transaction::Transaction::DeployAccount(tx) => { - Self::Deploy(DeployTransactionReceipt { - common, - contract_address: tx.contract_address, - }) - } - starknet_api::transaction::Transaction::Deploy(tx) => { - Self::Deploy(DeployTransactionReceipt { - common, - contract_address: tx.contract_address, - }) - } - _ => Self::Common(common), - } - } -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -pub struct DeployTransactionReceipt { - #[serde(flatten)] - pub common: CommonTransactionReceipt, - pub contract_address: ContractAddress, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] -pub struct CommonTransactionReceipt { +pub struct TransactionReceipt { pub transaction_hash: TransactionHash, pub r#type: TransactionType, pub block_hash: BlockHash, @@ -358,9 +311,9 @@ pub struct CommonTransactionReceipt { #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] #[serde(untagged)] pub enum TransactionOutput { - Declare(DeclareTransactionOutput), Deploy(DeployTransactionOutput), DeployAccount(DeployAccountTransactionOutput), + Declare(DeclareTransactionOutput), Invoke(InvokeTransactionOutput), L1Handler(L1HandlerTransactionOutput), } @@ -383,6 +336,7 @@ impl TransactionOutput { actual_fee: thin_deploy.actual_fee, messages_sent: thin_deploy.messages_sent, events, + contract_address: thin_deploy.contract_address, }) } ThinTransactionOutput::DeployAccount(thin_deploy) => { @@ -390,6 +344,7 @@ impl TransactionOutput { actual_fee: thin_deploy.actual_fee, messages_sent: thin_deploy.messages_sent, events, + contract_address: thin_deploy.contract_address, }) } ThinTransactionOutput::Invoke(thin_invoke) => { diff --git a/crates/papyrus_gateway/src/v0_3_0/transaction_test.rs b/crates/papyrus_gateway/src/v0_3_0/transaction_test.rs index e87100c9e5..0677f3348b 100644 --- a/crates/papyrus_gateway/src/v0_3_0/transaction_test.rs +++ b/crates/papyrus_gateway/src/v0_3_0/transaction_test.rs @@ -4,14 +4,10 @@ use papyrus_storage::body::events::{ ThinDeclareTransactionOutput, ThinDeployAccountTransactionOutput, ThinDeployTransactionOutput, ThinInvokeTransactionOutput, ThinL1HandlerTransactionOutput, ThinTransactionOutput, }; -use starknet_api::block::BlockHeader; -use starknet_api::transaction::{ - DeclareTransactionOutput, DeployAccountTransactionOutput, DeployTransactionOutput, - InvokeTransactionOutput, L1HandlerTransactionOutput, Transaction, -}; +use starknet_api::transaction::Transaction; use test_utils::{get_rng, GetTestInstance}; -use crate::v0_3_0::transaction::{TransactionOutput, TransactionReceipt}; +use crate::v0_3_0::transaction::TransactionOutput; macro_rules! gen_test_from_thin_transaction_output_macro { ($variant: ident) => { @@ -94,32 +90,3 @@ async fn test_gateway_trascation_from_starknet_api_transaction() { Transaction::DeployAccount(inner_transaction.clone()).try_into().unwrap(); assert_eq!(transaction.transaction_hash(), inner_transaction.transaction_hash); } - -macro_rules! test_recipe_from_transtaction_output { - ($variant:ident, $recipe_type:ident) => { - paste! { - #[tokio::test] - async fn []() { - let mut rng = get_rng(); - let block_header = BlockHeader::default(); - let transaction = Transaction::$variant( - starknet_api::transaction::[<$variant Transaction>]::get_test_instance(&mut rng), - ); - let output = TransactionOutput::$variant([<$variant TransactionOutput>]::default()); - let receipt = TransactionReceipt::from_transaction_output( - output, - &transaction, - block_header.block_hash, - block_header.block_number, - ); - assert_matches!(receipt, TransactionReceipt::$recipe_type(_)); - } - } - } -} - -test_recipe_from_transtaction_output!(Declare, Common); -test_recipe_from_transtaction_output!(Invoke, Common); -test_recipe_from_transtaction_output!(L1Handler, Common); -test_recipe_from_transtaction_output!(Deploy, Deploy); -test_recipe_from_transtaction_output!(DeployAccount, Deploy); diff --git a/crates/papyrus_monitoring_gateway/Cargo.toml b/crates/papyrus_monitoring_gateway/Cargo.toml index f33a5ecc48..4cff467da0 100644 --- a/crates/papyrus_monitoring_gateway/Cargo.toml +++ b/crates/papyrus_monitoring_gateway/Cargo.toml @@ -11,7 +11,7 @@ futures-util.workspace = true hyper = { workspace = true, features = ["full"] } metrics-exporter-prometheus = { version = "0.12.1" } metrics-process = { version = "1.0.11" } -papyrus_storage = { path = "../papyrus_storage" } +papyrus_storage = { path = "../papyrus_storage", version = "0.0.1" } serde = { workspace = true, features = ["derive"] } serde_json.workspace = true thiserror.workspace = true diff --git a/crates/papyrus_node/Cargo.toml b/crates/papyrus_node/Cargo.toml index be42edff3b..7474eb6dc4 100644 --- a/crates/papyrus_node/Cargo.toml +++ b/crates/papyrus_node/Cargo.toml @@ -19,7 +19,7 @@ jsonrpsee = { workspace = true, features = ["full"] } libmdbx = { workspace = true, features = ["lifetimed-bytes"] } papyrus_gateway = { path = "../papyrus_gateway" } papyrus_monitoring_gateway = { path = "../papyrus_monitoring_gateway" } -papyrus_storage = { path = "../papyrus_storage" } +papyrus_storage = { path = "../papyrus_storage", version = "0.0.1" } papyrus_sync = { path = "../papyrus_sync" } reqwest = { workspace = true, features = ["json", "blocking"] } serde = { workspace = true, features = ["derive"] } diff --git a/crates/papyrus_node/src/bin/central_source_integration_test.rs b/crates/papyrus_node/src/bin/central_source_integration_test.rs index cc1eae2603..75b6c91596 100644 --- a/crates/papyrus_node/src/bin/central_source_integration_test.rs +++ b/crates/papyrus_node/src/bin/central_source_integration_test.rs @@ -32,7 +32,7 @@ async fn main() { let mut block_marker = initial_block_number; let block_stream = central_source.stream_new_blocks(block_marker, last_block_number).fuse(); pin_mut!(block_stream); - while let Some(Ok((block_number, _block))) = block_stream.next().await { + while let Some(Ok((block_number, _block, _starknet_version))) = block_stream.next().await { assert!( block_marker == block_number, "Expected block number ({block_marker}) does not match the result ({block_number}).", diff --git a/crates/papyrus_storage/src/body/events.rs b/crates/papyrus_storage/src/body/events.rs index da6877e167..d8b5ec50e1 100644 --- a/crates/papyrus_storage/src/body/events.rs +++ b/crates/papyrus_storage/src/body/events.rs @@ -342,6 +342,8 @@ pub struct ThinDeployTransactionOutput { pub messages_sent: Vec, /// The contract addresses of the events emitted by the transaction. pub events_contract_addresses: Vec, + /// The contract address of the deployed contract. + pub contract_address: ContractAddress, } /// A thin version of @@ -355,6 +357,8 @@ pub struct ThinDeployAccountTransactionOutput { pub messages_sent: Vec, /// The contract addresses of the events emitted by the transaction. pub events_contract_addresses: Vec, + /// The contract address of the deployed contract. + pub contract_address: ContractAddress, } impl From for ThinTransactionOutput { @@ -374,6 +378,7 @@ impl From for ThinTransactionOutput { actual_fee: tx_output.actual_fee, messages_sent: tx_output.messages_sent, events_contract_addresses, + contract_address: tx_output.contract_address, }) } TransactionOutput::DeployAccount(tx_output) => { @@ -381,6 +386,7 @@ impl From for ThinTransactionOutput { actual_fee: tx_output.actual_fee, messages_sent: tx_output.messages_sent, events_contract_addresses, + contract_address: tx_output.contract_address, }) } TransactionOutput::Invoke(tx_output) => { diff --git a/crates/papyrus_storage/src/header.rs b/crates/papyrus_storage/src/header.rs index df6213c29b..28bdfa3010 100644 --- a/crates/papyrus_storage/src/header.rs +++ b/crates/papyrus_storage/src/header.rs @@ -36,6 +36,9 @@ #[path = "header_test.rs"] mod header_test; +use std::fmt::Display; + +use serde::{Deserialize, Serialize}; use starknet_api::block::{BlockHash, BlockHeader, BlockNumber}; use tracing::debug; @@ -56,6 +59,12 @@ pub trait HeaderStorageReader { &self, block_hash: &BlockHash, ) -> StorageResult>; + + /// Returns the Starknet version at the given block number. + fn get_starknet_version( + &self, + block_number: BlockNumber, + ) -> StorageResult>; } /// Interface for writing data related to the block headers. @@ -71,11 +80,22 @@ where block_header: &BlockHeader, ) -> StorageResult; + /// Update the starknet version if needed. + fn update_starknet_version( + self, + block_number: &BlockNumber, + starknet_version: &StarknetVersion, + ) -> StorageResult; + /// Removes a block header from the storage and returns the removed data. fn revert_header(self, block_number: BlockNumber) -> StorageResult<(Self, Option)>; } +/// A version of the Starknet protocol used when creating a block. +#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] +pub struct StarknetVersion(pub String); + impl<'env, Mode: TransactionKind> HeaderStorageReader for StorageTxn<'env, Mode> { fn get_header_marker(&self) -> StorageResult { let markers_table = self.txn.open_table(&self.tables.markers)?; @@ -96,6 +116,28 @@ impl<'env, Mode: TransactionKind> HeaderStorageReader for StorageTxn<'env, Mode> let block_number = block_hash_to_number_table.get(&self.txn, block_hash)?; Ok(block_number) } + + fn get_starknet_version( + &self, + block_number: BlockNumber, + ) -> StorageResult> { + if block_number >= self.get_header_marker()? { + return Ok(None); + } + + let starknet_version_table = self.txn.open_table(&self.tables.starknet_version)?; + let mut cursor = starknet_version_table.cursor(&self.txn)?; + cursor.lower_bound(&block_number.next())?; + let res = cursor.prev()?; + + match res { + Some((_block_number, starknet_version)) => Ok(Some(starknet_version)), + None => unreachable!( + "Since block_number >= self.get_header_marker(), starknet_version_table should \ + have at least a single mapping." + ), + } + } } impl<'env> HeaderStorageWriter for StorageTxn<'env, RW> { @@ -115,6 +157,27 @@ impl<'env> HeaderStorageWriter for StorageTxn<'env, RW> { // Write mapping. update_hash_mapping(&self.txn, &block_hash_to_number_table, block_header, block_number)?; + + Ok(self) + } + + fn update_starknet_version( + self, + block_number: &BlockNumber, + starknet_version: &StarknetVersion, + ) -> StorageResult { + let starknet_version_table = self.txn.open_table(&self.tables.starknet_version)?; + let mut cursor = starknet_version_table.cursor(&self.txn)?; + cursor.lower_bound(block_number)?; + let res = cursor.prev()?; + + match res { + Some((_block_number, last_starknet_version)) + if last_starknet_version == *starknet_version => {} + _ => { + starknet_version_table.insert(&self.txn, block_number, starknet_version)?; + } + } Ok(self) } @@ -181,3 +244,15 @@ fn update_marker<'env>( markers_table.upsert(txn, &MarkerKind::Header, &block_number.next())?; Ok(()) } + +impl Default for StarknetVersion { + fn default() -> Self { + Self("0.0.0".to_string()) + } +} + +impl Display for StarknetVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} diff --git a/crates/papyrus_storage/src/header_test.rs b/crates/papyrus_storage/src/header_test.rs index 7c9c4cdc55..0fcd88e3f1 100644 --- a/crates/papyrus_storage/src/header_test.rs +++ b/crates/papyrus_storage/src/header_test.rs @@ -4,7 +4,7 @@ use starknet_api::block::{BlockHash, BlockHeader, BlockNumber}; use starknet_api::hash::StarkFelt; use starknet_api::stark_felt; -use crate::header::{HeaderStorageReader, HeaderStorageWriter}; +use crate::header::{HeaderStorageReader, HeaderStorageWriter, StarknetVersion}; use crate::test_utils::get_test_storage; use crate::{StorageError, StorageWriter}; @@ -138,3 +138,91 @@ fn append_2_headers(writer: &mut StorageWriter) { .commit() .unwrap(); } + +#[tokio::test] +async fn starknet_version() { + fn block_header(hash: u8) -> BlockHeader { + BlockHeader { block_hash: BlockHash(stark_felt!(hash)), ..BlockHeader::default() } + } + + let ((reader, mut writer), _temp_dir) = get_test_storage(); + + let initial_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(0)).unwrap(); + assert!(initial_starknet_version.is_none()); + + writer + .begin_rw_txn() + .unwrap() + .append_header(BlockNumber(0), &block_header(0)) + .unwrap() + .update_starknet_version(&BlockNumber(0), &StarknetVersion::default()) + .unwrap() + .commit() + .unwrap(); + + let block_0_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(0)).unwrap(); + assert_eq!(block_0_starknet_version.unwrap(), StarknetVersion::default()); + + let non_existing_block_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(1)).unwrap(); + assert!(non_existing_block_starknet_version.is_none()); + + let second_version = StarknetVersion("second_version".to_string()); + let yet_another_version = StarknetVersion("yet_another_version".to_string()); + + writer + .begin_rw_txn() + .unwrap() + .append_header(BlockNumber(1), &block_header(1)) + .unwrap() + .update_starknet_version(&BlockNumber(1), &StarknetVersion::default()) + .unwrap() + .append_header(BlockNumber(2), &block_header(2)) + .unwrap() + .update_starknet_version(&BlockNumber(2), &second_version) + .unwrap() + .append_header(BlockNumber(3), &block_header(3)) + .unwrap() + .update_starknet_version(&BlockNumber(3), &second_version) + .unwrap() + .append_header(BlockNumber(4), &block_header(4)) + .unwrap() + .update_starknet_version(&BlockNumber(4), &yet_another_version) + .unwrap() + .append_header(BlockNumber(5), &block_header(5)) + .unwrap() + .update_starknet_version(&BlockNumber(5), &yet_another_version) + .unwrap() + .commit() + .unwrap(); + + let block_0_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(0)).unwrap(); + assert_eq!(block_0_starknet_version.unwrap(), StarknetVersion::default()); + + let block_1_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(1)).unwrap(); + assert_eq!(block_1_starknet_version.unwrap(), StarknetVersion::default()); + + let block_2_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(2)).unwrap(); + assert_eq!(block_2_starknet_version.unwrap(), second_version); + + let block_3_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(3)).unwrap(); + assert_eq!(block_3_starknet_version.unwrap(), second_version); + + let block_4_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(4)).unwrap(); + assert_eq!(block_4_starknet_version.unwrap(), yet_another_version); + + let block_5_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(5)).unwrap(); + assert_eq!(block_5_starknet_version.unwrap(), yet_another_version); + + let block_6_starknet_version = + reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(6)).unwrap(); + assert!(block_6_starknet_version.is_none()); +} diff --git a/crates/papyrus_storage/src/lib.rs b/crates/papyrus_storage/src/lib.rs index d4c4c70238..8604e1697c 100644 --- a/crates/papyrus_storage/src/lib.rs +++ b/crates/papyrus_storage/src/lib.rs @@ -1,5 +1,5 @@ #![warn(missing_docs)] -//! A storage implementation for a [`Starknet`] node. +//! A storage implementation for a [`Starknet`] full-node. //! //! This crate provides a writing and reading interface for various Starknet data structures to a //! database. Enables at most one writing operation and multiple reading operations concurrently. @@ -17,7 +17,7 @@ //! ``` //! use papyrus_storage::open_storage; //! use papyrus_storage::db::DbConfig; -//! use papyrus_storage::header::{HeaderStorageReader, HeaderStorageWriter}; // Import the header API. +//! use papyrus_storage::header::{HeaderStorageReader, HeaderStorageWriter, StarknetVersion}; // Import the header API. //! use starknet_api::block::{BlockHeader, BlockNumber}; //! use starknet_api::core::ChainId; //! @@ -88,6 +88,7 @@ use crate::db::{ open_env, DbConfig, DbError, DbReader, DbTransaction, DbWriter, TableHandle, TableIdentifier, TransactionKind, RO, RW, }; +use crate::header::StarknetVersion; use crate::state::data::IndexedDeprecatedContractClass; use crate::version::{VersionStorageReader, VersionStorageWriter}; @@ -124,6 +125,7 @@ pub fn open_storage(db_config: DbConfig) -> StorageResult<(StorageReader, Storag transaction_hash_to_idx: db_writer.create_table("transaction_hash_to_idx")?, transaction_outputs: db_writer.create_table("transaction_outputs")?, transactions: db_writer.create_table("transactions")?, + starknet_version: db_writer.create_table("starknet_version")?, storage_version: db_writer.create_table("storage_version")?, }); let reader = StorageReader { db_reader, tables: tables.clone() }; @@ -248,6 +250,7 @@ struct_field_names! { transaction_hash_to_idx: TableIdentifier, transaction_outputs: TableIdentifier, transactions: TableIdentifier, + starknet_version: TableIdentifier, storage_version: TableIdentifier } } diff --git a/crates/papyrus_storage/src/serializers.rs b/crates/papyrus_storage/src/serializers.rs index 5d5c749086..3d7a615d1f 100644 --- a/crates/papyrus_storage/src/serializers.rs +++ b/crates/papyrus_storage/src/serializers.rs @@ -56,6 +56,7 @@ use crate::compression_utils::{ compress, decompress, decompress_from_reader, serialize_and_compress, }; use crate::db::serialization::{StorageSerde, StorageSerdeError}; +use crate::header::StarknetVersion; use crate::ommer::{OmmerEventKey, OmmerTransactionKey}; #[cfg(test)] use crate::serializers::serializers_test::{create_storage_serde_test, StorageSerdeTest}; @@ -120,7 +121,6 @@ auto_storage_serde! { pub signature: TransactionSignature, pub nonce: Nonce, pub class_hash: ClassHash, - pub contract_address: ContractAddress, pub contract_address_salt: ContractAddressSalt, pub constructor_calldata: Calldata, } @@ -128,7 +128,6 @@ auto_storage_serde! { pub transaction_hash: TransactionHash, pub version: TransactionVersion, pub class_hash: ClassHash, - pub contract_address: ContractAddress, pub contract_address_salt: ContractAddressSalt, pub constructor_calldata: Calldata, } @@ -252,6 +251,7 @@ auto_storage_serde! { pub param: TypedParameter, pub offset: usize, } + pub struct StarknetVersion(pub String); pub struct ThinDeclareTransactionOutput { pub actual_fee: Fee, pub messages_sent: Vec, @@ -261,11 +261,13 @@ auto_storage_serde! { pub actual_fee: Fee, pub messages_sent: Vec, pub events_contract_addresses: Vec, + pub contract_address: ContractAddress, } pub struct ThinDeployAccountTransactionOutput { pub actual_fee: Fee, pub messages_sent: Vec, pub events_contract_addresses: Vec, + pub contract_address: ContractAddress, } pub struct TypedParameter { pub name: String, @@ -823,6 +825,3 @@ impl StorageSerde for CasmContractClass { }) } } - -#[cfg(test)] -create_storage_serde_test!(CasmContractClass); diff --git a/crates/papyrus_storage/src/snapshots/papyrus_storage__serializers__serializers_test__hint_modified.snap b/crates/papyrus_storage/src/snapshots/papyrus_storage__serializers__serializers_test__hint_modified.snap index 85686310a3..c2395d3b8b 100644 --- a/crates/papyrus_storage/src/snapshots/papyrus_storage__serializers__serializers_test__hint_modified.snap +++ b/crates/papyrus_storage/src/snapshots/papyrus_storage__serializers__serializers_test__hint_modified.snap @@ -102,7 +102,7 @@ definitions: remainder: $ref: "#/definitions/CellRef" additionalProperties: false - - description: "Divides dividend_low<<128+dividend_high by divisor_low<<128+divisor_high. Splits the remainder to 128bit words: remainder_low and remainder_high. Splits the quotient and the divisor to 128bit words. The lower 128 bits of the quotient are written to quotient0 and quotient1. The lower 128 bits of the divisor are written to divisor0 and divisor1. If the divisor is greater than 2^128, the upper 128 bits of the divisor are written to extra0 and extra1. In this case, quotient must be lower than 2^128. Otherwise, the upper 128 bits of the quotient are written to extra0 and extra1." + - description: "Divides dividend (represented by 2 128bit limbs) by divisor (represented by 2 128bit limbs). Returns the quotient (represented by 2 128bit limbs) and remainder (represented by 2 128bit limbs). In all cases - `name`0 is the least significant limb." type: object required: - Uint256DivMod @@ -110,42 +110,30 @@ definitions: Uint256DivMod: type: object required: - - dividend_high - - dividend_low + - dividend0 + - dividend1 - divisor0 - divisor1 - - divisor_high - - divisor_low - - extra0 - - extra1 - quotient0 - quotient1 - - remainder_high - - remainder_low + - remainder0 + - remainder1 properties: - dividend_low: + dividend0: $ref: "#/definitions/ResOperand" - dividend_high: + dividend1: $ref: "#/definitions/ResOperand" - divisor_low: + divisor0: $ref: "#/definitions/ResOperand" - divisor_high: + divisor1: $ref: "#/definitions/ResOperand" quotient0: $ref: "#/definitions/CellRef" quotient1: $ref: "#/definitions/CellRef" - divisor0: - $ref: "#/definitions/CellRef" - divisor1: - $ref: "#/definitions/CellRef" - extra0: - $ref: "#/definitions/CellRef" - extra1: - $ref: "#/definitions/CellRef" - remainder_low: + remainder0: $ref: "#/definitions/CellRef" - remainder_high: + remainder1: $ref: "#/definitions/CellRef" additionalProperties: false - description: "Divides dividend (represented by 4 128bit limbs) by divisor (represented by 2 128bit limbs). Returns the quotient (represented by 4 128bit limbs) and remainder (represented by 2 128bit limbs). In all cases - `name`0 is the least significant limb." diff --git a/crates/papyrus_storage/src/test_instances.rs b/crates/papyrus_storage/src/test_instances.rs index 01a31196da..4fe49522b1 100644 --- a/crates/papyrus_storage/src/test_instances.rs +++ b/crates/papyrus_storage/src/test_instances.rs @@ -11,6 +11,7 @@ use crate::body::events::{ ThinInvokeTransactionOutput, ThinL1HandlerTransactionOutput, ThinTransactionOutput, }; use crate::body::TransactionIndex; +use crate::header::StarknetVersion; use crate::state::data::IndexedDeprecatedContractClass; use crate::version::Version; use crate::{EventIndex, MarkerKind, OmmerEventKey, OmmerTransactionKey}; @@ -29,6 +30,7 @@ auto_impl_get_test_instance! { } struct OmmerTransactionKey(pub BlockHash, pub TransactionOffsetInBlock); struct OmmerEventKey(pub OmmerTransactionKey, pub EventIndexInTransactionOutput); + pub struct StarknetVersion(pub String); pub struct ThinDeclareTransactionOutput { pub actual_fee: Fee, pub messages_sent: Vec, @@ -38,11 +40,13 @@ auto_impl_get_test_instance! { pub actual_fee: Fee, pub messages_sent: Vec, pub events_contract_addresses: Vec, + pub contract_address: ContractAddress, } pub struct ThinDeployAccountTransactionOutput { pub actual_fee: Fee, pub messages_sent: Vec, pub events_contract_addresses: Vec, + pub contract_address: ContractAddress, } pub struct ThinInvokeTransactionOutput { pub actual_fee: Fee, diff --git a/crates/papyrus_sync/Cargo.toml b/crates/papyrus_sync/Cargo.toml index 4b8eae4d36..d5d8a6b312 100644 --- a/crates/papyrus_sync/Cargo.toml +++ b/crates/papyrus_sync/Cargo.toml @@ -15,7 +15,7 @@ futures.workspace = true hex.workspace = true indexmap = { workspace = true, features = ["serde"] } libmdbx = { workspace = true, features = ["lifetimed-bytes"] } -papyrus_storage = { path = "../papyrus_storage" } +papyrus_storage = { path = "../papyrus_storage", version = "0.0.1" } reqwest = { workspace = true, features = ["json", "blocking"] } serde = { workspace = true, features = ["derive"] } serde_json.workspace = true diff --git a/crates/papyrus_sync/src/lib.rs b/crates/papyrus_sync/src/lib.rs index ab3ee641c9..475927c6a7 100644 --- a/crates/papyrus_sync/src/lib.rs +++ b/crates/papyrus_sync/src/lib.rs @@ -14,7 +14,7 @@ use futures_util::{pin_mut, select, Stream, StreamExt}; use indexmap::IndexMap; use papyrus_storage::body::BodyStorageWriter; use papyrus_storage::compiled_class::{CasmStorageReader, CasmStorageWriter}; -use papyrus_storage::header::{HeaderStorageReader, HeaderStorageWriter}; +use papyrus_storage::header::{HeaderStorageReader, HeaderStorageWriter, StarknetVersion}; use papyrus_storage::ommer::{OmmerStorageReader, OmmerStorageWriter}; use papyrus_storage::state::{StateStorageReader, StateStorageWriter}; use papyrus_storage::{StorageError, StorageReader, StorageWriter}; @@ -72,6 +72,7 @@ pub enum SyncEvent { BlockAvailable { block_number: BlockNumber, block: Block, + starknet_version: StarknetVersion, }, StateDiffAvailable { block_number: BlockNumber, @@ -191,8 +192,8 @@ impl GenericStateSyn // Tries to store the incoming data. async fn process_sync_event(&mut self, sync_event: SyncEvent) -> StateSyncResult { match sync_event { - SyncEvent::BlockAvailable { block_number, block } => { - self.store_block(block_number, block) + SyncEvent::BlockAvailable { block_number, block, starknet_version } => { + self.store_block(block_number, block, &starknet_version) } SyncEvent::StateDiffAvailable { block_number, @@ -214,7 +215,12 @@ impl GenericStateSyn } #[instrument(skip(self, block), level = "debug", fields(block_hash = %block.header.block_hash), err)] - fn store_block(&mut self, block_number: BlockNumber, block: Block) -> StateSyncResult { + fn store_block( + &mut self, + block_number: BlockNumber, + block: Block, + starknet_version: &StarknetVersion, + ) -> StateSyncResult { // Assuming the central source is trusted, detect reverts by comparing the incoming block's // parent hash to the current hash. self.verify_parent_block_hash(block_number, &block)?; @@ -224,6 +230,7 @@ impl GenericStateSyn self.writer .begin_rw_txn()? .append_header(block_number, &block.header)? + .update_starknet_version(&block_number, starknet_version)? .append_body(block_number, block.body)? .commit()?; Ok(()) @@ -447,8 +454,8 @@ fn stream_new_blocks( central_source.stream_new_blocks(header_marker, up_to).fuse(); pin_mut!(block_stream); while let Some(maybe_block) = block_stream.next().await { - let (block_number, block) = maybe_block?; - yield SyncEvent::BlockAvailable { block_number, block }; + let (block_number, block, starknet_version) = maybe_block?; + yield SyncEvent::BlockAvailable { block_number, block , starknet_version}; } } } diff --git a/crates/papyrus_sync/src/sources/central.rs b/crates/papyrus_sync/src/sources/central.rs index b975905720..4b91829973 100644 --- a/crates/papyrus_sync/src/sources/central.rs +++ b/crates/papyrus_sync/src/sources/central.rs @@ -11,6 +11,7 @@ use futures_util::StreamExt; use indexmap::IndexMap; #[cfg(test)] use mockall::automock; +use papyrus_storage::header::StarknetVersion; use papyrus_storage::state::StateStorageReader; use papyrus_storage::{StorageError, StorageReader}; use serde::{Deserialize, Serialize}; @@ -123,7 +124,8 @@ pub trait CentralSourceTrait { ) -> CompiledClassesStream<'_>; } -pub(crate) type BlocksStream<'a> = BoxStream<'a, Result<(BlockNumber, Block), CentralError>>; +pub(crate) type BlocksStream<'a> = + BoxStream<'a, Result<(BlockNumber, Block, StarknetVersion), CentralError>>; type CentralStateUpdate = (BlockNumber, BlockHash, StateDiff, IndexMap); pub(crate) type StateUpdatesStream<'a> = BoxStream<'a, CentralResult>; @@ -187,8 +189,8 @@ impl CentralSource let maybe_central_block = client_to_central_block(current_block_number, maybe_client_block); match maybe_central_block { - Ok(block) => { - yield Ok((current_block_number, block)); + Ok(block_and_version) => { + yield Ok((current_block_number, block_and_version.0, block_and_version.1)); } Err(err) => { yield (Err(err)); @@ -265,18 +267,20 @@ impl CentralSource fn client_to_central_block( current_block_number: BlockNumber, maybe_client_block: Result, ClientError>, -) -> CentralResult { +) -> CentralResult<(Block, StarknetVersion)> { let res = match maybe_client_block { Ok(Some(block)) => { debug!("Received new block {current_block_number} with hash {}.", block.block_hash); trace!("Block: {block:#?}."); - Block::try_from(block).map_err(|err| CentralError::ClientError(Arc::new(err))) + Ok(block + .to_starknet_api_block_and_version() + .map_err(|err| CentralError::ClientError(Arc::new(err)))?) } Ok(None) => Err(CentralError::BlockNotFound { block_number: current_block_number }), Err(err) => Err(CentralError::ClientError(Arc::new(err))), }; match res { - Ok(block) => Ok(block), + Ok((block, version_string)) => Ok((block, StarknetVersion(version_string))), Err(err) => { debug!("Received error for block {}: {:?}.", current_block_number, err); Err(err) diff --git a/crates/papyrus_sync/src/sources/central_sync_test.rs b/crates/papyrus_sync/src/sources/central_sync_test.rs index bd2bed9c93..590e0f380d 100644 --- a/crates/papyrus_sync/src/sources/central_sync_test.rs +++ b/crates/papyrus_sync/src/sources/central_sync_test.rs @@ -6,7 +6,7 @@ use async_stream::stream; use async_trait::async_trait; use futures::StreamExt; use indexmap::IndexMap; -use papyrus_storage::header::HeaderStorageReader; +use papyrus_storage::header::{HeaderStorageReader, StarknetVersion}; use papyrus_storage::state::StateStorageReader; use papyrus_storage::test_utils::get_test_storage; use papyrus_storage::{StorageError, StorageReader, StorageWriter}; @@ -27,6 +27,7 @@ const SYNC_SLEEP_DURATION: Duration = Duration::from_millis(100); // 100ms const DURATION_BEFORE_CHECKING_STORAGE: Duration = SYNC_SLEEP_DURATION.saturating_mul(2); // 200ms twice the sleep duration of the sync loop. const MAX_CHECK_STORAGE_ITERATIONS: u8 = 3; const STREAM_SIZE: u32 = 1000; +const STARKNET_VERSION: &str = "starknet_version"; enum CheckStoragePredicateResult { InProgress, @@ -134,7 +135,7 @@ async fn sync_happy_flow() { parent_hash: create_block_hash(block_number.prev().unwrap_or_default(), false), ..BlockHeader::default() }; - yield Ok((block_number, Block { header, body: BlockBody::default() })); + yield Ok((block_number, Block { header, body: BlockBody::default() }, StarknetVersion(STARKNET_VERSION.to_string()))); } } .boxed(); @@ -378,7 +379,7 @@ async fn sync_with_revert() { block_hash: create_block_hash(i, false), parent_hash: create_block_hash(i.prev().unwrap_or_default(), false), ..BlockHeader::default()}; - yield Ok((i,Block{header, body: BlockBody::default()})); + yield Ok((i,Block{header, body: BlockBody::default()}, StarknetVersion(STARKNET_VERSION.to_string()))); } } .boxed(), @@ -392,7 +393,7 @@ async fn sync_with_revert() { block_hash: create_block_hash(i, i.0 >= CHAIN_FORK_BLOCK_NUMBER), parent_hash: create_block_hash(i.prev().unwrap_or_default(), i.0 > CHAIN_FORK_BLOCK_NUMBER), ..BlockHeader::default()}; - yield Ok((i, Block{header, body: BlockBody::default()})); + yield Ok((i, Block{header, body: BlockBody::default()}, StarknetVersion(STARKNET_VERSION.to_string()))); } } .boxed(), @@ -467,7 +468,11 @@ async fn test_unrecoverable_sync_error_flow() { parent_hash: create_block_hash(BLOCK_NUMBER.prev().unwrap_or_default(), false), ..BlockHeader::default() }; - yield Ok((BLOCK_NUMBER, Block { header, body: BlockBody::default() })); + yield Ok(( + BLOCK_NUMBER, + Block { header, body: BlockBody::default()}, + StarknetVersion(STARKNET_VERSION.to_string()), + )); } .boxed(); blocks_stream diff --git a/crates/papyrus_sync/src/sources/central_test.rs b/crates/papyrus_sync/src/sources/central_test.rs index b237086f7c..d4fd6f37dd 100644 --- a/crates/papyrus_sync/src/sources/central_test.rs +++ b/crates/papyrus_sync/src/sources/central_test.rs @@ -69,7 +69,7 @@ async fn stream_block_headers() { let stream = central_source.stream_new_blocks(expected_block_num, BlockNumber(END_BLOCK_NUMBER)); pin_mut!(stream); - while let Some(Ok((block_number, _block))) = stream.next().await { + while let Some(Ok((block_number, _block, _starknet_version))) = stream.next().await { assert_eq!(expected_block_num, block_number); expected_block_num = expected_block_num.next(); } diff --git a/crates/starknet_reader_client/src/lib.rs b/crates/starknet_reader_client/src/lib.rs index 44fc6c3415..3f1734e1ba 100644 --- a/crates/starknet_reader_client/src/lib.rs +++ b/crates/starknet_reader_client/src/lib.rs @@ -1,6 +1,9 @@ -//! Client implementation for [`starknet`] feeder gateway. +//! Client implementation for the [`Starknet`] feeder gateway. //! -//! [`starknet`]: https://starknet.io/ +//! This client can read data from [`Starknet`] about the current state +//! (e.g accepted blocks, contracts, classes). +//! +//! [`Starknet`]: https://starknet.io/ mod objects; pub mod retry; diff --git a/crates/starknet_reader_client/src/objects/block.rs b/crates/starknet_reader_client/src/objects/block.rs index e50441f02f..14a7e9e798 100644 --- a/crates/starknet_reader_client/src/objects/block.rs +++ b/crates/starknet_reader_client/src/objects/block.rs @@ -1,9 +1,9 @@ use std::ops::Index; use serde::{Deserialize, Serialize}; -#[cfg(doc)] -use starknet_api::block::Block as starknet_api_block; -use starknet_api::block::{BlockHash, BlockNumber, BlockTimestamp, GasPrice}; +use starknet_api::block::{ + Block as starknet_api_block, BlockHash, BlockNumber, BlockTimestamp, GasPrice, +}; use starknet_api::core::ContractAddress; use starknet_api::hash::StarkHash; use starknet_api::serde_utils::NonPrefixedBytesAsHex; @@ -39,6 +39,7 @@ impl From for starknet_api::core::GlobalRoot { /// A block as returned by the starknet gateway. #[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)] +#[serde(deny_unknown_fields)] pub struct Block { pub block_hash: BlockHash, pub block_number: BlockNumber, @@ -52,6 +53,9 @@ pub struct Block { pub timestamp: BlockTimestamp, pub transactions: Vec, pub transaction_receipts: Vec, + // Default since old blocks don't include this field. + #[serde(default)] + pub starknet_version: String, } /// Errors that might be encountered while converting the client representation of a [`Block`] to a @@ -111,18 +115,18 @@ pub enum TransactionReceiptsError { }, } -/// Converts the client representation of [`Block`] to a [`starknet_api`][`Block`]. -impl TryFrom for starknet_api::block::Block { - type Error = ClientError; - - fn try_from(block: Block) -> ClientResult { +/// Converts the client representation of [`Block`] to a tuple of a starknet_api +/// [Block](`starknet_api_block`) and String representing the Starknet version corresponding to +/// that block. +impl Block { + pub fn to_starknet_api_block_and_version(self) -> ClientResult<(starknet_api_block, String)> { // Check that the number of receipts is the same as the number of transactions. - let num_of_txs = block.transactions.len(); - let num_of_receipts = block.transaction_receipts.len(); + let num_of_txs = self.transactions.len(); + let num_of_receipts = self.transaction_receipts.len(); if num_of_txs != num_of_receipts { return Err(ClientError::TransactionReceiptsError( TransactionReceiptsError::WrongNumberOfReceipts { - block_number: block.block_number, + block_number: self.block_number, num_of_txs, num_of_receipts, }, @@ -131,15 +135,15 @@ impl TryFrom for starknet_api::block::Block { // Get the transaction outputs. let mut transaction_outputs = vec![]; - for (i, receipt) in block.transaction_receipts.into_iter().enumerate() { - let transaction = block.transactions.index(i); + for (i, receipt) in self.transaction_receipts.into_iter().enumerate() { + let transaction = self.transactions.index(i); // Check that the transaction index that appears in the receipt is the same as the // index of the transaction. if i != receipt.transaction_index.0 { return Err(ClientError::TransactionReceiptsError( TransactionReceiptsError::MismatchTransactionIndex { - block_number: block.block_number, + block_number: self.block_number, tx_index: TransactionOffsetInBlock(i), tx_hash: transaction.transaction_hash(), receipt_tx_index: receipt.transaction_index, @@ -152,7 +156,7 @@ impl TryFrom for starknet_api::block::Block { if transaction.transaction_hash() != receipt.transaction_hash { return Err(ClientError::TransactionReceiptsError( TransactionReceiptsError::MismatchTransactionHash { - block_number: block.block_number, + block_number: self.block_number, tx_index: TransactionOffsetInBlock(i), tx_hash: transaction.transaction_hash(), receipt_tx_hash: receipt.transaction_hash, @@ -166,7 +170,7 @@ impl TryFrom for starknet_api::block::Block { { return Err(ClientError::TransactionReceiptsError( TransactionReceiptsError::MismatchFields { - block_number: block.block_number, + block_number: self.block_number, tx_index: TransactionOffsetInBlock(i), tx_hash: transaction.transaction_hash(), tx_type: transaction.transaction_type(), @@ -174,8 +178,7 @@ impl TryFrom for starknet_api::block::Block { )); } - let tx_output = - receipt.into_starknet_api_transaction_output(transaction.transaction_type()); + let tx_output = receipt.into_starknet_api_transaction_output(transaction); transaction_outputs.push(tx_output); } @@ -183,7 +186,7 @@ impl TryFrom for starknet_api::block::Block { // Note: This cannot happen before getting the transaction outputs since we need to borrow // the block transactions inside the for loop for the transaction type (TransactionType is // defined in starknet_client therefore starknet_api::Transaction cannot return it). - let transactions: Vec<_> = block + let transactions: Vec<_> = self .transactions .into_iter() .map(starknet_api::transaction::Transaction::try_from) @@ -191,18 +194,18 @@ impl TryFrom for starknet_api::block::Block { // Get the header. let header = starknet_api::block::BlockHeader { - block_hash: block.block_hash, - parent_hash: block.parent_block_hash, - block_number: block.block_number, - gas_price: block.gas_price, - state_root: block.state_root.into(), - sequencer: block.sequencer_address, - timestamp: block.timestamp, + block_hash: self.block_hash, + parent_hash: self.parent_block_hash, + block_number: self.block_number, + gas_price: self.gas_price, + state_root: self.state_root.into(), + sequencer: self.sequencer_address, + timestamp: self.timestamp, }; let body = starknet_api::block::BlockBody { transactions, transaction_outputs }; - Ok(Self { header, body }) + Ok((starknet_api_block { header, body }, self.starknet_version)) } } diff --git a/crates/starknet_reader_client/src/objects/block_test.rs b/crates/starknet_reader_client/src/objects/block_test.rs index 496fc7a0f8..4d2c7ea4e6 100644 --- a/crates/starknet_reader_client/src/objects/block_test.rs +++ b/crates/starknet_reader_client/src/objects/block_test.rs @@ -105,16 +105,16 @@ fn load_block_state_update_succeeds() { } #[tokio::test] -async fn try_into_starknet_api() { +async fn to_starknet_api_block_and_version() { let raw_block = read_resource_file("block.json"); let block: Block = serde_json::from_str(&raw_block).unwrap(); let expected_num_of_tx_outputs = block.transactions.len(); - let starknet_api_block = starknet_api::block::Block::try_from(block).unwrap(); + let (starknet_api_block, _version) = block.to_starknet_api_block_and_version().unwrap(); assert_eq!(expected_num_of_tx_outputs, starknet_api_block.body.transaction_outputs.len()); let mut err_block: Block = serde_json::from_str(&raw_block).unwrap(); err_block.transaction_receipts.pop(); - let err = starknet_api::block::Block::try_from(err_block).unwrap_err(); + let err = err_block.to_starknet_api_block_and_version().unwrap_err(); assert_matches!( err, ClientError::TransactionReceiptsError(TransactionReceiptsError::WrongNumberOfReceipts { @@ -126,7 +126,7 @@ async fn try_into_starknet_api() { let mut err_block: Block = serde_json::from_str(&raw_block).unwrap(); err_block.transaction_receipts[0].transaction_index = TransactionOffsetInBlock(1); - let err = starknet_api::block::Block::try_from(err_block).unwrap_err(); + let err = err_block.to_starknet_api_block_and_version().unwrap_err(); assert_matches!( err, ClientError::TransactionReceiptsError(TransactionReceiptsError::MismatchTransactionIndex { @@ -139,7 +139,7 @@ async fn try_into_starknet_api() { let mut err_block: Block = serde_json::from_str(&raw_block).unwrap(); err_block.transaction_receipts[0].transaction_hash = TransactionHash(stark_felt!("0x4")); - let err = starknet_api::block::Block::try_from(err_block).unwrap_err(); + let err = err_block.to_starknet_api_block_and_version().unwrap_err(); assert_matches!( err, ClientError::TransactionReceiptsError(TransactionReceiptsError::MismatchTransactionHash { @@ -156,7 +156,7 @@ async fn try_into_starknet_api() { transaction_hash: err_block.transactions[0].transaction_hash(), ..err_block.transaction_receipts[4].clone() }; - let err = starknet_api::block::Block::try_from(err_block).unwrap_err(); + let err = err_block.to_starknet_api_block_and_version().unwrap_err(); assert_matches!( err, ClientError::TransactionReceiptsError(TransactionReceiptsError::MismatchFields { diff --git a/crates/starknet_reader_client/src/objects/transaction.rs b/crates/starknet_reader_client/src/objects/transaction.rs index 14f1dbc131..f4b8e130f9 100644 --- a/crates/starknet_reader_client/src/objects/transaction.rs +++ b/crates/starknet_reader_client/src/objects/transaction.rs @@ -80,6 +80,14 @@ impl Transaction { Transaction::L1Handler(_) => TransactionType::L1Handler, } } + + pub fn contract_address(&self) -> Option { + match self { + Transaction::Deploy(tx) => Some(tx.contract_address), + Transaction::DeployAccount(tx) => Some(tx.contract_address), + _ => None, + } + } } #[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] @@ -187,7 +195,6 @@ impl From for starknet_api::transaction::DeployTransaction { starknet_api::transaction::DeployTransaction { transaction_hash: deploy_tx.transaction_hash, version: deploy_tx.version, - contract_address: deploy_tx.contract_address, constructor_calldata: deploy_tx.constructor_calldata, class_hash: deploy_tx.class_hash, contract_address_salt: deploy_tx.contract_address_salt, @@ -215,7 +222,6 @@ impl From for starknet_api::transaction::DeployAccount starknet_api::transaction::DeployAccountTransaction { transaction_hash: deploy_tx.transaction_hash, version: deploy_tx.version, - contract_address: deploy_tx.contract_address, constructor_calldata: deploy_tx.constructor_calldata, class_hash: deploy_tx.class_hash, contract_address_salt: deploy_tx.contract_address_salt, @@ -313,10 +319,11 @@ pub struct TransactionReceipt { impl TransactionReceipt { pub fn into_starknet_api_transaction_output( self, - tx_type: TransactionType, + transaction: &Transaction, ) -> TransactionOutput { let messages_sent = self.l2_to_l1_messages.into_iter().map(MessageToL1::from).collect(); - match tx_type { + let contract_address = transaction.contract_address(); + match transaction.transaction_type() { TransactionType::Declare => TransactionOutput::Declare(DeclareTransactionOutput { actual_fee: self.actual_fee, messages_sent, @@ -326,12 +333,16 @@ impl TransactionReceipt { actual_fee: self.actual_fee, messages_sent, events: self.events, + contract_address: contract_address + .expect("Deploy transaction must have a contract address."), }), TransactionType::DeployAccount => { TransactionOutput::DeployAccount(DeployAccountTransactionOutput { actual_fee: self.actual_fee, messages_sent, events: self.events, + contract_address: contract_address + .expect("Deploy account transaction must have a contract address."), }) } TransactionType::InvokeFunction => TransactionOutput::Invoke(InvokeTransactionOutput { diff --git a/crates/starknet_writer_client/src/lib.rs b/crates/starknet_writer_client/src/lib.rs index 270d80e649..06a0bb9135 100644 --- a/crates/starknet_writer_client/src/lib.rs +++ b/crates/starknet_writer_client/src/lib.rs @@ -1,5 +1,7 @@ -//! Client implementation for [`starknet`] gateway. +//! Client implementation for the [`Starknet`] gateway. //! -//! [`starknet`]: https://starknet.io/ +//! This client can make changes to [`Starknet`] by adding transactions to the next block. +//! +//! [`Starknet`]: https://starknet.io/ pub mod objects; diff --git a/crates/starknet_writer_client/src/objects/transaction.rs b/crates/starknet_writer_client/src/objects/transaction.rs index 199577adba..b661e8626c 100644 --- a/crates/starknet_writer_client/src/objects/transaction.rs +++ b/crates/starknet_writer_client/src/objects/transaction.rs @@ -1,3 +1,11 @@ +//! This module contains all the different transactions that can be added to [`Starknet`] via the +//! gateway. +//! +//! Each transaction can be serialized into a JSON object that the gateway can receive through the +//! `add_transaction` HTTP method. +//! +//! [`Starknet`]: https://starknet.io/ + use std::collections::HashMap; use serde::{Deserialize, Serialize}; @@ -11,6 +19,9 @@ use starknet_api::transaction::{ Calldata, ContractAddressSalt, Fee, TransactionSignature, TransactionVersion, }; +/// A generic transaction that can be added to Starknet. When the transaction is serialized into a +/// JSON object, it must be in the format that the Starknet gateway expects in the +/// `add_transaction` HTTP method. #[derive(Debug, Deserialize, Serialize, Clone, Eq, PartialEq)] #[serde(tag = "type")] pub enum Transaction { @@ -24,6 +35,7 @@ pub enum Transaction { DeclareV2(DeclareV2Transaction), } +/// A deploy account transaction that can be added to Starknet through the Starknet gateway. #[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)] #[serde(deny_unknown_fields)] pub struct DeployAccountTransaction { @@ -33,22 +45,24 @@ pub struct DeployAccountTransaction { pub nonce: Nonce, pub max_fee: Fee, pub signature: TransactionSignature, - #[serde(default)] pub version: TransactionVersion, } +/// An invoke account transaction that can be added to Starknet through the Starknet gateway. +/// The invoke is a V1 transaction. #[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)] #[serde(deny_unknown_fields)] pub struct InvokeTransaction { pub calldata: Calldata, pub sender_address: ContractAddress, - #[serde(default)] pub nonce: Nonce, pub max_fee: Fee, pub signature: TransactionSignature, pub version: TransactionVersion, } +/// A declare transaction of a Cairo-v0 (deprecated) contract class that can be added to Starknet +/// through the Starknet gateway. #[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)] #[serde(deny_unknown_fields)] pub struct DeclareV1Transaction { @@ -60,6 +74,8 @@ pub struct DeclareV1Transaction { pub signature: TransactionSignature, } +/// A declare transaction of a Cairo-v1 contract class that can be added to Starknet through the +/// Starknet gateway. #[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)] #[serde(deny_unknown_fields)] pub struct DeclareV2Transaction { @@ -72,8 +88,8 @@ pub struct DeclareV2Transaction { pub signature: TransactionSignature, } -// The only difference between this and ContractClass in starknet_api (in the -// deprecated_contract_class module) is in the program. +// The structs that are implemented here are the structs that have deviations from starknet_api. + #[derive(Debug, Clone, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct DeprecatedContractClass { #[serde(skip_serializing_if = "Option::is_none")] @@ -85,8 +101,6 @@ pub struct DeprecatedContractClass { pub entry_points_by_type: HashMap>, } -// The only difference between this and ContractClass in starknet_api is in the sierra_program and -// in the version. #[derive(Debug, Clone, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct ContractClass { // TODO(shahak): Create a struct for a compressed base64 value. @@ -97,9 +111,6 @@ pub struct ContractClass { pub abi: String, } -// The differences between this and ContractClassAbiEntry in starknet_api are: -// 1. This enum is tagged. -// 2. There are variants for Constructor and L1Handler. #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] #[serde(deny_unknown_fields)] #[serde(tag = "type")] diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index cbcce54012..e9b84b25fc 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -355,7 +355,6 @@ auto_impl_get_test_instance! { pub signature: TransactionSignature, pub nonce: Nonce, pub class_hash: ClassHash, - pub contract_address: ContractAddress, pub contract_address_salt: ContractAddressSalt, pub constructor_calldata: Calldata, } @@ -363,7 +362,6 @@ auto_impl_get_test_instance! { pub transaction_hash: TransactionHash, pub version: TransactionVersion, pub class_hash: ClassHash, - pub contract_address: ContractAddress, pub contract_address_salt: ContractAddressSalt, pub constructor_calldata: Calldata, }