diff --git a/.gitignore b/.gitignore index c7ee5414c6..59de33725e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ # These are backup files generated by rustfmt **/*.rs.bk +# Rust compiler error files +rustc-ice-*.txt + .DS_Store # The cache for docker container dependency diff --git a/CHANGELOG.md b/CHANGELOG.md index 42da5aba7a..86c5387929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ## Next release -- fix: Change seliazation of bitvec to &[u8] in merkle tree to avoid memory +- feat(rpc): Added starknet_simulateTransactions +- fix: Change serialization of bitvec to &[u8] in merkle tree to avoid memory uninitialized - chore: change SCARB config version for foundry CI diff --git a/Cargo.lock b/Cargo.lock index 3c0799d986..0bd07c4e24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,25 +36,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aead" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" -dependencies = [ - "generic-array 0.14.7", -] - -[[package]] -name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" -dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", -] - [[package]] name = "aead" version = "0.5.2" @@ -65,29 +46,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "aes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" -dependencies = [ - "aes-soft", - "aesni", - "cipher 0.2.5", -] - -[[package]] -name = "aes" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" -dependencies = [ - "cfg-if", - "cipher 0.3.0", - "cpufeatures", - "opaque-debug 0.3.0", -] - [[package]] name = "aes" version = "0.8.3" @@ -99,52 +57,18 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "aes-gcm" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" -dependencies = [ - "aead 0.4.3", - "aes 0.7.5", - "cipher 0.3.0", - "ctr 0.8.0", - "ghash 0.4.4", - "subtle 2.4.1", -] - [[package]] name = "aes-gcm" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ - "aead 0.5.2", - "aes 0.8.3", + "aead", + "aes", "cipher 0.4.4", - "ctr 0.9.2", - "ghash 0.5.0", - "subtle 2.4.1", -] - -[[package]] -name = "aes-soft" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" -dependencies = [ - "cipher 0.2.5", - "opaque-debug 0.3.0", -] - -[[package]] -name = "aesni" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" -dependencies = [ - "cipher 0.2.5", - "opaque-debug 0.3.0", + "ctr", + "ghash", + "subtle 2.5.0", ] [[package]] @@ -298,12 +222,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "arc-swap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" - [[package]] name = "ark-bls12-377" version = "0.4.0" @@ -566,9 +484,9 @@ checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" [[package]] name = "array-bytes" -version = "6.2.0" +version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de17a919934ad8c5cc99a1a74de4e2dab95d6121a8f27f94755ff525b630382c" +checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" [[package]] name = "array-init" @@ -606,29 +524,13 @@ dependencies = [ "term", ] -[[package]] -name = "asn1-rs" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ff05a702273012438132f449575dbc804e27b2f3cbe3069aa237d26c98fa33" -dependencies = [ - "asn1-rs-derive 0.1.0", - "asn1-rs-impl", - "displaydoc", - "nom", - "num-traits 0.2.17", - "rusticata-macros", - "thiserror", - "time", -] - [[package]] name = "asn1-rs" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ - "asn1-rs-derive 0.4.0", + "asn1-rs-derive", "asn1-rs-impl", "displaydoc", "nom", @@ -638,18 +540,6 @@ dependencies = [ "time", ] -[[package]] -name = "asn1-rs-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure", -] - [[package]] name = "asn1-rs-derive" version = "0.4.0" @@ -764,12 +654,6 @@ dependencies = [ "pin-project-lite 0.2.13", ] -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "atty" version = "0.2.14" @@ -864,12 +748,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - [[package]] name = "base16ct" version = "0.2.0" @@ -1066,7 +944,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding 0.1.5", + "block-padding", "byte-tools", "byteorder", "generic-array 0.12.4", @@ -1090,16 +968,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-modes" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" -dependencies = [ - "block-padding 0.2.1", - "cipher 0.2.5", -] - [[package]] name = "block-padding" version = "0.1.5" @@ -1109,12 +977,6 @@ dependencies = [ "byte-tools", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "blockifier" version = "0.1.0-rc2" @@ -1821,17 +1683,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ccm" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca1a8fbc20b50ac9673ff014abfb2b5f4085ee1a850d408f14a159c5853ac7" -dependencies = [ - "aead 0.3.2", - "cipher 0.2.5", - "subtle 2.4.1", -] - [[package]] name = "celestia-proto" version = "0.1.0" @@ -1938,7 +1789,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ - "aead 0.5.2", + "aead", "chacha20", "cipher 0.4.4", "poly1305", @@ -1995,15 +1846,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array 0.14.7", -] - [[package]] name = "cipher" version = "0.4.4" @@ -2453,21 +2295,6 @@ dependencies = [ "wasmtime-types", ] -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - [[package]] name = "crc32fast" version = "1.3.2" @@ -2516,18 +2343,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "crypto-bigint" version = "0.5.5" @@ -2536,7 +2351,7 @@ checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle 2.5.0", "zeroize", ] @@ -2568,26 +2383,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ "generic-array 0.14.7", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] name = "crypto-mac" -version = "0.11.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ "generic-array 0.14.7", - "subtle 2.4.1", -] - -[[package]] -name = "ctr" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" -dependencies = [ - "cipher 0.3.0", + "subtle 2.5.0", ] [[package]] @@ -2608,7 +2414,7 @@ dependencies = [ "byteorder", "digest 0.8.1", "rand_core 0.5.1", - "subtle 2.4.1", + "subtle 2.5.0", "zeroize", ] @@ -2621,7 +2427,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle 2.4.1", + "subtle 2.5.0", "zeroize", ] @@ -2638,7 +2444,7 @@ dependencies = [ "fiat-crypto", "platforms", "rustc_version 0.4.0", - "subtle 2.4.1", + "subtle 2.5.0", "zeroize", ] @@ -2806,17 +2612,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - [[package]] name = "der" version = "0.7.8" @@ -2827,27 +2622,13 @@ dependencies = [ "zeroize", ] -[[package]] -name = "der-parser" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" -dependencies = [ - "asn1-rs 0.3.1", - "displaydoc", - "nom", - "num-bigint", - "num-traits 0.2.17", - "rusticata-macros", -] - [[package]] name = "der-parser" version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", "displaydoc", "nom", "num-bigint", @@ -2887,37 +2668,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_builder" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" -dependencies = [ - "darling 0.14.4", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_macro" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" -dependencies = [ - "derive_builder_core", - "syn 1.0.109", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -2970,7 +2720,7 @@ dependencies = [ "block-buffer 0.10.4", "const-oid", "crypto-common", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -3134,30 +2884,18 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - [[package]] name = "ecdsa" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.8", + "der", "digest 0.10.7", - "elliptic-curve 0.13.8", - "rfc6979 0.4.0", + "elliptic-curve", + "rfc6979", "signature 2.2.0", - "spki 0.7.3", + "spki", ] [[package]] @@ -3175,7 +2913,7 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8 0.10.2", + "pkcs8", "signature 2.2.0", ] @@ -3215,7 +2953,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "sha2 0.10.8", - "subtle 2.4.1", + "subtle 2.5.0", "zeroize", ] @@ -3239,44 +2977,22 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array 0.14.7", - "group 0.12.1", - "hkdf", - "pem-rfc7468", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.5", + "base16ct", + "crypto-bigint", "digest 0.10.7", - "ff 0.13.0", + "ff", "generic-array 0.14.7", - "group 0.13.0", - "pkcs8 0.10.2", + "group", + "pkcs8", "rand_core 0.6.4", - "sec1 0.7.3", - "subtle 2.4.1", + "sec1", + "subtle 2.5.0", "zeroize", ] @@ -3387,8 +3103,8 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" dependencies = [ - "aes 0.8.3", - "ctr 0.9.2", + "aes", + "ctr", "digest 0.10.7", "hex", "hmac 0.12.1", @@ -3549,7 +3265,7 @@ dependencies = [ "cargo_metadata 0.18.1", "chrono", "const-hex", - "elliptic-curve 0.13.8", + "elliptic-curve", "ethabi", "generic-array 0.14.7", "k256", @@ -3658,7 +3374,7 @@ dependencies = [ "coins-bip32", "coins-bip39", "const-hex", - "elliptic-curve 0.13.8", + "elliptic-curve", "eth-keystore", "ethers-core", "rand 0.8.5", @@ -3796,16 +3512,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle 2.4.1", -] - [[package]] name = "ff" version = "0.13.0" @@ -3813,13 +3519,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] name = "fflonk" version = "0.1.0" -source = "git+https://github.com/w3f/fflonk#95f3a57d1f4252fe95310c1567d153f25f3066b4" +source = "git+https://github.com/w3f/fflonk#1e854f35e9a65d08b11a86291405cdc95baa0a35" dependencies = [ "ark-ec", "ark-ff 0.4.2", @@ -3847,14 +3553,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] @@ -3996,7 +3702,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ "Inflector", - "array-bytes 6.2.0", + "array-bytes 6.2.2", "chrono", "clap 4.4.10", "comfy-table", @@ -4350,7 +4056,7 @@ checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" dependencies = [ "futures-io", "rustls 0.20.9", - "webpki 0.22.4", + "webpki", ] [[package]] @@ -4478,16 +4184,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "ghash" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" -dependencies = [ - "opaque-debug 0.3.0", - "polyval 0.5.3", -] - [[package]] name = "ghash" version = "0.5.0" @@ -4495,7 +4191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" dependencies = [ "opaque-debug 0.3.0", - "polyval 0.6.1", + "polyval", ] [[package]] @@ -4589,26 +4285,15 @@ dependencies = [ "minilp", ] -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle 2.4.1", -] - [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -4773,7 +4458,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ - "crypto-mac 0.11.1", + "crypto-mac 0.11.0", "digest 0.9.0", ] @@ -5147,25 +4832,6 @@ dependencies = [ "num-traits 0.2.17", ] -[[package]] -name = "interceptor" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8a11ae2da61704edada656798b61c94b35ecac2c58eb955156987d5e6be90b" -dependencies = [ - "async-trait", - "bytes", - "log", - "rand 0.8.5", - "rtcp", - "rtp", - "thiserror", - "tokio", - "waitgroup", - "webrtc-srtp", - "webrtc-util", -] - [[package]] name = "io-lifetimes" version = "1.0.11" @@ -5553,8 +5219,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" dependencies = [ "cfg-if", - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", + "ecdsa", + "elliptic-curve", "once_cell", "sha2 0.10.8", "signature 2.2.0", @@ -5679,9 +5345,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libp2p" -version = "0.51.3" +version = "0.51.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f210d259724eae82005b5c48078619b7745edb7b76de370b03f8ba59ea103097" +checksum = "f35eae38201a993ece6bdc823292d6abd1bffed1c4d0f4a3517d2bd8e1d917fe" dependencies = [ "bytes", "futures", @@ -5704,7 +5370,6 @@ dependencies = [ "libp2p-swarm", "libp2p-tcp", "libp2p-wasm-ext", - "libp2p-webrtc", "libp2p-websocket", "libp2p-yamux", "multiaddr 0.17.1", @@ -6031,12 +5696,12 @@ dependencies = [ "futures-rustls", "libp2p-core", "libp2p-identity 0.1.3", - "rcgen 0.10.0", + "rcgen", "ring 0.16.20", "rustls 0.20.9", "thiserror", - "webpki 0.22.4", - "x509-parser 0.14.0", + "webpki", + "x509-parser", "yasna", ] @@ -6055,41 +5720,10 @@ dependencies = [ ] [[package]] -name = "libp2p-webrtc" -version = "0.4.0-alpha.4" +name = "libp2p-websocket" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba48592edbc2f60b4bc7c10d65445b0c3964c07df26fdf493b6880d33be36f8" -dependencies = [ - "async-trait", - "asynchronous-codec", - "bytes", - "futures", - "futures-timer", - "hex", - "if-watch", - "libp2p-core", - "libp2p-identity 0.1.3", - "libp2p-noise", - "log", - "multihash 0.17.0", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "rcgen 0.9.3", - "serde", - "stun", - "thiserror", - "tinytemplate", - "tokio", - "tokio-util", - "webrtc", -] - -[[package]] -name = "libp2p-websocket" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "111273f7b3d3510524c752e8b7a5314b7f7a1fee7e68161c01a7d72cbb06db9f" +checksum = "111273f7b3d3510524c752e8b7a5314b7f7a1fee7e68161c01a7d72cbb06db9f" dependencies = [ "either", "futures", @@ -6170,7 +5804,7 @@ checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ "crunchy", "digest 0.9.0", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -6464,6 +6098,7 @@ dependencies = [ "mp-chain-id", "mp-felt", "mp-hashers", + "mp-simulations", "mp-transactions", "pallet-aura", "pallet-grandpa", @@ -6484,6 +6119,7 @@ dependencies = [ "sp-std 8.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0)", "sp-transaction-pool", "sp-version", + "starknet-core", "starknet-ff", "starknet_api", "substrate-wasm-builder", @@ -6650,6 +6286,7 @@ dependencies = [ "mp-block", "mp-felt", "mp-hashers", + "mp-simulations", "mp-transactions", "pallet-starknet", "pallet-starknet-runtime-api", @@ -6690,6 +6327,8 @@ dependencies = [ "jsonrpsee 0.16.3", "mp-block", "mp-digest-log", + "mp-felt", + "mp-simulations", "mp-transactions", "num-bigint", "serde", @@ -6767,15 +6406,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.8.0" @@ -6860,9 +6490,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", @@ -6889,7 +6519,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_distr", - "subtle 2.4.1", + "subtle 2.5.0", "thiserror", "zeroize", ] @@ -6992,7 +6622,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", + "serde_with", "sp-core 21.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0)", + "starknet-core", "starknet-ff", "starknet_api", "thiserror-no-std", @@ -7021,6 +6653,20 @@ dependencies = [ "thiserror-no-std", ] +[[package]] +name = "mp-simulations" +version = "0.6.0" +dependencies = [ + "blockifier", + "mp-felt", + "parity-scale-codec", + "scale-info", + "serde", + "serde_with", + "starknet-core", + "starknet_api", +] + [[package]] name = "mp-state" version = "0.6.0" @@ -7051,6 +6697,7 @@ dependencies = [ "cairo-vm", "derive_more", "flate2", + "log", "mp-fee", "mp-felt", "mp-hashers", @@ -7336,7 +6983,6 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.6.5", ] [[package]] @@ -7576,29 +7222,20 @@ dependencies = [ "memchr", ] -[[package]] -name = "oid-registry" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e20717fa0541f39bd146692035c37bedfa532b3e5071b35761082407546b2a" -dependencies = [ - "asn1-rs 0.3.1", -] - [[package]] name = "oid-registry" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" @@ -7693,28 +7330,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "p256" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" -dependencies = [ - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", -] - -[[package]] -name = "p384" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" -dependencies = [ - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", -] - [[package]] name = "pallet-aura" version = "4.0.0-dev" @@ -7816,6 +7431,7 @@ dependencies = [ "mp-felt", "mp-hashers", "mp-sequencer-address", + "mp-simulations", "mp-state", "mp-storage", "mp-transactions", @@ -7850,12 +7466,14 @@ dependencies = [ "blockifier", "hashbrown 0.14.3", "mp-felt", + "mp-simulations", "mp-transactions", "parity-scale-codec", "scale-info", "sp-api", "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0)", "sp-runtime 24.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0)", + "starknet-core", "starknet_api", ] @@ -8006,7 +7624,7 @@ checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" dependencies = [ "base64ct", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -8033,7 +7651,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" dependencies = [ - "crypto-mac 0.11.1", + "crypto-mac 0.11.0", ] [[package]] @@ -8073,15 +7691,6 @@ dependencies = [ "base64 0.13.1", ] -[[package]] -name = "pem-rfc7468" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" -dependencies = [ - "base64ct", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -8248,24 +7857,14 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", - "spki 0.7.3", + "der", + "spki", ] [[package]] @@ -8302,19 +7901,7 @@ checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", "opaque-debug 0.3.0", - "universal-hash 0.5.1", -] - -[[package]] -name = "polyval" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug 0.3.0", - "universal-hash 0.4.1", + "universal-hash", ] [[package]] @@ -8326,14 +7913,14 @@ dependencies = [ "cfg-if", "cpufeatures", "opaque-debug 0.3.0", - "universal-hash 0.5.1", + "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" [[package]] name = "powerfmt" @@ -8720,7 +8307,7 @@ dependencies = [ "thiserror", "tinyvec", "tracing", - "webpki 0.22.4", + "webpki", ] [[package]] @@ -8863,19 +8450,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "rcgen" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" -dependencies = [ - "pem", - "ring 0.16.20", - "time", - "x509-parser 0.13.2", - "yasna", -] - [[package]] name = "rcgen" version = "0.10.0" @@ -8897,15 +8471,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -9067,17 +8632,6 @@ dependencies = [ "quick-error", ] -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac 0.12.1", - "zeroize", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -9085,7 +8639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ "hmac 0.12.1", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -9121,9 +8675,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", "getrandom 0.2.11", @@ -9214,17 +8768,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "rtcp" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1919efd6d4a6a85d13388f9487549bb8e359f17198cc03ffd72f79b553873691" -dependencies = [ - "bytes", - "thiserror", - "webrtc-util", -] - [[package]] name = "rtnetlink" version = "0.10.1" @@ -9250,20 +8793,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rtp" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a095411ff00eed7b12e4c6a118ba984d113e1079582570d56a5ee723f11f80" -dependencies = [ - "async-trait", - "bytes", - "rand 0.8.5", - "serde", - "thiserror", - "webrtc-util", -] - [[package]] name = "ruint" version = "1.11.1" @@ -9366,19 +8895,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.1", - "log", - "ring 0.16.20", - "sct 0.6.1", - "webpki 0.21.4", -] - [[package]] name = "rustls" version = "0.20.9" @@ -9387,8 +8903,8 @@ checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring 0.16.20", - "sct 0.7.1", - "webpki 0.22.4", + "sct", + "webpki", ] [[package]] @@ -9398,9 +8914,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", - "ring 0.17.6", + "ring 0.17.7", "rustls-webpki", - "sct 0.7.1", + "sct", ] [[package]] @@ -9430,7 +8946,7 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.6", + "ring 0.17.7", "untrusted 0.9.0", ] @@ -9597,7 +9113,7 @@ name = "sc-cli" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "array-bytes 6.2.0", + "array-bytes 6.2.2", "chrono", "clap 4.4.10", "fdlimit", @@ -9793,7 +9309,7 @@ version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ "ahash 0.8.6", - "array-bytes 6.2.0", + "array-bytes 6.2.2", "async-trait", "dyn-clone", "finality-grandpa", @@ -9959,7 +9475,7 @@ name = "sc-keystore" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "array-bytes 6.2.0", + "array-bytes 6.2.2", "parking_lot 0.12.1", "serde_json", "sp-application-crypto 23.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0)", @@ -10001,7 +9517,7 @@ name = "sc-network" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "array-bytes 6.2.0", + "array-bytes 6.2.2", "async-channel", "async-trait", "asynchronous-codec", @@ -10097,7 +9613,7 @@ name = "sc-network-light" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "array-bytes 6.2.0", + "array-bytes 6.2.2", "async-channel", "futures", "libp2p-identity 0.1.3", @@ -10118,7 +9634,7 @@ name = "sc-network-sync" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "array-bytes 6.2.0", + "array-bytes 6.2.2", "async-channel", "async-trait", "fork-tree", @@ -10153,7 +9669,7 @@ name = "sc-network-transactions" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "array-bytes 6.2.0", + "array-bytes 6.2.2", "futures", "libp2p", "log", @@ -10171,7 +9687,7 @@ name = "sc-offchain" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "array-bytes 6.2.0", + "array-bytes 6.2.2", "bytes", "fnv", "futures", @@ -10281,7 +9797,7 @@ name = "sc-rpc-spec-v2" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "array-bytes 6.2.0", + "array-bytes 6.2.2", "futures", "futures-util", "hex", @@ -10661,7 +10177,7 @@ dependencies = [ "rand 0.7.3", "rand_core 0.5.1", "sha2 0.8.2", - "subtle 2.4.1", + "subtle 2.5.0", "zeroize", ] @@ -10689,63 +10205,27 @@ dependencies = [ "sha2 0.10.8", ] -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - [[package]] name = "sct" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.6", + "ring 0.17.7", "untrusted 0.9.0", ] -[[package]] -name = "sdp" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d22a5ef407871893fd72b4562ee15e4742269b173959db4b8df6f538c414e13" -dependencies = [ - "rand 0.8.5", - "substring", - "thiserror", - "url", -] - -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array 0.14.7", - "pkcs8 0.9.0", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct 0.2.0", - "der 0.7.8", + "base16ct", + "der", "generic-array 0.14.7", - "pkcs8 0.10.2", - "subtle 2.4.1", + "pkcs8", + "subtle 2.5.0", "zeroize", ] @@ -11074,10 +10554,6 @@ name = "signature" version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] [[package]] name = "signature" @@ -11171,15 +10647,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58021967fd0a5eeeb23b08df6cc244a4d4a5b4aec1d27c9e02fad1a58b4cd74e" dependencies = [ - "aes-gcm 0.10.3", + "aes-gcm", "blake2 0.10.6", "chacha20poly1305", "curve25519-dalek 4.1.1", "rand_core 0.6.4", - "ring 0.17.6", + "ring 0.17.7", "rustc_version 0.4.0", "sha2 0.10.8", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -11484,7 +10960,7 @@ name = "sp-core" version = "21.0.0" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "array-bytes 6.2.0", + "array-bytes 6.2.2", "bandersnatch_vrfs", "bitflags 1.3.2", "blake2 0.10.6", @@ -11986,7 +11462,7 @@ name = "sp-statement-store" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" dependencies = [ - "aes-gcm 0.10.3", + "aes-gcm", "curve25519-dalek 4.1.1", "ed25519-dalek 2.1.0", "hkdf", @@ -12262,16 +11738,6 @@ dependencies = [ "strum 0.24.1", ] -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - [[package]] name = "spki" version = "0.7.3" @@ -12279,7 +11745,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.8", + "der", ] [[package]] @@ -12363,13 +11829,13 @@ name = "starknet-crypto" version = "0.6.1" source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=a35ce22#a35ce22be52bf33b8e544d0df926031b0ec7d761" dependencies = [ - "crypto-bigint 0.5.5", + "crypto-bigint", "hex", "hmac 0.12.1", "num-bigint", "num-integer", "num-traits 0.2.17", - "rfc6979 0.4.0", + "rfc6979", "sha2 0.10.8", "starknet-crypto-codegen", "starknet-curve", @@ -12402,7 +11868,7 @@ source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=a35ce22#a35ce2 dependencies = [ "ark-ff 0.4.2", "bigdecimal", - "crypto-bigint 0.5.5", + "crypto-bigint", "getrandom 0.2.11", "hex", "serde", @@ -12434,6 +11900,7 @@ dependencies = [ "anyhow", "assert_matches", "async-lock 3.2.0", + "async-trait", "flate2", "reqwest", "rstest", @@ -12458,7 +11925,7 @@ source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=a35ce22#a35ce2 dependencies = [ "async-trait", "auto_impl", - "crypto-bigint 0.5.5", + "crypto-bigint", "eth-keystore", "rand 0.8.5", "starknet-core", @@ -12613,25 +12080,6 @@ dependencies = [ "syn 2.0.39", ] -[[package]] -name = "stun" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e94b1ec00bad60e6410e058b52f1c66de3dc5fe4d62d09b3e52bb7d3b73e25" -dependencies = [ - "base64 0.13.1", - "crc", - "lazy_static", - "md-5", - "rand 0.8.5", - "ring 0.16.20", - "subtle 2.4.1", - "thiserror", - "tokio", - "url", - "webrtc-util", -] - [[package]] name = "substrate-bip39" version = "0.4.5" @@ -12712,15 +12160,6 @@ dependencies = [ "wasm-opt", ] -[[package]] -name = "substring" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" -dependencies = [ - "autocfg", -] - [[package]] name = "subtle" version = "1.0.0" @@ -12729,9 +12168,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "subtle-encoding" @@ -12948,7 +12387,7 @@ dependencies = [ "serde_repr", "sha2 0.10.8", "signature 2.2.0", - "subtle 2.4.1", + "subtle 2.5.0", "subtle-encoding", "tendermint-proto", "time", @@ -13172,16 +12611,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -13660,25 +13089,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "turn" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4712ee30d123ec7ae26d1e1b218395a16c87cdbaf4b3925d170d684af62ea5e8" -dependencies = [ - "async-trait", - "base64 0.13.1", - "futures", - "log", - "md-5", - "rand 0.8.5", - "ring 0.16.20", - "stun", - "thiserror", - "tokio", - "webrtc-util", -] - [[package]] name = "twox-hash" version = "1.6.3" @@ -13732,9 +13142,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -13769,16 +13179,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" -[[package]] -name = "universal-hash" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" -dependencies = [ - "generic-array 0.14.7", - "subtle 2.4.1", -] - [[package]] name = "universal-hash" version = "0.5.1" @@ -13786,7 +13186,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -13910,15 +13310,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "waitgroup" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292" -dependencies = [ - "atomic-waker", -] - [[package]] name = "walkdir" version = "2.4.0" @@ -14295,23 +13686,13 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - [[package]] name = "webpki" version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.6", + "ring 0.17.7", "untrusted 0.9.0", ] @@ -14321,7 +13702,7 @@ version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ - "webpki 0.22.4", + "webpki", ] [[package]] @@ -14330,214 +13711,6 @@ version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" -[[package]] -name = "webrtc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3bc9049bdb2cea52f5fd4f6f728184225bdb867ed0dc2410eab6df5bdd67bb" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "hex", - "interceptor", - "lazy_static", - "log", - "rand 0.8.5", - "rcgen 0.9.3", - "regex", - "ring 0.16.20", - "rtcp", - "rtp", - "rustls 0.19.1", - "sdp", - "serde", - "serde_json", - "sha2 0.10.8", - "stun", - "thiserror", - "time", - "tokio", - "turn", - "url", - "waitgroup", - "webrtc-data", - "webrtc-dtls", - "webrtc-ice", - "webrtc-mdns", - "webrtc-media", - "webrtc-sctp", - "webrtc-srtp", - "webrtc-util", -] - -[[package]] -name = "webrtc-data" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef36a4d12baa6e842582fe9ec16a57184ba35e1a09308307b67d43ec8883100" -dependencies = [ - "bytes", - "derive_builder", - "log", - "thiserror", - "tokio", - "webrtc-sctp", - "webrtc-util", -] - -[[package]] -name = "webrtc-dtls" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a00f4242f2db33307347bd5be53263c52a0331c96c14292118c9a6bb48d267" -dependencies = [ - "aes 0.6.0", - "aes-gcm 0.10.3", - "async-trait", - "bincode 1.3.3", - "block-modes", - "byteorder", - "ccm", - "curve25519-dalek 3.2.0", - "der-parser 8.2.0", - "elliptic-curve 0.12.3", - "hkdf", - "hmac 0.12.1", - "log", - "p256", - "p384", - "rand 0.8.5", - "rand_core 0.6.4", - "rcgen 0.10.0", - "ring 0.16.20", - "rustls 0.19.1", - "sec1 0.3.0", - "serde", - "sha1", - "sha2 0.10.8", - "signature 1.6.4", - "subtle 2.4.1", - "thiserror", - "tokio", - "webpki 0.21.4", - "webrtc-util", - "x25519-dalek 2.0.0", - "x509-parser 0.13.2", -] - -[[package]] -name = "webrtc-ice" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a03cc11e9a7d7b4f9f99870558fe37a102b65b93f8045392fef7c67b39e80" -dependencies = [ - "arc-swap", - "async-trait", - "crc", - "log", - "rand 0.8.5", - "serde", - "serde_json", - "stun", - "thiserror", - "tokio", - "turn", - "url", - "uuid 1.6.1", - "waitgroup", - "webrtc-mdns", - "webrtc-util", -] - -[[package]] -name = "webrtc-mdns" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f08dfd7a6e3987e255c4dbe710dde5d94d0f0574f8a21afa95d171376c143106" -dependencies = [ - "log", - "socket2 0.4.10", - "thiserror", - "tokio", - "webrtc-util", -] - -[[package]] -name = "webrtc-media" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f72e1650a8ae006017d1a5280efb49e2610c19ccc3c0905b03b648aee9554991" -dependencies = [ - "byteorder", - "bytes", - "rand 0.8.5", - "rtp", - "thiserror", -] - -[[package]] -name = "webrtc-sctp" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d47adcd9427eb3ede33d5a7f3424038f63c965491beafcc20bc650a2f6679c0" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "crc", - "log", - "rand 0.8.5", - "thiserror", - "tokio", - "webrtc-util", -] - -[[package]] -name = "webrtc-srtp" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6183edc4c1c6c0175f8812eefdce84dfa0aea9c3ece71c2bf6ddd3c964de3da5" -dependencies = [ - "aead 0.4.3", - "aes 0.7.5", - "aes-gcm 0.9.4", - "async-trait", - "byteorder", - "bytes", - "ctr 0.8.0", - "hmac 0.11.0", - "log", - "rtcp", - "rtp", - "sha-1", - "subtle 2.4.1", - "thiserror", - "tokio", - "webrtc-util", -] - -[[package]] -name = "webrtc-util" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f1db1727772c05cf7a2cfece52c3aca8045ca1e176cd517d323489aa3c6d87" -dependencies = [ - "async-trait", - "bitflags 1.3.2", - "bytes", - "cc", - "ipnet", - "lazy_static", - "libc", - "log", - "nix", - "rand 0.8.5", - "thiserror", - "tokio", - "winapi", -] - [[package]] name = "which" version = "4.4.2" @@ -14816,9 +13989,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.19" +version = "0.5.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +checksum = "b7e87b8dfbe3baffbe687eef2e164e32286eff31a5ee16463ce03d991643ec94" dependencies = [ "memchr", ] @@ -14884,38 +14057,19 @@ dependencies = [ "zeroize", ] -[[package]] -name = "x509-parser" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" -dependencies = [ - "asn1-rs 0.3.1", - "base64 0.13.1", - "data-encoding", - "der-parser 7.0.0", - "lazy_static", - "nom", - "oid-registry 0.4.0", - "ring 0.16.20", - "rusticata-macros", - "thiserror", - "time", -] - [[package]] name = "x509-parser" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", "base64 0.13.1", "data-encoding", - "der-parser 8.2.0", + "der-parser", "lazy_static", "nom", - "oid-registry 0.6.1", + "oid-registry", "rusticata-macros", "thiserror", "time", @@ -14973,18 +14127,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.28" +version = "0.7.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" +checksum = "5d075cf85bbb114e933343e087b92f2146bac0d55b534cbb8188becf0039948e" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.28" +version = "0.7.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" +checksum = "86cd5ca076997b97ef09d3ad65efe811fa68c9e874cb636ccb211223a813b0c2" dependencies = [ "proc-macro2", "quote", @@ -15017,7 +14171,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ - "aes 0.8.3", + "aes", "byteorder", "bzip2", "constant_time_eq 0.1.5", diff --git a/Cargo.toml b/Cargo.toml index 01d900d16a..26b823f8e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -162,6 +162,7 @@ mp-storage = { path = "crates/primitives/storage", default-features = false } mp-transactions = { path = "crates/primitives/transactions", default-features = false } mp-commitments = { path = "crates/primitives/commitments", default-features = false } mp-chain-id = { path = "crates/primitives/chain-id", default-features = false } +mp-simulations = { path = "crates/primitives/simulations", default-features = false } # Madara client mc-mapping-sync = { path = "crates/client/mapping-sync" } diff --git a/crates/client/rpc-core/Cargo.toml b/crates/client/rpc-core/Cargo.toml index 758cc578c2..c3b1916c11 100644 --- a/crates/client/rpc-core/Cargo.toml +++ b/crates/client/rpc-core/Cargo.toml @@ -32,6 +32,8 @@ jsonrpsee = { workspace = true, features = [ ], default-features = true } mp-block = { workspace = true } mp-digest-log = { workspace = true } +mp-felt = { workspace = true } +mp-simulations = { workspace = true } mp-transactions = { workspace = true, features = ["serde"] } num-bigint = { workspace = true } serde = { workspace = true, default-features = true } diff --git a/crates/client/rpc-core/src/lib.rs b/crates/client/rpc-core/src/lib.rs index 230351d5c1..2403bd43ac 100644 --- a/crates/client/rpc-core/src/lib.rs +++ b/crates/client/rpc-core/src/lib.rs @@ -14,6 +14,7 @@ use serde_with::serde_as; pub mod utils; +use mp_simulations::{SimulatedTransaction, SimulationFlag}; use mp_transactions::TransactionStatus; use starknet_core::serde::unsigned_field_element::UfeHex; use starknet_core::types::{ @@ -53,7 +54,7 @@ pub trait StarknetWriteRpcApi { ) -> RpcResult; } -/// Starknet rpc interface. +/// Starknet read rpc interface. #[rpc(server, namespace = "starknet")] pub trait StarknetReadRpcApi { /// Get the Version of the StarkNet JSON-RPC Specification Being Used @@ -148,3 +149,16 @@ pub trait StarknetReadRpcApi { transaction_hash: FieldElement, ) -> RpcResult; } + +/// Starknet trace rpc interface. +#[rpc(server, namespace = "starknet")] +pub trait StarknetTraceRpcApi { + /// Returns the execution trace of a transaction by simulating it in the runtime. + #[method(name = "simulateTransactions")] + async fn simulate_transactions( + &self, + block_id: BlockId, + transactions: Vec, + simulation_flags: Vec, + ) -> RpcResult>; +} diff --git a/crates/client/rpc/Cargo.toml b/crates/client/rpc/Cargo.toml index f719688bf9..c11c524eb0 100644 --- a/crates/client/rpc/Cargo.toml +++ b/crates/client/rpc/Cargo.toml @@ -49,9 +49,10 @@ jsonrpsee = { workspace = true, default-features = true, features = [ "macros", ] } log = { workspace = true, default-features = true } -mp-block = { workspace = true } -mp-felt = { workspace = true } -mp-hashers = { workspace = true } +mp-block = { workspace = true, default-features = true } +mp-felt = { workspace = true, default-features = true } +mp-hashers = { workspace = true, default-features = true } +mp-simulations = { workspace = true } mp-transactions = { workspace = true, features = ["client"] } serde_json = { workspace = true, default-features = true } thiserror = { workspace = true } diff --git a/crates/client/rpc/src/lib.rs b/crates/client/rpc/src/lib.rs index cd11b52c64..fed728653e 100644 --- a/crates/client/rpc/src/lib.rs +++ b/crates/client/rpc/src/lib.rs @@ -7,7 +7,6 @@ mod errors; mod events; mod madara_backend_client; mod types; - use std::marker::PhantomData; use std::sync::Arc; @@ -17,10 +16,11 @@ use jsonrpsee::types::error::CallError; use log::error; use mc_db::Backend as MadaraBackend; pub use mc_rpc_core::utils::*; -pub use mc_rpc_core::{Felt, StarknetReadRpcApiServer, StarknetWriteRpcApiServer}; +pub use mc_rpc_core::{Felt, StarknetReadRpcApiServer, StarknetTraceRpcApiServer, StarknetWriteRpcApiServer}; use mc_storage::OverrideHandle; use mp_felt::{Felt252Wrapper, Felt252WrapperError}; use mp_hashers::HasherT; +use mp_simulations::{SimulatedTransaction, SimulationFlag, SimulationFlags}; use mp_transactions::compute_hash::ComputeTransactionHash; use mp_transactions::to_starknet_core_transaction::to_starknet_core_tx; use mp_transactions::{TransactionStatus, UserTransaction}; @@ -1459,6 +1459,60 @@ where } } +#[async_trait] +#[allow(unused_variables)] +impl StarknetTraceRpcApiServer for Starknet +where + A: ChainApi + 'static, + B: BlockT, + P: TransactionPool + 'static, + BE: Backend + 'static, + C: HeaderBackend + BlockBackend + StorageProvider + 'static, + C: ProvideRuntimeApi, + C::Api: StarknetRuntimeApi + ConvertTransactionRuntimeApi, + H: HasherT + Send + Sync + 'static, +{ + async fn simulate_transactions( + &self, + block_id: BlockId, + transactions: Vec, + simulation_flags: Vec, + ) -> RpcResult> { + let substrate_block_hash = self.substrate_block_hash_from_starknet_block(block_id).map_err(|e| { + error!("'{e}'"); + StarknetRpcApiError::BlockNotFound + })?; + let best_block_hash = self.client.info().best_hash; + let chain_id = Felt252Wrapper(self.chain_id()?.0); + + let mut user_transactions = vec![]; + for tx in transactions { + let tx = tx.try_into().map_err(|e| { + error!("Failed to convert BroadcastedTransaction to UserTransaction: {e}"); + StarknetRpcApiError::InternalServerError + })?; + user_transactions.push(tx); + } + + let simulation_flags: SimulationFlags = simulation_flags.into(); + + let fee_estimates = self + .client + .runtime_api() + .simulate_transactions(substrate_block_hash, user_transactions, simulation_flags) + .map_err(|e| { + error!("Request parameters error: {e}"); + StarknetRpcApiError::InternalServerError + })? + .map_err(|e| { + error!("Failed to call function: {:#?}", e); + StarknetRpcApiError::ContractError + })?; + + Ok(fee_estimates) + } +} + async fn submit_extrinsic( pool: Arc

, best_block_hash: ::Hash, diff --git a/crates/node/src/rpc/mod.rs b/crates/node/src/rpc/mod.rs index 44d58dd632..908c7f76a7 100644 --- a/crates/node/src/rpc/mod.rs +++ b/crates/node/src/rpc/mod.rs @@ -58,7 +58,7 @@ where P: TransactionPool + 'static, BE: Backend + 'static, { - use mc_rpc::{Starknet, StarknetReadRpcApiServer, StarknetWriteRpcApiServer}; + use mc_rpc::{Starknet, StarknetReadRpcApiServer, StarknetTraceRpcApiServer, StarknetWriteRpcApiServer}; use sc_consensus_manual_seal::rpc::{ManualSeal, ManualSealApiServer}; use substrate_frame_rpc_system::{System, SystemApiServer}; @@ -76,6 +76,15 @@ where starknet_params.starting_block, )))?; module.merge(StarknetWriteRpcApiServer::into_rpc(Starknet::<_, _, _, _, _, StarknetHasher>::new( + client.clone(), + starknet_params.madara_backend.clone(), + starknet_params.overrides.clone(), + pool.clone(), + graph.clone(), + starknet_params.sync_service.clone(), + starknet_params.starting_block, + )))?; + module.merge(StarknetTraceRpcApiServer::into_rpc(Starknet::<_, _, _, _, _, StarknetHasher>::new( client, starknet_params.madara_backend, starknet_params.overrides, diff --git a/crates/pallets/starknet/Cargo.toml b/crates/pallets/starknet/Cargo.toml index c901e88add..6f17170f13 100644 --- a/crates/pallets/starknet/Cargo.toml +++ b/crates/pallets/starknet/Cargo.toml @@ -23,6 +23,10 @@ mp-fee = { workspace = true } mp-felt = { workspace = true, features = ["parity-scale-codec", "serde"] } mp-hashers = { workspace = true } mp-sequencer-address = { workspace = true, features = ["parity-scale-codec"] } +mp-simulations = { workspace = true, features = [ + "parity-scale-codec", + "serde", +] } mp-state = { workspace = true } mp-storage = { workspace = true, features = ["parity-scale-codec"] } mp-transactions = { workspace = true, features = ["scale-info"] } @@ -106,6 +110,8 @@ std = [ "dep:reqwest", "dep:cairo-lang-casm-contract-class", "parity-scale-codec/std", + "starknet-core/std", + "mp-simulations/std", ] runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] try-runtime = ["frame-support/try-runtime"] diff --git a/crates/pallets/starknet/runtime_api/Cargo.toml b/crates/pallets/starknet/runtime_api/Cargo.toml index 160f4c4c0b..0950fa133b 100644 --- a/crates/pallets/starknet/runtime_api/Cargo.toml +++ b/crates/pallets/starknet/runtime_api/Cargo.toml @@ -8,6 +8,10 @@ edition = "2021" [dependencies] # Madara primitives mp-felt = { workspace = true, features = ["parity-scale-codec", "serde"] } +mp-simulations = { workspace = true, features = [ + "parity-scale-codec", + "scale-info", +] } mp-transactions = { workspace = true, features = [ "parity-scale-codec", "scale-info", @@ -19,12 +23,13 @@ blockifier = { workspace = true, features = [ "scale-info", ] } hashbrown = { workspace = true } +starknet-core = { workspace = true } starknet_api = { workspace = true, features = [ "scale-info", "parity-scale-codec", ] } -# Substrate +# Substrate parity-scale-codec = { workspace = true, features = ["derive"] } scale-info = { workspace = true, features = ["derive"] } sp-api = { workspace = true } @@ -44,4 +49,6 @@ std = [ "sp-arithmetic/std", "parity-scale-codec/std", "scale-info/std", + "starknet-core/std", + "mp-simulations/std", ] diff --git a/crates/pallets/starknet/runtime_api/src/lib.rs b/crates/pallets/starknet/runtime_api/src/lib.rs index e296dc6814..bdb9524dfa 100644 --- a/crates/pallets/starknet/runtime_api/src/lib.rs +++ b/crates/pallets/starknet/runtime_api/src/lib.rs @@ -16,6 +16,7 @@ pub extern crate alloc; use alloc::string::String; use alloc::vec::Vec; +use mp_simulations::{SimulatedTransaction, SimulationFlags}; use sp_runtime::DispatchError; use starknet_api::api_core::{ChainId, ClassHash, ContractAddress, EntryPointSelector, Nonce}; use starknet_api::block::{BlockNumber, BlockTimestamp}; @@ -48,6 +49,8 @@ sp_api::decl_runtime_apis! { fn chain_id() -> Felt252Wrapper; /// Returns fee estimate fn estimate_fee(transactions: Vec) -> Result, DispatchError>; + /// Simulates transactions and returns their trace + fn simulate_transactions(transactions: Vec, simulation_flags: SimulationFlags) -> Result, DispatchError>; /// Filters extrinsic transactions to return only Starknet transactions /// /// To support runtime upgrades, the client must be unaware of the specific extrinsic diff --git a/crates/pallets/starknet/src/blockifier_state_adapter.rs b/crates/pallets/starknet/src/blockifier_state_adapter.rs index 22e28a1cf7..f8362f8a10 100644 --- a/crates/pallets/starknet/src/blockifier_state_adapter.rs +++ b/crates/pallets/starknet/src/blockifier_state_adapter.rs @@ -2,13 +2,12 @@ use alloc::collections::{BTreeMap, BTreeSet}; use core::marker::PhantomData; use blockifier::execution::contract_class::ContractClass; -use blockifier::state::cached_state::{CommitmentStateDiff, ContractStorageKey}; +use blockifier::state::cached_state::{CommitmentStateDiff, ContractStorageKey, StateChangesCount}; use blockifier::state::errors::StateError; use blockifier::state::state_api::{State, StateReader, StateResult}; use indexmap::IndexMap; use mp_felt::Felt252Wrapper; -use mp_state::{FeeConfig, StateChanges}; -use sp_core::Get; +use mp_state::StateChanges; use starknet_api::api_core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::hash::StarkFelt; use starknet_api::state::StorageKey; @@ -32,19 +31,15 @@ impl StateChanges for BlockifierStateAdapter where T: Config, { - fn count_state_changes(&self) -> (usize, usize, usize, usize) { + fn count_state_changes(&self) -> StateChangesCount { let keys = self.storage_update.keys(); let n_contract_updated = BTreeSet::from_iter(keys.clone().map(|&(contract_address, _)| contract_address)).len(); - (n_contract_updated, keys.len(), self.class_hash_update, self.compiled_class_hash_update) - } -} - -impl FeeConfig for BlockifierStateAdapter -where - T: Config, -{ - fn is_transaction_fee_disabled(&self) -> bool { - T::DisableTransactionFee::get() + StateChangesCount { + n_modified_contracts: n_contract_updated, + n_storage_updates: keys.len(), + n_class_hash_updates: self.class_hash_update, + n_compiled_class_hash_updates: self.compiled_class_hash_update, + } } } diff --git a/crates/pallets/starknet/src/execution_config.rs b/crates/pallets/starknet/src/execution_config.rs new file mode 100644 index 0000000000..e69b2b8e30 --- /dev/null +++ b/crates/pallets/starknet/src/execution_config.rs @@ -0,0 +1,37 @@ +use mp_simulations::SimulationFlags; +use mp_transactions::execution::ExecutionConfig; +use sp_core::Get; + +use crate::Config; + +/// Builder pattern for [`ExecutionConfig`]. Combines the +/// execution configuration from the runtime with the possible +/// flags for each transaction mode (e.g. normal, estimate fee, simulate, ...). +pub struct RuntimeExecutionConfigBuilder(ExecutionConfig); + +impl RuntimeExecutionConfigBuilder { + pub fn new() -> Self { + Self(ExecutionConfig { + is_query: false, + disable_fee_charge: false, + disable_validation: false, + disable_nonce_validation: T::DisableNonceValidation::get(), + disable_transaction_fee: T::DisableTransactionFee::get(), + }) + } + #[must_use] + pub fn with_query_mode(mut self) -> Self { + self.0.is_query = true; + self + } + #[must_use] + pub fn with_simulation_mode(mut self, simulation_flags: &SimulationFlags) -> Self { + self.0.disable_fee_charge = simulation_flags.skip_fee_charge; + self.0.disable_validation = simulation_flags.skip_validate; + self + } + + pub fn build(self) -> ExecutionConfig { + self.0 + } +} diff --git a/crates/pallets/starknet/src/lib.rs b/crates/pallets/starknet/src/lib.rs index 668c17addb..0a4b03717b 100644 --- a/crates/pallets/starknet/src/lib.rs +++ b/crates/pallets/starknet/src/lib.rs @@ -33,6 +33,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::large_enum_variant)] +use blockifier::transaction::objects::TransactionExecutionResult; /// Starknet pallet. /// Definition of the pallet's runtime storage items, events, errors, and dispatchable /// functions. @@ -41,6 +42,8 @@ pub use pallet::*; /// An adapter for the blockifier state related traits pub mod blockifier_state_adapter; +/// The implementation of the execution configuration. +pub mod execution_config; #[cfg(feature = "std")] pub mod genesis_loader; /// The implementation of the message type. @@ -55,15 +58,17 @@ mod offchain_worker; use blockifier::execution::entry_point::{CallEntryPoint, CallType, EntryPointExecutionContext}; use blockifier::state::cached_state::ContractStorageKey; -use blockifier::transaction::objects::{TransactionExecutionInfo, TransactionExecutionResult}; use starknet_api::state::StorageKey; use starknet_api::transaction::{Calldata, Event as StarknetEvent, Fee}; #[cfg(test)] mod tests; +mod utils; #[macro_use] pub extern crate alloc; +extern crate core; + use alloc::str::from_utf8_unchecked; use alloc::string::String; use alloc::vec; @@ -82,6 +87,10 @@ use mp_fee::INITIAL_GAS; use mp_felt::Felt252Wrapper; use mp_hashers::HasherT; use mp_sequencer_address::{InherentError, InherentType, DEFAULT_SEQUENCER_ADDRESS, INHERENT_IDENTIFIER}; +use mp_simulations::{ + DeclareTransactionTrace, DeployAccountTransactionTrace, FeeEstimate, FunctionInvocation, InvokeTransactionTrace, + SimulatedTransaction, SimulationFlags, TransactionTrace, +}; use mp_storage::{StarknetStorageSchemaVersion, PALLET_STARKNET_SCHEMA}; use mp_transactions::execution::{Execute, Validate}; use mp_transactions::{ @@ -90,7 +99,6 @@ use mp_transactions::{ }; use sp_runtime::traits::UniqueSaturatedInto; use sp_runtime::DigestItem; -use sp_std::result; use starknet_api::api_core::{ChainId, ClassHash, CompiledClassHash, ContractAddress, EntryPointSelector, Nonce}; use starknet_api::block::{BlockNumber, BlockTimestamp}; use starknet_api::deprecated_contract_class::EntryPointType; @@ -99,7 +107,9 @@ use starknet_api::transaction::TransactionHash; use starknet_crypto::FieldElement; use crate::alloc::string::ToString; +use crate::execution_config::RuntimeExecutionConfigBuilder; use crate::types::StorageSlot; +use crate::utils::{convert_call_info_to_execute_invocation, execute_txs_and_rollback}; pub(crate) const LOG_TARGET: &str = "runtime::starknet"; @@ -428,6 +438,9 @@ pub mod pallet { SequencerAddressNotValid, InvalidContractClassForThisDeclareVersion, Unimplemented, + MissingRevertReason, + MissingCallInfo, + TransactionalExecutionFailed, } /// The Starknet pallet external functions. @@ -495,8 +508,7 @@ pub mod pallet { .execute( &mut BlockifierStateAdapter::::default(), &Self::get_block_context(), - false, - T::DisableNonceValidation::get(), + &RuntimeExecutionConfigBuilder::new::().build(), ) .map_err(|e| { log::error!("failed to execute invoke tx: {:?}", e); @@ -558,8 +570,7 @@ pub mod pallet { .execute( &mut BlockifierStateAdapter::::default(), &Self::get_block_context(), - false, - T::DisableNonceValidation::get(), + &RuntimeExecutionConfigBuilder::new::().build(), ) .map_err(|_| Error::::TransactionExecutionFailed)?; @@ -608,8 +619,7 @@ pub mod pallet { .execute( &mut BlockifierStateAdapter::::default(), &Self::get_block_context(), - false, - T::DisableNonceValidation::get(), + &RuntimeExecutionConfigBuilder::new::().build(), ) .map_err(|e| { log::error!("failed to deploy accout: {:?}", e); @@ -664,8 +674,7 @@ pub mod pallet { .execute( &mut BlockifierStateAdapter::::default(), &Self::get_block_context(), - false, - T::DisableNonceValidation::get(), + &RuntimeExecutionConfigBuilder::new::().build(), ) .map_err(|e| { log::error!("Failed to consume l1 message: {}", e); @@ -703,10 +712,6 @@ pub mod pallet { Some(Call::set_sequencer_address { addr: inherent_data }) } - fn check_inherent(_call: &Self::Call, _data: &InherentData) -> result::Result<(), Self::Error> { - Ok(()) - } - fn is_inherent(call: &Self::Call) -> bool { matches!(call, Call::set_sequencer_address { .. }) } @@ -1091,60 +1096,12 @@ impl Pallet { pub fn estimate_fee(transactions: Vec) -> Result, DispatchError> { let chain_id = Self::chain_id(); - fn execute_txs_and_rollback( - txs: Vec, - block_context: &BlockContext, - disable_nonce_validation: bool, - chain_id: Felt252Wrapper, - ) -> Vec> { - let mut execution_results = vec![]; - let _: Result<_, DispatchError> = storage::transactional::with_transaction(|| { - for tx in txs { - let result = match tx { - UserTransaction::Declare(tx, contract_class) => { - let executable = tx - .try_into_executable::(chain_id, contract_class, true) - .map_err(|_| Error::::InvalidContractClass) - .expect("Contract class should be valid"); - executable.execute( - &mut BlockifierStateAdapter::::default(), - block_context, - true, - disable_nonce_validation, - ) - } - UserTransaction::DeployAccount(tx) => { - let executable = tx.into_executable::(chain_id, true); - executable.execute( - &mut BlockifierStateAdapter::::default(), - block_context, - true, - disable_nonce_validation, - ) - } - UserTransaction::Invoke(tx) => { - let executable = tx.into_executable::(chain_id, true); - executable.execute( - &mut BlockifierStateAdapter::::default(), - block_context, - true, - disable_nonce_validation, - ) - } - }; - execution_results.push(result); - } - storage::TransactionOutcome::Rollback(Ok(())) - }); - execution_results - } - let execution_results = execute_txs_and_rollback::( - transactions, + &transactions, &Self::get_block_context(), - T::DisableNonceValidation::get(), chain_id, - ); + &RuntimeExecutionConfigBuilder::new::().with_query_mode().build(), + )?; let mut results = vec![]; for res in execution_results { @@ -1166,6 +1123,90 @@ impl Pallet { Ok(results) } + pub fn simulate_transactions( + transactions: Vec, + simulation_flags: SimulationFlags, + ) -> Result, DispatchError> { + let chain_id = Self::chain_id(); + + let execution_results = execute_txs_and_rollback::( + &transactions, + &Self::get_block_context(), + chain_id, + &RuntimeExecutionConfigBuilder::new::().with_simulation_mode(&simulation_flags).build(), + )?; + + fn get_function_invocation( + call_info: Option<&CallInfo>, + ) -> TransactionExecutionResult> { + call_info.map(FunctionInvocation::try_from).transpose() + } + + let mut results = vec![]; + for (tx, res) in transactions.iter().zip(execution_results.iter()) { + match res { + Ok(tx_exec_info) => { + let validate_invocation = get_function_invocation(tx_exec_info.validate_call_info.as_ref()) + .map_err(|err| { + log::error!("Failed to convert validate call info to function invocation: {}", err); + Error::::TransactionExecutionFailed + })?; + let fee_transfer_invocation = get_function_invocation(tx_exec_info.fee_transfer_call_info.as_ref()) + .map_err(|err| { + log::error!("Failed to convert fee transfer call info to function invocation: {}", err); + Error::::TransactionExecutionFailed + })?; + let transaction_trace = match tx { + UserTransaction::Invoke(_) => TransactionTrace::Invoke(InvokeTransactionTrace { + validate_invocation, + execute_invocation: convert_call_info_to_execute_invocation::( + tx_exec_info + .execute_call_info + .as_ref() + .ok_or(Error::::TransactionExecutionFailed)?, + tx_exec_info.revert_error.as_ref(), + )?, + fee_transfer_invocation, + }), + UserTransaction::Declare(_, _) => TransactionTrace::Declare(DeclareTransactionTrace { + validate_invocation, + fee_transfer_invocation, + }), + UserTransaction::DeployAccount(_) => { + TransactionTrace::DeployAccount(DeployAccountTransactionTrace { + validate_invocation, + constructor_invocation: tx_exec_info + .execute_call_info + .as_ref() + .ok_or(Error::::TransactionExecutionFailed)? + .try_into() + .map_err(|_| Error::::TransactionExecutionFailed)?, + + fee_transfer_invocation, + }) + } + }; + let gas_consumed = tx_exec_info + .execute_call_info + .as_ref() + .map(|x| x.execution.gas_consumed) + .ok_or(Error::::TransactionExecutionFailed)?; + let overall_fee = tx_exec_info.actual_fee.0 as u64; + let gas_price = if gas_consumed > 0 { overall_fee / gas_consumed } else { 0 }; + results.push(SimulatedTransaction { + transaction_trace, + fee_estimation: FeeEstimate { gas_consumed, gas_price, overall_fee }, + }) + } + Err(e) => { + log::error!("Failed to simulate transactions: {:?}, error: {:?}", tx, e); + return Err(Error::::TransactionExecutionFailed.into()); + } + } + } + Ok(results) + } + pub fn emit_and_store_tx_and_fees_events( tx_hash: TransactionHash, execute_call_info: Option, diff --git a/crates/pallets/starknet/src/tests/query_tx.rs b/crates/pallets/starknet/src/tests/query_tx.rs index 25b98ef0d7..1aa008d773 100644 --- a/crates/pallets/starknet/src/tests/query_tx.rs +++ b/crates/pallets/starknet/src/tests/query_tx.rs @@ -4,7 +4,7 @@ use mp_transactions::compute_hash::ComputeTransactionHash; use mp_transactions::UserTransaction; use super::mock::default_mock::*; -use super::mock::*; +use super::mock::new_test_ext; use crate::tests::utils::sign_message_hash; use crate::tests::{get_invoke_argent_dummy, get_invoke_dummy, get_storage_read_write_dummy}; use crate::{Config, Error}; diff --git a/crates/pallets/starknet/src/utils.rs b/crates/pallets/starknet/src/utils.rs new file mode 100644 index 0000000000..50385aed0a --- /dev/null +++ b/crates/pallets/starknet/src/utils.rs @@ -0,0 +1,59 @@ +use alloc::string::String; +use alloc::vec::Vec; + +use blockifier::block_context::BlockContext; +use blockifier::execution::entry_point::CallInfo; +use blockifier::transaction::objects::{TransactionExecutionInfo, TransactionExecutionResult}; +use frame_support::storage; +use mp_felt::Felt252Wrapper; +use mp_simulations::{ExecuteInvocation, RevertedInvocation}; +use mp_transactions::execution::{Execute, ExecutionConfig}; +use mp_transactions::UserTransaction; +use sp_runtime::DispatchError; + +use crate::blockifier_state_adapter::BlockifierStateAdapter; +use crate::{pallet, Error}; + +pub fn execute_txs_and_rollback( + txs: &Vec, + block_context: &BlockContext, + chain_id: Felt252Wrapper, + execution_config: &ExecutionConfig, +) -> Result>, Error> { + let mut execution_results = vec![]; + storage::transactional::with_transaction(|| { + for tx in txs { + let result = match tx { + UserTransaction::Declare(tx, contract_class) => tx + .try_into_executable::(chain_id, contract_class.clone(), execution_config.is_query) + .and_then(|exec| { + exec.execute(&mut BlockifierStateAdapter::::default(), block_context, execution_config) + }), + UserTransaction::DeployAccount(tx) => { + let executable = tx.into_executable::(chain_id, execution_config.is_query); + executable.execute(&mut BlockifierStateAdapter::::default(), block_context, execution_config) + } + UserTransaction::Invoke(tx) => { + let executable = tx.into_executable::(chain_id, execution_config.is_query); + executable.execute(&mut BlockifierStateAdapter::::default(), block_context, execution_config) + } + }; + execution_results.push(result); + } + storage::TransactionOutcome::Rollback(Result::<_, DispatchError>::Ok(())) + }) + .map_err(|_| Error::::TransactionalExecutionFailed)?; + Ok(execution_results) +} + +pub fn convert_call_info_to_execute_invocation( + call_info: &CallInfo, + revert_error: Option<&String>, +) -> Result> { + if call_info.execution.failed { + return Ok(ExecuteInvocation::Reverted(RevertedInvocation { + revert_reason: revert_error.ok_or(Error::MissingRevertReason)?.clone(), + })); + } + Ok(ExecuteInvocation::Success(call_info.try_into().map_err(|_| Error::TransactionExecutionFailed)?)) +} diff --git a/crates/primitives/fee/src/lib.rs b/crates/primitives/fee/src/lib.rs index da89a49e85..392a2fc65f 100644 --- a/crates/primitives/fee/src/lib.rs +++ b/crates/primitives/fee/src/lib.rs @@ -14,7 +14,6 @@ use blockifier::block_context::BlockContext; use blockifier::execution::entry_point::{ CallEntryPoint, CallInfo, CallType, EntryPointExecutionContext, ExecutionResources, }; -use blockifier::state::cached_state::StateChangesCount; use blockifier::state::state_api::State; use blockifier::transaction::errors::TransactionExecutionError; use blockifier::transaction::objects::{AccountTransactionContext, ResourcesMapping, TransactionExecutionResult}; @@ -22,7 +21,7 @@ use blockifier::transaction::transaction_types::TransactionType; use blockifier::transaction::transaction_utils::{calculate_l1_gas_usage, calculate_tx_resources}; #[cfg(not(feature = "std"))] use hashbrown::HashMap; -use mp_state::{FeeConfig, StateChanges}; +use mp_state::StateChanges; use sp_arithmetic::fixed_point::{FixedPointNumber, FixedU128}; use sp_arithmetic::traits::Zero; use starknet_api::api_core::EntryPointSelector; @@ -63,14 +62,7 @@ pub fn compute_transaction_resources( tx_type: TransactionType, l1_handler_payload_size: Option, ) -> TransactionExecutionResult { - let (n_modified_contracts, n_storage_updates, n_class_hash_updates, n_compiled_class_hash_updates) = - state.count_state_changes(); - let state_changes_count = StateChangesCount { - n_storage_updates, - n_class_hash_updates, - n_compiled_class_hash_updates, - n_modified_contracts, - }; + let state_changes_count = state.count_state_changes(); let non_optional_call_infos: Vec<&CallInfo> = vec![execute_call_info, validate_call_info].into_iter().flatten().collect(); @@ -81,21 +73,30 @@ pub fn compute_transaction_resources( } /// Charges the fees for a specific execution resources. -pub fn charge_fee( +pub fn charge_fee( state: &mut S, block_context: &BlockContext, account_tx_context: AccountTransactionContext, resources: &ResourcesMapping, + disable_transaction_fee: bool, + disable_fee_charge: bool, ) -> TransactionExecutionResult<(Fee, Option)> { - if state.is_transaction_fee_disabled() { + // disable_transaction_fee flag implies that transaction fees have + // been disabled and so we return 0 as the fees + if disable_transaction_fee { return Ok((Fee(0), None)); } let actual_fee = calculate_tx_fee(resources, block_context)?; - // even if the user doesn't have enough balance - // estimate fee shouldn't fail - if account_tx_context.version.0 >= StarkFelt::try_from("0x100000000000000000000000000000000").unwrap() { + // Fee charging is skipped in the following cases: + // 1) If the tx version >= 0x100000000000000000000000000000000, the current transaction mode is a + // estimate fee transaction, so we don't charge fees + // 2) The disable_fee_charge flag is set + // in both cases we return the actual fee. + if disable_fee_charge + || account_tx_context.version.0 >= StarkFelt::try_from("0x100000000000000000000000000000000").unwrap() + { return Ok((actual_fee, None)); } diff --git a/crates/primitives/felt/Cargo.toml b/crates/primitives/felt/Cargo.toml index 9fee03efdf..258fe4f90c 100644 --- a/crates/primitives/felt/Cargo.toml +++ b/crates/primitives/felt/Cargo.toml @@ -13,6 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] cairo-vm = { workspace = true } sp-core = { workspace = true } +starknet-core = { workspace = true } starknet-ff = { workspace = true } starknet_api = { workspace = true } thiserror-no-std = { workspace = true } @@ -24,21 +25,24 @@ parity-scale-codec = { workspace = true, features = [ ], optional = true } scale-info = { workspace = true, features = ["derive"], optional = true } serde = { workspace = true, features = ["derive"], optional = true } +serde_with = { workspace = true, optional = true } [features] default = ["std"] parity-scale-codec = ["dep:parity-scale-codec", "dep:hex"] scale-info = ["dep:scale-info"] -serde = ["dep:serde", "starknet-ff/serde"] +serde = ["dep:serde", "starknet-ff/serde", "dep:serde_with"] std = [ "cairo-vm/std", "thiserror-no-std/std", "starknet_api/std", "sp-core/std", "starknet-ff/std", + "starknet-core/std", # Optional "parity-scale-codec?/std", "scale-info?/std", "serde?/std", "hex?/std", + "serde_with?/std", ] diff --git a/crates/primitives/felt/src/lib.rs b/crates/primitives/felt/src/lib.rs index 3c57af9313..361176b8f8 100644 --- a/crates/primitives/felt/src/lib.rs +++ b/crates/primitives/felt/src/lib.rs @@ -14,6 +14,9 @@ pub extern crate alloc; mod starkware_types_conversions; +#[cfg(feature = "serde")] +pub mod with_serde; + use alloc::string::{String, ToString}; use cairo_vm::felt::Felt252; @@ -26,6 +29,9 @@ use starknet_api::hash::StarkFelt; use starknet_ff::{FieldElement, FromByteSliceError, FromStrError}; use thiserror_no_std::Error; +#[cfg(feature = "serde")] +pub use crate::with_serde::*; + #[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Hash, Eq, Copy)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Felt252Wrapper(pub FieldElement); diff --git a/crates/primitives/felt/src/with_serde.rs b/crates/primitives/felt/src/with_serde.rs new file mode 100644 index 0000000000..f3bcac9474 --- /dev/null +++ b/crates/primitives/felt/src/with_serde.rs @@ -0,0 +1,15 @@ +use serde::Serializer; +use serde_with::SerializeAs; + +use crate::Felt252Wrapper; + +pub struct UfeHex; + +impl SerializeAs for UfeHex { + fn serialize_as(value: &Felt252Wrapper, serializer: S) -> Result + where + S: Serializer, + { + starknet_core::serde::unsigned_field_element::UfeHex::serialize_as::(&value.0, serializer) + } +} diff --git a/crates/primitives/simulations/Cargo.toml b/crates/primitives/simulations/Cargo.toml new file mode 100644 index 0000000000..8d32f10437 --- /dev/null +++ b/crates/primitives/simulations/Cargo.toml @@ -0,0 +1,48 @@ +[package] +name = "mp-simulations" +version.workspace = true +edition.workspace = true +license = "MIT" +description = "Starknet chain ids" +authors = { workspace = true } +repository = { workspace = true } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +serde = { workspace = true, features = ["derive"], optional = true } +serde_with = { workspace = true, optional = true } + +# Madara primitives +mp-felt = { workspace = true } + +# Substrate dependencies +parity-scale-codec = { workspace = true, optional = true } +scale-info = { workspace = true, optional = true } + +# Starknet dependencies +blockifier = { workspace = true } +starknet-core = { workspace = true } +starknet_api = { workspace = true } + +[features] +default = ["std"] +parity-scale-codec = [ + "dep:parity-scale-codec", + "starknet_api/parity-scale-codec", + "mp-felt/parity-scale-codec", +] +serde = ["dep:serde", "dep:serde_with", "mp-felt/serde"] +scale-info = ["dep:scale-info", "starknet_api/scale-info"] +std = [ + "mp-felt/std", + "starknet_api/std", + "blockifier/std", + "starknet-core/std", + # Optional + "parity-scale-codec?/std", + "scale-info?/std", + "serde?/std", + "serde_with?/std", +] diff --git a/crates/primitives/simulations/src/lib.rs b/crates/primitives/simulations/src/lib.rs new file mode 100644 index 0000000000..fd12d2da2d --- /dev/null +++ b/crates/primitives/simulations/src/lib.rs @@ -0,0 +1,278 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +#[doc(hidden)] +pub extern crate alloc; + +use alloc::collections::BTreeMap; +use alloc::string::String; +use alloc::vec::Vec; + +use blockifier::execution::entry_point::{CallInfo, OrderedL2ToL1Message}; +use blockifier::transaction::errors::TransactionExecutionError; +use blockifier::transaction::objects::TransactionExecutionResult; +use mp_felt::{Felt252Wrapper, UfeHex}; +use starknet_api::api_core::EthAddress; +use starknet_api::deprecated_contract_class::EntryPointType; +use starknet_api::transaction::EventContent; + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SimulationFlags { + pub skip_validate: bool, + pub skip_fee_charge: bool, +} + +impl From> for SimulationFlags { + fn from(flags: Vec) -> Self { + let mut skip_validate = false; + let mut skip_fee_charge = false; + + for flag in flags { + match flag { + SimulationFlag::SkipValidate => skip_validate = true, + SimulationFlag::SkipFeeCharge => skip_fee_charge = true, + } + if skip_validate && skip_fee_charge { + break; + } + } + + Self { skip_validate, skip_fee_charge } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum SimulationFlag { + #[serde(rename = "SKIP_VALIDATE")] + SkipValidate, + #[serde(rename = "SKIP_FEE_CHARGE")] + SkipFeeCharge, +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct SimulatedTransaction { + /// The transaction's trace + pub transaction_trace: TransactionTrace, + /// The transaction's resources and fee + pub fee_estimation: FeeEstimate, +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[serde(untagged)] +pub enum TransactionTrace { + Invoke(InvokeTransactionTrace), + DeployAccount(DeployAccountTransactionTrace), + L1Handler(L1HandlerTransactionTrace), + Declare(DeclareTransactionTrace), +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct FeeEstimate { + /// The Ethereum gas cost of the transaction (see + /// https://docs.starknet.io/docs/fees/fee-mechanism for more info) + pub gas_consumed: u64, + /// The gas price (in gwei) that was used in the cost estimation + pub gas_price: u64, + /// The estimated fee for the transaction (in gwei), product of gas_consumed and gas_price + pub overall_fee: u64, +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct DeclareTransactionTrace { + #[serde(skip_serializing_if = "Option::is_none")] + pub validate_invocation: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_transfer_invocation: Option, +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct InvokeTransactionTrace { + #[serde(skip_serializing_if = "Option::is_none")] + pub validate_invocation: Option, + pub execute_invocation: ExecuteInvocation, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_transfer_invocation: Option, +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct DeployAccountTransactionTrace { + #[serde(skip_serializing_if = "Option::is_none")] + pub validate_invocation: Option, + /// The trace of the __execute__ call or constructor call, depending on the transaction type + /// (none for declare transactions) + pub constructor_invocation: FunctionInvocation, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_transfer_invocation: Option, +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct L1HandlerTransactionTrace { + /// The trace of the __execute__ call or constructor call, depending on the transaction type + /// (none for declare transactions) + pub function_invocation: FunctionInvocation, +} + +#[serde_with::serde_as] +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct MessageToL1 { + /// The address of the L2 contract sending the message + #[serde_as(as = "UfeHex")] + pub from_address: Felt252Wrapper, + /// The target L1 address the message is sent to + pub to_address: EthAddress, + /// The payload of the message + #[serde_as(as = "Vec")] + pub payload: Vec, +} + +#[serde_with::serde_as] +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct FunctionInvocation { + /// Contract address + #[serde_as(as = "UfeHex")] + pub contract_address: Felt252Wrapper, + /// Entry point selector + #[serde_as(as = "UfeHex")] + pub entry_point_selector: Felt252Wrapper, + /// The parameters passed to the function + #[serde_as(as = "Vec")] + pub calldata: Vec, + /// The address of the invoking contract. 0 for the root invocation + #[serde_as(as = "UfeHex")] + pub caller_address: Felt252Wrapper, + /// The hash of the class being called + #[serde_as(as = "Option")] + pub class_hash: Option, + pub entry_point_type: EntryPointType, + pub call_type: CallType, + /// The value returned from the function invocation + #[serde_as(as = "Vec")] + pub result: Vec, + /// The calls made by this invocation + pub calls: Vec, + /// The events emitted in this invocation + pub events: Vec, + /// The messages sent by this invocation to L1 + pub messages: Vec, +} + +impl TryFrom<&CallInfo> for FunctionInvocation { + type Error = TransactionExecutionError; + + fn try_from(call_info: &CallInfo) -> TransactionExecutionResult { + let messages = ordered_l2_to_l1_messages(call_info); + + let inner_calls = call_info + .inner_calls + .iter() + .map(|call| call.try_into()) + .collect::>()?; + + call_info.get_sorted_l2_to_l1_payloads_length()?; + + Ok(FunctionInvocation { + contract_address: call_info.call.storage_address.0.0.into(), + entry_point_selector: call_info.call.entry_point_selector.0.into(), + calldata: call_info.call.calldata.0.iter().map(|x| (*x).into()).collect(), + caller_address: call_info.call.caller_address.0.0.into(), + class_hash: call_info.call.class_hash.map(|x| x.0.into()), + entry_point_type: call_info.call.entry_point_type, + call_type: call_info.call.call_type.into(), + result: call_info.execution.retdata.0.iter().map(|x| (*x).into()).collect(), + calls: inner_calls, + events: call_info.execution.events.iter().map(|event| event.event.clone()).collect(), + messages, + }) + } +} + +fn ordered_l2_to_l1_messages(call_info: &CallInfo) -> Vec { + let mut messages = BTreeMap::new(); + + for call in call_info.into_iter() { + for OrderedL2ToL1Message { order, message } in &call.execution.l2_to_l1_messages { + messages.insert( + order, + MessageToL1 { + payload: message.payload.0.iter().map(|x| (*x).into()).collect(), + to_address: message.to_address, + from_address: call.call.storage_address.0.0.into(), + }, + ); + } + } + + messages.into_values().collect() +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[serde(untagged)] +pub enum ExecuteInvocation { + Success(FunctionInvocation), + Reverted(RevertedInvocation), +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct RevertedInvocation { + /// The revert reason for the failed execution + pub revert_reason: String, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "parity-scale-codec", derive(parity_scale_codec::Encode, parity_scale_codec::Decode))] +#[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum CallType { + #[serde(rename = "CALL")] + Call, + #[serde(rename = "LIBRARY_CALL")] + LibraryCall, +} + +impl From for CallType { + fn from(value: blockifier::execution::entry_point::CallType) -> Self { + use blockifier::execution::entry_point::CallType::*; + match value { + Call => Self::Call, + Delegate => Self::LibraryCall, + } + } +} diff --git a/crates/primitives/state/src/lib.rs b/crates/primitives/state/src/lib.rs index 1278cb41ae..c97d2d59d8 100644 --- a/crates/primitives/state/src/lib.rs +++ b/crates/primitives/state/src/lib.rs @@ -1,7 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use blockifier::execution::contract_class::ContractClass; -use blockifier::state::cached_state::ContractStorageKey; +use blockifier::state::cached_state::{ContractStorageKey, StateChangesCount}; use blockifier::state::errors::StateError; use blockifier::state::state_api::{StateReader, StateResult}; use starknet_api::api_core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; @@ -16,24 +16,7 @@ type ContractClassMapping = HashMap; pub trait StateChanges { /// This function counts the storage var updates implied by a transaction and the newly declared /// class hashes. - /// - /// # Returns - /// - /// * `usize` - The number of modified contracts in the transaction. - /// * `usize` - The number of modified storage vars in the transaction. - /// * `usize` - The number of newly declared classes. - fn count_state_changes(&self) -> (usize, usize, usize, usize); -} - -/// This trait allows to get the fee config for the pallet and accordingly charge the fees -pub trait FeeConfig { - /// This function reads the DisableTransactionFee from the pallet and returns a boolean - /// class hashes. - /// - /// # Returns - /// - /// * `bool` - Is the fee disabled - fn is_transaction_fee_disabled(&self) -> bool; + fn count_state_changes(&self) -> StateChangesCount; } /// A simple implementation of `StateReader` using `HashMap`s as storage. diff --git a/crates/primitives/transactions/Cargo.toml b/crates/primitives/transactions/Cargo.toml index 999638fe12..37e6b51dc8 100644 --- a/crates/primitives/transactions/Cargo.toml +++ b/crates/primitives/transactions/Cargo.toml @@ -13,6 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] blockifier = { workspace = true } derive_more = { workspace = true, features = ["from"] } +log = { workspace = true } mp-fee = { workspace = true } mp-felt = { workspace = true } mp-hashers = { workspace = true } diff --git a/crates/primitives/transactions/src/execution.rs b/crates/primitives/transactions/src/execution.rs index f6495c9137..e2f81fb200 100644 --- a/crates/primitives/transactions/src/execution.rs +++ b/crates/primitives/transactions/src/execution.rs @@ -24,7 +24,7 @@ use blockifier::transaction::transactions::{ }; use mp_fee::{calculate_tx_fee, charge_fee, compute_transaction_resources}; use mp_felt::Felt252Wrapper; -use mp_state::{FeeConfig, StateChanges}; +use mp_state::StateChanges; use starknet_api::api_core::{ContractAddress, EntryPointSelector, Nonce}; use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::hash::StarkFelt; @@ -34,6 +34,25 @@ use super::SIMULATE_TX_VERSION_OFFSET; const TX_INITIAL_AVAILABLE_GAS: u64 = INITIAL_GAS_COST - TRANSACTION_GAS_COST; +/// Contains the execution configuration regarding transaction fee +/// activation, transaction fee charging, nonce validation, transaction +/// validation and the execution mode (query or not). +/// Use [`RuntimeExecutionConfigBuilder`] to build this struct in the runtime. +#[derive(Debug, Clone)] +pub struct ExecutionConfig { + /// If true, the transaction is a query. + pub is_query: bool, + /// If true, transaction fee calculation and charging + /// is disabled for all transactions. + pub disable_transaction_fee: bool, + /// If true, fee charging is disabled for all transactions. + pub disable_fee_charge: bool, + /// If true, nonce validation is disabled for all transactions. + pub disable_nonce_validation: bool, + /// If true, transaction validation is disabled for all transactions. + pub disable_validation: bool, +} + pub struct ValidateExecuteCallInfo { pub validate_call_info: Option, pub execute_call_info: Option, @@ -267,13 +286,14 @@ pub trait Validate: GetAccountTransactionContext + GetTransactionCalldata { } pub trait Execute: Sized + GetAccountTransactionContext + GetTransactionCalldata + GetTxType { - fn execute_inner( + fn execute_inner( &self, state: &mut S, block_context: &BlockContext, resources: &mut ExecutionResources, remaining_gas: &mut u64, account_tx_context: &AccountTransactionContext, + disable_validation: bool, ) -> TransactionExecutionResult; fn handle_nonce( @@ -301,20 +321,29 @@ pub trait Execute: Sized + GetAccountTransactionContext + GetTransactionCalldata } /// Handles nonce and checks that the account's balance covers max fee. - fn handle_nonce_and_check_fee_balance( - state: &mut dyn State, + fn handle_nonce_and_check_fee_balance( + state: &mut S, block_context: &BlockContext, account_tx_context: &AccountTransactionContext, - disable_nonce_validation: bool, + execution_config: &ExecutionConfig, ) -> TransactionExecutionResult<()> { // Handle nonce. - - if !disable_nonce_validation { + if !execution_config.disable_nonce_validation { Self::handle_nonce(account_tx_context, state)?; } - // Check fee balance. - if account_tx_context.max_fee != Fee(0) { + // Check fee balance. Skipped in the following cases: + // 1. account_tx_context.max_fee - balance would always be enough if max_fee is 0 + // 2. disable_fee_charge - true during simulate transactions + // 3. disable_fee_charge - true when fees is disabled at app level + // 4. is_query - true during estimate_fee transactions. estimate_fee transactions normally have + // max_fee = 0 but they should also work if max_fee > 0 + if account_tx_context.max_fee != Fee(0) + && !execution_config.disable_fee_charge + && !execution_config.disable_transaction_fee + && !execution_config.is_query + { + log::debug!("Inside checking balance"); let (balance_low, balance_high) = state.get_fee_token_balance(block_context, &account_tx_context.sender_address)?; @@ -330,20 +359,19 @@ pub trait Execute: Sized + GetAccountTransactionContext + GetTransactionCalldata Ok(()) } - fn execute( + fn execute( &self, state: &mut S, block_context: &BlockContext, - is_query: bool, - disable_nonce_validation: bool, + execution_config: &ExecutionConfig, ) -> TransactionExecutionResult { let mut execution_resources = ExecutionResources::default(); let mut remaining_gas = TX_INITIAL_AVAILABLE_GAS; - let account_tx_context = self.get_account_transaction_context(is_query); + let account_tx_context = self.get_account_transaction_context(execution_config.is_query); // Nonce and fee check should be done before running user code. - Self::handle_nonce_and_check_fee_balance(state, block_context, &account_tx_context, disable_nonce_validation)?; + Self::handle_nonce_and_check_fee_balance(state, block_context, &account_tx_context, execution_config)?; // execute let ValidateExecuteCallInfo { validate_call_info, execute_call_info, revert_error } = self.execute_inner( @@ -352,6 +380,7 @@ pub trait Execute: Sized + GetAccountTransactionContext + GetTransactionCalldata &mut execution_resources, &mut remaining_gas, &account_tx_context, + execution_config.disable_validation, )?; let (actual_fee, fee_transfer_call_info, actual_resources) = self.handle_fee( @@ -361,6 +390,7 @@ pub trait Execute: Sized + GetAccountTransactionContext + GetTransactionCalldata &mut execution_resources, block_context, account_tx_context, + execution_config, )?; let tx_execution_info = TransactionExecutionInfo { @@ -375,7 +405,8 @@ pub trait Execute: Sized + GetAccountTransactionContext + GetTransactionCalldata Ok(tx_execution_info) } - fn handle_fee( + #[allow(clippy::too_many_arguments)] + fn handle_fee( &self, state: &mut S, execute_call_info: &Option, @@ -383,6 +414,7 @@ pub trait Execute: Sized + GetAccountTransactionContext + GetTransactionCalldata execution_resources: &mut ExecutionResources, block_context: &BlockContext, account_tx_context: AccountTransactionContext, + execution_config: &ExecutionConfig, ) -> TransactionExecutionResult<(Fee, Option, ResourcesMapping)> { let actual_resources = compute_transaction_resources( state, @@ -393,8 +425,14 @@ pub trait Execute: Sized + GetAccountTransactionContext + GetTransactionCalldata None, )?; - let (actual_fee, fee_transfer_call_info) = - charge_fee(state, block_context, account_tx_context, &actual_resources)?; + let (actual_fee, fee_transfer_call_info) = charge_fee( + state, + block_context, + account_tx_context, + &actual_resources, + execution_config.disable_transaction_fee, + execution_config.disable_fee_charge, + )?; Ok((actual_fee, fee_transfer_call_info, actual_resources)) } @@ -405,13 +443,14 @@ impl Validate for InvokeTransaction { } impl Execute for InvokeTransaction { - fn execute_inner( + fn execute_inner( &self, state: &mut S, block_context: &BlockContext, resources: &mut ExecutionResources, remaining_gas: &mut u64, account_tx_context: &AccountTransactionContext, + disable_validation: bool, ) -> TransactionExecutionResult { let mut context = EntryPointExecutionContext::new( block_context.clone(), @@ -419,13 +458,17 @@ impl Execute for InvokeTransaction { block_context.invoke_tx_max_n_steps, ); - let validate_call_info = self.validate_tx_inner( - state, - resources, - remaining_gas, - &mut context, - GetTransactionCalldata::calldata(self), - )?; + let validate_call_info = if !disable_validation { + self.validate_tx_inner( + state, + resources, + remaining_gas, + &mut context, + GetTransactionCalldata::calldata(self), + )? + } else { + None + }; let validate_execute_call_info = match self.tx { // V0 tx cannot revert, we cannot charge the failling ones starknet_api::transaction::InvokeTransaction::V0(_) => { @@ -437,7 +480,10 @@ impl Execute for InvokeTransaction { Ok(execute_call_info) => { ValidateExecuteCallInfo::new_accepted(validate_call_info, execute_call_info) } - Err(_) => ValidateExecuteCallInfo::new_reverted(validate_call_info, context.error_trace()), + Err(e) => { + log::debug!("Invoke transaction reverted with error: {:?}", e); + ValidateExecuteCallInfo::new_reverted(validate_call_info, context.error_trace()) + } } } }; @@ -451,13 +497,14 @@ impl Validate for DeclareTransaction { } impl Execute for DeclareTransaction { - fn execute_inner( + fn execute_inner( &self, state: &mut S, block_context: &BlockContext, resources: &mut ExecutionResources, remaining_gas: &mut u64, account_tx_context: &AccountTransactionContext, + disable_validation: bool, ) -> TransactionExecutionResult { let mut context = EntryPointExecutionContext::new( block_context.clone(), @@ -465,8 +512,11 @@ impl Execute for DeclareTransaction { block_context.invoke_tx_max_n_steps, ); - let validate_call_info = - self.validate_tx_inner(state, resources, remaining_gas, &mut context, self.calldata())?; + let validate_call_info = if !disable_validation { + self.validate_tx_inner(state, resources, remaining_gas, &mut context, self.calldata())? + } else { + None + }; let validate_execute_call_info = match self.tx() { // V0 tx cannot revert, we cannot charge the failling ones starknet_api::transaction::DeclareTransaction::V0(_) => { @@ -493,13 +543,14 @@ impl Validate for DeployAccountTransaction { } impl Execute for DeployAccountTransaction { - fn execute_inner( + fn execute_inner( &self, state: &mut S, block_context: &BlockContext, resources: &mut ExecutionResources, remaining_gas: &mut u64, account_tx_context: &AccountTransactionContext, + disable_validation: bool, ) -> TransactionExecutionResult { let mut context = EntryPointExecutionContext::new( block_context.clone(), @@ -510,21 +561,25 @@ impl Execute for DeployAccountTransaction { // In order to be verified the tx must first be executed // so that the `constructor` method can initialize the account state let execute_call_info = self.run_execute(state, resources, &mut context, remaining_gas)?; - let validate_call_info = - self.validate_tx_inner(state, resources, remaining_gas, &mut context, self.calldata())?; + let validate_call_info = if !disable_validation { + self.validate_tx_inner(state, resources, remaining_gas, &mut context, self.calldata())? + } else { + None + }; Ok(ValidateExecuteCallInfo::new_accepted(validate_call_info, execute_call_info)) } } impl Execute for L1HandlerTransaction { - fn execute_inner( + fn execute_inner( &self, state: &mut S, block_context: &BlockContext, resources: &mut ExecutionResources, remaining_gas: &mut u64, account_tx_context: &AccountTransactionContext, + _disable_validation: bool, ) -> TransactionExecutionResult { let mut context = EntryPointExecutionContext::new( block_context.clone(), @@ -538,7 +593,7 @@ impl Execute for L1HandlerTransaction { } // No fee are charged for L1HandlerTransaction - fn handle_fee( + fn handle_fee( &self, state: &mut S, execute_call_info: &Option, @@ -546,6 +601,7 @@ impl Execute for L1HandlerTransaction { execution_resources: &mut ExecutionResources, block_context: &BlockContext, _account_tx_context: AccountTransactionContext, + _execution_config: &ExecutionConfig, ) -> TransactionExecutionResult<(Fee, Option, ResourcesMapping)> { // The calldata includes the "from" field, which is not a part of the payload. let l1_handler_payload_size = self.calldata().0.len() - 1; diff --git a/crates/runtime/Cargo.toml b/crates/runtime/Cargo.toml index 52a6db7375..033419578c 100644 --- a/crates/runtime/Cargo.toml +++ b/crates/runtime/Cargo.toml @@ -56,9 +56,11 @@ pallet-starknet-runtime-api = { workspace = true } mp-chain-id = { workspace = true } mp-felt = { workspace = true } mp-hashers = { workspace = true } +mp-simulations = { workspace = true } mp-transactions = { workspace = true } # Starknet dependencies blockifier = { workspace = true } +starknet-core = { workspace = true } starknet-ff = { workspace = true } starknet_api = { workspace = true } diff --git a/crates/runtime/src/lib.rs b/crates/runtime/src/lib.rs index 2dbe163616..ad532dff92 100644 --- a/crates/runtime/src/lib.rs +++ b/crates/runtime/src/lib.rs @@ -28,6 +28,7 @@ pub use frame_support::{construct_runtime, parameter_types, StorageValue}; pub use frame_system::Call as SystemCall; use frame_system::{EventRecord, Phase}; use mp_felt::Felt252Wrapper; +use mp_simulations::{SimulatedTransaction, SimulationFlags}; use mp_transactions::compute_hash::ComputeTransactionHash; use mp_transactions::{Transaction, UserTransaction}; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; @@ -266,6 +267,10 @@ impl_runtime_apis! { Starknet::estimate_fee(transactions) } + fn simulate_transactions(transactions: Vec, simulation_flags: SimulationFlags) -> Result, DispatchError> { + Starknet::simulate_transactions(transactions, simulation_flags) + } + fn get_starknet_events_and_their_associated_tx_hash(block_extrinsics: Vec<::Extrinsic>, chain_id: Felt252Wrapper) -> Vec<(Felt252Wrapper, StarknetEvent)> { System::read_events_no_consensus().filter_map(|event_record| { let (phase, event) = match *event_record { diff --git a/starknet-rpc-test/Cargo.toml b/starknet-rpc-test/Cargo.toml index 61589a2e76..00b416dbe4 100644 --- a/starknet-rpc-test/Cargo.toml +++ b/starknet-rpc-test/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" anyhow = "1.0.72" assert_matches = "1.5.0" async-lock = "3.1.0" +async-trait = { workspace = true } flate2 = { workspace = true } reqwest = "0.11.18" rstest = "0.18.1" @@ -108,3 +109,7 @@ path = "get_events.rs" [[test]] name = "starknet_estimate_fee" path = "estimate_fee.rs" + +[[test]] +name = "starknet_simulate_transaction" +path = "simulate_transaction.rs" diff --git a/starknet-rpc-test/estimate_fee.rs b/starknet-rpc-test/estimate_fee.rs index c349ac4156..73636f9e98 100644 --- a/starknet-rpc-test/estimate_fee.rs +++ b/starknet-rpc-test/estimate_fee.rs @@ -3,10 +3,11 @@ extern crate starknet_rpc_test; use assert_matches::assert_matches; use rstest::rstest; use starknet_core::types::{BlockId, BlockTag, BroadcastedInvokeTransaction, BroadcastedTransaction, StarknetError}; +use starknet_core::utils::get_selector_from_name; use starknet_ff::FieldElement; use starknet_providers::ProviderError::StarknetError as StarknetProviderError; use starknet_providers::{MaybeUnknownErrorCode, Provider, StarknetErrorWithMessage}; -use starknet_rpc_test::constants::ACCOUNT_CONTRACT; +use starknet_rpc_test::constants::{ACCOUNT_CONTRACT, TEST_CONTRACT_ADDRESS}; use starknet_rpc_test::fixtures::{madara, ThreadSafeMadaraClient}; #[rstest] @@ -20,11 +21,10 @@ async fn fail_non_existing_block(madara: &ThreadSafeMadaraClient) -> Result<(), nonce: FieldElement::ZERO, sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), calldata: vec![ - FieldElement::from_hex_be("5a02acdbf218464be3dd787df7a302f71fab586cad5588410ba88b3ed7b3a21").unwrap(), - FieldElement::from_hex_be("3d7905601c217734671143d457f0db37f7f8883112abd34b92c4abfeafde0c3").unwrap(), - FieldElement::from_hex_be("2").unwrap(), - FieldElement::from_hex_be("e150b6c2db6ed644483b01685571de46d2045f267d437632b508c19f3eb877").unwrap(), - FieldElement::from_hex_be("494196e88ce16bff11180d59f3c75e4ba3475d9fba76249ab5f044bcd25add6").unwrap(), + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), ], is_query: true, }); @@ -51,19 +51,16 @@ async fn fail_if_one_txn_cannot_be_executed(madara: &ThreadSafeMadaraClient) -> is_query: true, }); - // from mainnet tx: 0x000c52079f33dcb44a58904fac3803fd908ac28d6632b67179ee06f2daccb4b5 - // https://starkscan.co/tx/0x000c52079f33dcb44a58904fac3803fd908ac28d6632b67179ee06f2daccb4b5 let ok_invoke_transaction = BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { max_fee: FieldElement::ZERO, signature: vec![], nonce: FieldElement::ZERO, sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), calldata: vec![ - FieldElement::from_hex_be("5a02acdbf218464be3dd787df7a302f71fab586cad5588410ba88b3ed7b3a21").unwrap(), - FieldElement::from_hex_be("3d7905601c217734671143d457f0db37f7f8883112abd34b92c4abfeafde0c3").unwrap(), - FieldElement::from_hex_be("2").unwrap(), - FieldElement::from_hex_be("e150b6c2db6ed644483b01685571de46d2045f267d437632b508c19f3eb877").unwrap(), - FieldElement::from_hex_be("494196e88ce16bff11180d59f3c75e4ba3475d9fba76249ab5f044bcd25add6").unwrap(), + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), ], is_query: true, }); @@ -90,17 +87,14 @@ async fn works_ok(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> nonce: FieldElement::ZERO, sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), calldata: vec![ - FieldElement::from_hex_be("5a02acdbf218464be3dd787df7a302f71fab586cad5588410ba88b3ed7b3a21").unwrap(), - FieldElement::from_hex_be("3d7905601c217734671143d457f0db37f7f8883112abd34b92c4abfeafde0c3").unwrap(), - FieldElement::from_hex_be("2").unwrap(), - FieldElement::from_hex_be("e150b6c2db6ed644483b01685571de46d2045f267d437632b508c19f3eb877").unwrap(), - FieldElement::from_hex_be("494196e88ce16bff11180d59f3c75e4ba3475d9fba76249ab5f044bcd25add6").unwrap(), + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), ], is_query: true, }; - // from mainnet tx: 0x000c52079f33dcb44a58904fac3803fd908ac28d6632b67179ee06f2daccb4b5 - // https://starkscan.co/tx/0x000c52079f33dcb44a58904fac3803fd908ac28d6632b67179ee06f2daccb4b5 let invoke_transaction = BroadcastedTransaction::Invoke(tx.clone()); let invoke_transaction_2 = @@ -111,8 +105,8 @@ async fn works_ok(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> // TODO: instead execute the tx and check that the actual fee are the same as the estimated ones assert_eq!(estimates.len(), 2); - assert_eq!(estimates[0].overall_fee, 410); - assert_eq!(estimates[1].overall_fee, 410); + assert_eq!(estimates[0].overall_fee, 420); + assert_eq!(estimates[1].overall_fee, 420); // https://starkscan.co/block/5 assert_eq!(estimates[0].gas_consumed, 0); assert_eq!(estimates[1].gas_consumed, 0); diff --git a/starknet-rpc-test/get_transaction_receipt.rs b/starknet-rpc-test/get_transaction_receipt.rs index 7d1a8ee058..a1eb8d85ec 100644 --- a/starknet-rpc-test/get_transaction_receipt.rs +++ b/starknet-rpc-test/get_transaction_receipt.rs @@ -37,7 +37,7 @@ async fn get_transaction_receipt( async fn work_with_invoke_transaction(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> { let rpc = madara.get_starknet_client().await; - let recepient = FieldElement::from_hex_be("0x123").unwrap(); + let recipient = FieldElement::from_hex_be("0x123").unwrap(); let transfer_amount = FieldElement::ONE; let mut txs = { @@ -45,7 +45,7 @@ async fn work_with_invoke_transaction(madara: &ThreadSafeMadaraClient) -> Result let account = build_single_owner_account(&rpc, SIGNER_PRIVATE, ARGENT_CONTRACT_ADDRESS, true); madara_write_lock .create_block_with_txs(vec![Transaction::Execution(account.transfer_tokens( - recepient, + recipient, transfer_amount, None, ))]) @@ -76,7 +76,7 @@ async fn work_with_invoke_transaction(madara: &ThreadSafeMadaraClient) -> Result keys: vec![get_selector_from_name("Transfer").unwrap()], data: vec![ FieldElement::from_hex_be(ARGENT_CONTRACT_ADDRESS).unwrap(), // from - recepient, // to + recipient, // to transfer_amount, // value low FieldElement::ZERO, // value high ], diff --git a/starknet-rpc-test/simulate_transaction.rs b/starknet-rpc-test/simulate_transaction.rs new file mode 100644 index 0000000000..569f8a81d2 --- /dev/null +++ b/starknet-rpc-test/simulate_transaction.rs @@ -0,0 +1,242 @@ +extern crate starknet_rpc_test; + +use assert_matches::assert_matches; +use rstest::rstest; +use starknet_accounts::{Call, ConnectedAccount}; +use starknet_core::types::{ + BlockId, BlockTag, BroadcastedInvokeTransaction, BroadcastedTransaction, SimulationFlag, StarknetError, +}; +use starknet_core::utils::get_selector_from_name; +use starknet_ff::FieldElement; +use starknet_providers::ProviderError::StarknetError as StarknetProviderError; +use starknet_providers::{MaybeUnknownErrorCode, Provider, StarknetErrorWithMessage}; +use starknet_rpc_test::constants::{ACCOUNT_CONTRACT, ARGENT_CONTRACT_ADDRESS, SIGNER_PRIVATE, TEST_CONTRACT_ADDRESS}; +use starknet_rpc_test::fixtures::{madara, ThreadSafeMadaraClient}; +use starknet_rpc_test::utils::{build_single_owner_account, AccountActions}; + +#[rstest] +#[tokio::test] +async fn fail_non_existing_block(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> { + let rpc = madara.get_starknet_client().await; + + let ok_invoke_transaction = BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { + max_fee: FieldElement::ZERO, + signature: vec![], + nonce: FieldElement::ZERO, + sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), + calldata: vec![ + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), + ], + is_query: false, + }); + + assert_matches!( + rpc.simulate_transactions(BlockId::Hash(FieldElement::ZERO),&[ok_invoke_transaction], []).await, + Err(StarknetProviderError(StarknetErrorWithMessage { code: MaybeUnknownErrorCode::Known(code), .. })) if code == StarknetError::BlockNotFound + ); + + Ok(()) +} + +#[rstest] +#[tokio::test] +async fn fail_max_fee_too_big(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> { + let rpc = madara.get_starknet_client().await; + + let ok_invoke_transaction = BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { + max_fee: FieldElement::from_hex_be("0x100000000000000000000000000000000").unwrap(), // u128::MAX + 1 + signature: vec![], + nonce: FieldElement::ZERO, + sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), + calldata: vec![ + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), + ], + is_query: false, + }); + + assert_matches!( + rpc.simulate_transactions(BlockId::Tag(BlockTag::Latest), &[ok_invoke_transaction], []).await, + Err(StarknetProviderError(StarknetErrorWithMessage { code: MaybeUnknownErrorCode::Unknown(500), message })) if message == "Internal server error" + ); + + Ok(()) +} + +#[rstest] +#[tokio::test] +async fn fail_if_one_txn_cannot_be_executed(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> { + let rpc = madara.get_starknet_client().await; + + let bad_invoke_transaction = BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { + max_fee: FieldElement::default(), + nonce: FieldElement::ZERO, + sender_address: FieldElement::default(), + signature: vec![], + calldata: vec![FieldElement::from_hex_be("0x0").unwrap()], + is_query: false, + }); + + let ok_invoke_transaction = BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { + max_fee: FieldElement::ZERO, + signature: vec![], + nonce: FieldElement::ZERO, + sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), + calldata: vec![ + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), + ], + is_query: false, + }); + + assert_matches!( + rpc.simulate_transactions(BlockId::Tag(BlockTag::Latest),&[ + bad_invoke_transaction, + ok_invoke_transaction, + ],[] ).await, + Err(StarknetProviderError(StarknetErrorWithMessage { code: MaybeUnknownErrorCode::Known(code), .. })) if code == StarknetError::ContractError + ); + + Ok(()) +} + +#[rstest] +#[tokio::test] +async fn works_ok_on_no_validate(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> { + let rpc = madara.get_starknet_client().await; + + let tx = BroadcastedInvokeTransaction { + max_fee: FieldElement::from(420u16), + signature: vec![], + nonce: FieldElement::ZERO, + sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), + calldata: vec![ + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), + ], + is_query: false, + }; + + let invoke_transaction = BroadcastedTransaction::Invoke(tx.clone()); + + let invoke_transaction_2 = + BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { nonce: FieldElement::ONE, ..tx }); + + let simulations = rpc + .simulate_transactions(BlockId::Tag(BlockTag::Latest), &[invoke_transaction, invoke_transaction_2], []) + .await?; + + assert_eq!(simulations.len(), 2); + assert_eq!(simulations[0].fee_estimation.gas_consumed, 0); + assert_eq!(simulations[0].fee_estimation.overall_fee, 420); + assert_eq!(simulations[0].fee_estimation.gas_price, 0); + + Ok(()) +} + +#[rstest] +#[tokio::test] +async fn works_ok_on_validate_with_signature(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> { + let rpc = madara.get_starknet_client().await; + let funding_account = build_single_owner_account(&rpc, SIGNER_PRIVATE, ARGENT_CONTRACT_ADDRESS, true); + let nonce = funding_account.get_nonce().await?; + let max_fee = FieldElement::from(1000u16); + + let calls = vec![Call { + to: FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + selector: get_selector_from_name("sqrt").unwrap(), + calldata: vec![FieldElement::from(81u8)], + }]; + let tx = funding_account.prepare_invoke(calls, nonce, max_fee, false).await; + + let invoke_transaction = BroadcastedTransaction::Invoke(tx); + + let simulations = rpc.simulate_transactions(BlockId::Tag(BlockTag::Latest), &[invoke_transaction], []).await?; + + assert_eq!(simulations.len(), 1); + assert_eq!(simulations[0].fee_estimation.gas_consumed, 0); + assert_eq!(simulations[0].fee_estimation.overall_fee, 480); + assert_eq!(simulations[0].fee_estimation.gas_price, 0); + + Ok(()) +} + +#[rstest] +#[tokio::test] +async fn works_ok_on_validate_without_signature_with_skip_validate( + madara: &ThreadSafeMadaraClient, +) -> Result<(), anyhow::Error> { + let rpc = madara.get_starknet_client().await; + let funding_account = build_single_owner_account(&rpc, SIGNER_PRIVATE, ARGENT_CONTRACT_ADDRESS, true); + let nonce = funding_account.get_nonce().await?; + let max_fee = FieldElement::from(1000u16); + + let calls = vec![Call { + to: FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + selector: get_selector_from_name("sqrt").unwrap(), + calldata: vec![FieldElement::from(81u8)], + }]; + let tx = funding_account.prepare_invoke(calls, nonce, max_fee, false).await; + + let invoke_transaction = BroadcastedTransaction::Invoke(tx); + + let simulations = rpc + .simulate_transactions(BlockId::Tag(BlockTag::Latest), &[invoke_transaction], [SimulationFlag::SkipValidate]) + .await?; + + assert_eq!(simulations.len(), 1); + assert_eq!(simulations[0].fee_estimation.gas_consumed, 0); + assert_eq!(simulations[0].fee_estimation.overall_fee, 440); + assert_eq!(simulations[0].fee_estimation.gas_price, 0); + + Ok(()) +} + +#[rstest] +#[tokio::test] +async fn works_ok_without_max_fee_with_skip_fee_charge(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> { + let rpc = madara.get_starknet_client().await; + + let tx = BroadcastedInvokeTransaction { + max_fee: FieldElement::from(0u8), + signature: vec![], + nonce: FieldElement::ZERO, + sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), + calldata: vec![ + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), + ], + is_query: false, + }; + + let invoke_transaction = BroadcastedTransaction::Invoke(tx.clone()); + + let invoke_transaction_2 = + BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { nonce: FieldElement::ONE, ..tx }); + + let simulations = rpc + .simulate_transactions( + BlockId::Tag(BlockTag::Latest), + &[invoke_transaction, invoke_transaction_2], + [SimulationFlag::SkipFeeCharge], + ) + .await?; + + assert_eq!(simulations.len(), 2); + assert_eq!(simulations[0].fee_estimation.gas_consumed, 0); + assert_eq!(simulations[0].fee_estimation.overall_fee, 420); + assert_eq!(simulations[0].fee_estimation.gas_price, 0); + + Ok(()) +} diff --git a/starknet-rpc-test/spec_version.rs b/starknet-rpc-test/spec_version.rs index 41dd9feafe..334083a761 100644 --- a/starknet-rpc-test/spec_version.rs +++ b/starknet-rpc-test/spec_version.rs @@ -1,18 +1,11 @@ extern crate starknet_rpc_test; use rstest::rstest; -use starknet_providers::Provider; -use starknet_rpc_test::constants::SPEC_VERSION; use starknet_rpc_test::fixtures::{madara, ThreadSafeMadaraClient}; #[rstest] #[tokio::test] #[ignore = "Waiting for starknet_providers::jsonrpc upgrade to v0.6.0"] async fn returns_hardcoded_spec_version(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> { - let rpc = madara.get_starknet_client().await; - - // TODO: test it when starknet_providers::jsonrpc upgrades to v0.6.0 - // assert_eq!(rpc.spec_version().await?, SPEC_VERSION); - Ok(()) } diff --git a/starknet-rpc-test/src/lib.rs b/starknet-rpc-test/src/lib.rs index 6dbe2766d2..f4797c840a 100644 --- a/starknet-rpc-test/src/lib.rs +++ b/starknet-rpc-test/src/lib.rs @@ -29,7 +29,7 @@ const NODE_RPC_URL: &str = "http://localhost:9944"; type RpcAccount<'a> = SingleOwnerAccount<&'a JsonRpcClient, LocalWallet>; pub type RpcOzAccountFactory<'a> = OpenZeppelinAccountFactory>; -type TransactionExecution<'a> = Execution<'a, RpcAccount<'a>>; +pub type TransactionExecution<'a> = Execution<'a, RpcAccount<'a>>; type TransactionDeclaration<'a> = Declaration<'a, RpcAccount<'a>>; type TransactionLegacyDeclaration<'a> = LegacyDeclaration<'a, RpcAccount<'a>>; type TransactionAccountDeployment<'a> = AccountDeployment<'a, RpcOzAccountFactory<'a>>; diff --git a/starknet-rpc-test/src/utils.rs b/starknet-rpc-test/src/utils.rs index c7348971da..d0c159f187 100644 --- a/starknet-rpc-test/src/utils.rs +++ b/starknet-rpc-test/src/utils.rs @@ -1,11 +1,14 @@ use std::future::Future; use std::sync::Arc; -use starknet_accounts::{Account, AccountFactory, Call, OpenZeppelinAccountFactory, SingleOwnerAccount}; +use async_trait::async_trait; +use starknet_accounts::{ + Account, AccountFactory, Call, ConnectedAccount, Execution, OpenZeppelinAccountFactory, SingleOwnerAccount, +}; use starknet_core::chain_id; use starknet_core::types::contract::legacy::LegacyContractClass; use starknet_core::types::contract::{CompiledClass, SierraClass}; -use starknet_core::types::{BlockId, BlockTag, FieldElement, FunctionCall, MsgToL1}; +use starknet_core::types::{BlockId, BlockTag, BroadcastedInvokeTransaction, FieldElement, FunctionCall, MsgToL1}; use starknet_core::utils::get_selector_from_name; use starknet_providers::jsonrpc::{HttpTransport, JsonRpcClient}; use starknet_providers::Provider; @@ -72,6 +75,7 @@ pub fn build_deploy_account_tx<'a>( oz_factory.deploy(contract_address_salt).max_fee(max_fee) } +#[async_trait] pub trait AccountActions { fn transfer_tokens_u256( &self, @@ -94,6 +98,20 @@ pub trait AccountActions { ) -> (TransactionDeclaration, FieldElement, FieldElement); fn declare_legacy_contract(&self, path_to_compiled_contract: &str) -> (TransactionLegacyDeclaration, FieldElement); + + async fn prepare_invoke( + &self, + calls: Vec, + nonce: FieldElement, + max_fee: FieldElement, + query_only: bool, + ) -> BroadcastedInvokeTransaction + where + Self: Account + ConnectedAccount, + { + let prepared_execution = Execution::new(calls, self).nonce(nonce).max_fee(max_fee).prepared().unwrap(); + prepared_execution.get_invoke_request(query_only).await.unwrap() + } } impl AccountActions for SingleOwnerAccount<&JsonRpcClient, LocalWallet> {