diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68de387ca9..dcb238f9c1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -190,5 +190,9 @@ jobs: curl --location --remote-name https://github.com/Orange-OpenSource/hurl/releases/download/3.0.0/hurl_3.0.0_amd64.deb sudo apt update && sudo apt install ./hurl_3.0.0_amd64.deb chmod +x /tmp/bins/katana + chmod +x /tmp/bins/sozo nohup /tmp/bins/katana --accounts 2 --disable-fee & + - run: | + /tmp/bins/sozo --manifest-path examples/spawn-and-move/Scarb.toml build + /tmp/bins/sozo --manifest-path examples/spawn-and-move/Scarb.toml migrate apply - run: hurl --test examples/rpc/**/*.hurl diff --git a/Cargo.lock b/Cargo.lock index 3efd806e95..a661166da3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,27 +15,28 @@ dependencies = [ [[package]] name = "account_sdk" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/controller?rev=e8276cfffe48b5d09f0598026d13635374204b72#e8276cfffe48b5d09f0598026d13635374204b72" +source = "git+https://github.com/cartridge-gg/controller?branch=bump-starknet#366484fe7f19aa3fffef3929f8a00b753062fbdc" dependencies = [ "anyhow", "async-trait", "base64 0.21.7", - "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f)", - "cairo-lang-starknet 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", + "cairo-lang-starknet 2.6.4", "coset", "ecdsa", "futures", "indexmap 2.2.6", "js-sys", "lazy_static", + "num-traits 0.2.19", "p256", "primitive-types", "rand_core", "serde", "serde_json", "sha2 0.10.8", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "thiserror", "tokio", "toml 0.8.14", @@ -144,7 +145,7 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-consensus 0.1.3", "alloy-contract 0.1.3", @@ -188,7 +189,7 @@ dependencies = [ [[package]] name = "alloy-consensus" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-eips 0.1.3", "alloy-primitives", @@ -219,7 +220,7 @@ dependencies = [ [[package]] name = "alloy-contract" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -280,7 +281,7 @@ dependencies = [ [[package]] name = "alloy-eips" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -305,7 +306,7 @@ dependencies = [ [[package]] name = "alloy-genesis" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-primitives", "alloy-serde 0.1.3", @@ -339,7 +340,7 @@ dependencies = [ [[package]] name = "alloy-json-rpc" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-primitives", "serde", @@ -368,7 +369,7 @@ dependencies = [ [[package]] name = "alloy-network" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-consensus 0.1.3", "alloy-eips 0.1.3", @@ -387,7 +388,7 @@ dependencies = [ [[package]] name = "alloy-node-bindings" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-genesis 0.1.3", "alloy-primitives", @@ -453,7 +454,7 @@ dependencies = [ [[package]] name = "alloy-provider" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-chains", "alloy-consensus 0.1.3", @@ -486,9 +487,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b155716bab55763c95ba212806cf43d05bcc70e5f35b02bad20cf5ec7fe11fed" +checksum = "a43b18702501396fa9bcdeecd533bc85fac75150d308fc0f6800a01e6234a003" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -497,9 +498,9 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8037e03c7f462a063f28daec9fda285a9a89da003c552f8637a80b9c8fd96241" +checksum = "d83524c1f6162fcb5b0decf775498a125066c86dda6066ed609531b0e912f85a" dependencies = [ "proc-macro2", "quote", @@ -529,7 +530,7 @@ dependencies = [ [[package]] name = "alloy-rpc-client" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-json-rpc 0.1.3", "alloy-transport 0.1.3", @@ -567,7 +568,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-primitives", "alloy-serde 0.1.3", @@ -577,7 +578,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-consensus 0.1.3", "alloy-eips 0.1.3", @@ -616,7 +617,7 @@ dependencies = [ [[package]] name = "alloy-serde" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-primitives", "serde", @@ -639,7 +640,7 @@ dependencies = [ [[package]] name = "alloy-signer" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-primitives", "async-trait", @@ -652,7 +653,7 @@ dependencies = [ [[package]] name = "alloy-signer-local" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-consensus 0.1.3", "alloy-network 0.1.3", @@ -757,7 +758,7 @@ dependencies = [ [[package]] name = "alloy-transport" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-json-rpc 0.1.3", "base64 0.22.1", @@ -788,7 +789,7 @@ dependencies = [ [[package]] name = "alloy-transport-http" version = "0.1.3" -source = "git+https://github.com/alloy-rs/alloy#60cd429bd036c16f1e1f23ec7950689ad9819c76" +source = "git+https://github.com/alloy-rs/alloy#78807cbd0e659873c32d373af963031f71bde8a2" dependencies = [ "alloy-json-rpc 0.1.3", "alloy-transport 0.1.3", @@ -1682,7 +1683,7 @@ dependencies = [ "serde_json", "sozo", "sozo-ops", - "starknet", + "starknet 0.11.0", "tokio", ] @@ -2087,20 +2088,22 @@ checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "cainome" version = "0.2.3" -source = "git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f#a84dfe0f54116116f5a3c79642cd4111b1d4a5ac" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.3.0#6c82c5b8e8169a79fe5606f963a3afdf0aa37078" dependencies = [ "anyhow", "async-trait", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f)", - "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f)", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", + "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", + "cainome-rs-macro 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "camino", "clap", "clap_complete", "convert_case 0.6.0", "serde", "serde_json", - "starknet", + "starknet 0.11.0", + "starknet-types-core", "thiserror", "tracing", "tracing-subscriber", @@ -2110,21 +2113,22 @@ dependencies = [ [[package]] name = "cainome" version = "0.2.3" -source = "git+https://github.com/cartridge-gg/cainome?rev=ec18eea5#ec18eea55a5c3c563dc502c051a8df3dfab118a9" +source = "git+https://github.com/cartridge-gg/cainome?rev=e67d925#e67d9259fc562cf743a1a22e5a936e66e073592a" dependencies = [ "anyhow", "async-trait", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", - "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", - "cainome-rs-macro", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", + "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", + "cainome-rs-macro 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", "camino", "clap", "clap_complete", "convert_case 0.6.0", "serde", "serde_json", - "starknet", + "starknet 0.11.0", + "starknet-types-core", "thiserror", "tracing", "tracing-subscriber", @@ -2134,32 +2138,32 @@ dependencies = [ [[package]] name = "cainome-cairo-serde" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f#a84dfe0f54116116f5a3c79642cd4111b1d4a5ac" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.3.0#6c82c5b8e8169a79fe5606f963a3afdf0aa37078" dependencies = [ "serde", - "starknet", + "starknet 0.11.0", "thiserror", ] [[package]] name = "cainome-cairo-serde" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?rev=ec18eea5#ec18eea55a5c3c563dc502c051a8df3dfab118a9" +source = "git+https://github.com/cartridge-gg/cainome?rev=e67d925#e67d9259fc562cf743a1a22e5a936e66e073592a" dependencies = [ "serde", - "starknet", + "starknet 0.11.0", "thiserror", ] [[package]] name = "cainome-parser" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f#a84dfe0f54116116f5a3c79642cd4111b1d4a5ac" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.3.0#6c82c5b8e8169a79fe5606f963a3afdf0aa37078" dependencies = [ "convert_case 0.6.0", "quote", "serde_json", - "starknet", + "starknet 0.11.0", "syn 2.0.68", "thiserror", ] @@ -2167,12 +2171,12 @@ dependencies = [ [[package]] name = "cainome-parser" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?rev=ec18eea5#ec18eea55a5c3c563dc502c051a8df3dfab118a9" +source = "git+https://github.com/cartridge-gg/cainome?rev=e67d925#e67d9259fc562cf743a1a22e5a936e66e073592a" dependencies = [ "convert_case 0.6.0", "quote", "serde_json", - "starknet", + "starknet 0.11.0", "syn 2.0.68", "thiserror", ] @@ -2180,17 +2184,17 @@ dependencies = [ [[package]] name = "cainome-rs" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f#a84dfe0f54116116f5a3c79642cd4111b1d4a5ac" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.3.0#6c82c5b8e8169a79fe5606f963a3afdf0aa37078" dependencies = [ "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=a84dfe0f)", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "camino", "prettyplease 0.2.20", "proc-macro2", "quote", "serde_json", - "starknet", + "starknet 0.11.0", "syn 2.0.68", "thiserror", ] @@ -2198,17 +2202,17 @@ dependencies = [ [[package]] name = "cainome-rs" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?rev=ec18eea5#ec18eea55a5c3c563dc502c051a8df3dfab118a9" +source = "git+https://github.com/cartridge-gg/cainome?rev=e67d925#e67d9259fc562cf743a1a22e5a936e66e073592a" dependencies = [ "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", "camino", "prettyplease 0.2.20", "proc-macro2", "quote", "serde_json", - "starknet", + "starknet 0.11.0", "syn 2.0.68", "thiserror", ] @@ -2216,16 +2220,33 @@ dependencies = [ [[package]] name = "cainome-rs-macro" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?rev=ec18eea5#ec18eea55a5c3c563dc502c051a8df3dfab118a9" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.3.0#6c82c5b8e8169a79fe5606f963a3afdf0aa37078" dependencies = [ "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", - "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", + "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "proc-macro2", "quote", "serde_json", - "starknet", + "starknet 0.11.0", + "syn 2.0.68", + "thiserror", +] + +[[package]] +name = "cainome-rs-macro" +version = "0.1.0" +source = "git+https://github.com/cartridge-gg/cainome?rev=e67d925#e67d9259fc562cf743a1a22e5a936e66e073592a" +dependencies = [ + "anyhow", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", + "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?rev=e67d925)", + "proc-macro2", + "quote", + "serde_json", + "starknet 0.11.0", "syn 2.0.68", "thiserror", ] @@ -2245,10 +2266,9 @@ dependencies = [ [[package]] name = "cairo-lang-casm" version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d9c31baeb6b52586b5adc88f01e90f86389d63d94363c562de5c79352e545b" +source = "git+https://github.com/starkware-libs/cairo?tag=v2.6.3#2203a47f8a098cd4718d03bd109ca014049419e7" dependencies = [ - "cairo-lang-utils 2.6.4", + "cairo-lang-utils 2.6.3 (git+https://github.com/starkware-libs/cairo?tag=v2.6.3)", "indoc 2.0.5", "num-bigint", "num-traits 0.2.19", @@ -2259,9 +2279,9 @@ dependencies = [ [[package]] name = "cairo-lang-casm" version = "2.6.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.6.3#2203a47f8a098cd4718d03bd109ca014049419e7" +source = "git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632#d9984ef58e2f704909e271f2f01327f520ded632" dependencies = [ - "cairo-lang-utils 2.6.3 (git+https://github.com/starkware-libs/cairo?tag=v2.6.3)", + "cairo-lang-utils 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", "indoc 2.0.5", "num-bigint", "num-traits 0.2.19", @@ -2271,10 +2291,11 @@ dependencies = [ [[package]] name = "cairo-lang-casm" -version = "2.6.3" -source = "git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632#d9984ef58e2f704909e271f2f01327f520ded632" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6296d5748288d9fb97175d31aff9f68ea3f602456923895e512b078e9a2210a0" dependencies = [ - "cairo-lang-utils 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", + "cairo-lang-utils 2.6.4", "indoc 2.0.5", "num-bigint", "num-traits 0.2.19", @@ -2915,7 +2936,7 @@ dependencies = [ "sha2 0.10.8", "smol_str", "starknet-crypto 0.6.2", - "starknet-types-core 0.1.4", + "starknet-types-core", "thiserror", ] @@ -3040,7 +3061,7 @@ dependencies = [ "serde_json", "sha3", "smol_str", - "starknet-types-core 0.1.4", + "starknet-types-core", "thiserror", ] @@ -3227,27 +3248,6 @@ dependencies = [ "smol_str", ] -[[package]] -name = "cairo-lang-sierra-to-casm" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3c3be88c8562fbf93b0803c186e7282f6daad93576c07f61b04a591fde468f" -dependencies = [ - "assert_matches", - "cairo-felt", - "cairo-lang-casm 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cairo-lang-sierra 2.6.4", - "cairo-lang-sierra-ap-change 2.6.4", - "cairo-lang-sierra-gas 2.6.4", - "cairo-lang-sierra-type-size 2.6.4", - "cairo-lang-utils 2.6.4", - "indoc 2.0.5", - "itertools 0.11.0", - "num-bigint", - "num-traits 0.2.19", - "thiserror", -] - [[package]] name = "cairo-lang-sierra-to-casm" version = "2.6.3" @@ -3284,7 +3284,28 @@ dependencies = [ "itertools 0.12.1", "num-bigint", "num-traits 0.2.19", - "starknet-types-core 0.1.4", + "starknet-types-core", + "thiserror", +] + +[[package]] +name = "cairo-lang-sierra-to-casm" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ac02c90be2630ae861db6af226090da92741020519768332dd2c07e24d94c75" +dependencies = [ + "assert_matches", + "cairo-felt", + "cairo-lang-casm 2.6.4", + "cairo-lang-sierra 2.6.4", + "cairo-lang-sierra-ap-change 2.6.4", + "cairo-lang-sierra-gas 2.6.4", + "cairo-lang-sierra-type-size 2.6.4", + "cairo-lang-utils 2.6.4", + "indoc 2.0.5", + "itertools 0.11.0", + "num-bigint", + "num-traits 0.2.19", "thiserror", ] @@ -3316,37 +3337,6 @@ dependencies = [ "cairo-lang-utils 2.6.4", ] -[[package]] -name = "cairo-lang-starknet" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9ffa8b3b8c47138c36b1907cebb5047dfc4de29ec10ece5bd6d6853243ec50" -dependencies = [ - "anyhow", - "cairo-felt", - "cairo-lang-compiler 2.6.4", - "cairo-lang-defs 2.6.4", - "cairo-lang-diagnostics 2.6.4", - "cairo-lang-filesystem 2.6.4", - "cairo-lang-lowering 2.6.4", - "cairo-lang-plugins 2.6.4", - "cairo-lang-semantic 2.6.4", - "cairo-lang-sierra 2.6.4", - "cairo-lang-sierra-generator 2.6.4", - "cairo-lang-starknet-classes 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cairo-lang-syntax 2.6.4", - "cairo-lang-utils 2.6.4", - "const_format", - "indent", - "indoc 2.0.5", - "itertools 0.11.0", - "once_cell", - "serde", - "serde_json", - "smol_str", - "thiserror", -] - [[package]] name = "cairo-lang-starknet" version = "2.6.3" @@ -3403,32 +3393,38 @@ dependencies = [ "serde", "serde_json", "smol_str", - "starknet-types-core 0.1.4", + "starknet-types-core", "thiserror", ] [[package]] -name = "cairo-lang-starknet-classes" -version = "2.6.3" +name = "cairo-lang-starknet" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c64ae2bb00173e3a88760128bf72de356fa80eb19fa47602479063648b4003" +checksum = "a27921a2bf82d191d28afd570b913341080c8fc25c83bf870dbf1252570b1b41" dependencies = [ + "anyhow", "cairo-felt", - "cairo-lang-casm 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-compiler 2.6.4", + "cairo-lang-defs 2.6.4", + "cairo-lang-diagnostics 2.6.4", + "cairo-lang-filesystem 2.6.4", + "cairo-lang-lowering 2.6.4", + "cairo-lang-plugins 2.6.4", + "cairo-lang-semantic 2.6.4", "cairo-lang-sierra 2.6.4", - "cairo-lang-sierra-to-casm 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-generator 2.6.4", + "cairo-lang-starknet-classes 2.6.4", + "cairo-lang-syntax 2.6.4", "cairo-lang-utils 2.6.4", - "convert_case 0.6.0", + "const_format", + "indent", + "indoc 2.0.5", "itertools 0.11.0", - "num-bigint", - "num-integer", - "num-traits 0.2.19", "once_cell", "serde", "serde_json", - "sha3", "smol_str", - "starknet-crypto 0.6.2", "thiserror", ] @@ -3476,7 +3472,32 @@ dependencies = [ "sha3", "smol_str", "starknet-crypto 0.6.2", - "starknet-types-core 0.1.4", + "starknet-types-core", + "thiserror", +] + +[[package]] +name = "cairo-lang-starknet-classes" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8623b076ef3569e4262da5da270a84658b1ff242fe0c9624fbe432e7a937d101" +dependencies = [ + "cairo-felt", + "cairo-lang-casm 2.6.4", + "cairo-lang-sierra 2.6.4", + "cairo-lang-sierra-to-casm 2.6.4", + "cairo-lang-utils 2.6.4", + "convert_case 0.6.0", + "itertools 0.11.0", + "num-bigint", + "num-integer", + "num-traits 0.2.19", + "once_cell", + "serde", + "serde_json", + "sha3", + "smol_str", + "starknet-crypto 0.6.2", "thiserror", ] @@ -3578,7 +3599,7 @@ dependencies = [ "num-bigint", "num-traits 0.2.19", "serde", - "starknet-types-core 0.1.4", + "starknet-types-core", ] [[package]] @@ -3600,7 +3621,7 @@ dependencies = [ "itertools 0.12.1", "num-traits 0.2.19", "rayon", - "starknet-types-core 0.1.4", + "starknet-types-core", ] [[package]] @@ -3665,7 +3686,7 @@ dependencies = [ [[package]] name = "cairo-proof-parser" version = "0.3.0" -source = "git+https://github.com/cartridge-gg/cairo-proof-parser?tag=v0.3.0#1cd7af307609d0f6a602a59d124d5044e56cc7b4" +source = "git+https://github.com/cartridge-gg/cairo-proof-parser?branch=v0.3.0/new-felt#c2b95715c053c2ab81ae605ab30527ecbafa4f03" dependencies = [ "anyhow", "clap", @@ -3674,8 +3695,9 @@ dependencies = [ "regex", "serde", "serde_json", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", + "starknet-types-core", "tokio", "url", ] @@ -3735,7 +3757,7 @@ dependencies = [ "sha2 0.10.8", "sha3", "starknet-crypto 0.6.2", - "starknet-types-core 0.1.4", + "starknet-types-core", "thiserror-no-std", "zip", ] @@ -3789,9 +3811,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.101" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac367972e516d45567c7eafc73d24e1c193dcf200a8d94e9db7b3d38b349572d" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" dependencies = [ "jobserver", "libc", @@ -3977,7 +3999,7 @@ dependencies = [ "num-traits 0.2.19", "serde", "wasm-bindgen", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -4043,9 +4065,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" dependencies = [ "clap_builder", "clap_derive", @@ -4063,9 +4085,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" dependencies = [ "anstream", "anstyle", @@ -4075,18 +4097,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.6" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbca90c87c2a04da41e95d1856e8bcd22f159bdbfa147314d2ce5218057b0e58" +checksum = "1d598e88f6874d4b888ed40c71efbcbf4076f1dfbae128a08a8c9e45f710605d" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -4172,7 +4194,7 @@ dependencies = [ "prefix-hex", "serde", "serde_json", - "serde_with 3.8.1", + "serde_with 3.8.3", ] [[package]] @@ -5049,7 +5071,7 @@ name = "dojo-bindgen" version = "0.7.3" dependencies = [ "async-trait", - "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "camino", "chrono", "convert_case 0.6.0", @@ -5058,7 +5080,7 @@ dependencies = [ "scarb", "serde", "serde_json", - "starknet", + "starknet 0.11.0", "thiserror", ] @@ -5113,7 +5135,7 @@ dependencies = [ "serde_json", "serde_with 2.3.3", "smol_str", - "starknet", + "starknet 0.11.0", "test-log", "thiserror", "toml 0.8.14", @@ -5174,7 +5196,8 @@ dependencies = [ "serde_json", "serde_with 2.3.3", "smol_str", - "starknet", + "starknet 0.10.0", + "starknet 0.11.0", "thiserror", "tokio", "toml 0.8.14", @@ -5186,13 +5209,14 @@ dependencies = [ name = "dojo-types" version = "0.7.3" dependencies = [ - "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "crypto-bigint", "hex", "itertools 0.12.1", + "num-traits 0.2.19", "serde", "serde_json", - "starknet", + "starknet 0.11.0", "strum 0.25.0", "strum_macros 0.25.3", "thiserror", @@ -5206,7 +5230,7 @@ dependencies = [ "assert_fs", "assert_matches", "async-trait", - "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "cairo-lang-filesystem 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", "cairo-lang-project 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", "cairo-lang-starknet 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", @@ -5220,14 +5244,15 @@ dependencies = [ "http 0.2.12", "ipfs-api-backend-hyper", "katana-runner", + "num-traits 0.2.19", "scarb", "serde", "serde_json", "serde_with 2.3.3", "similar-asserts", "smol_str", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "tempfile", "thiserror", "tokio", @@ -6074,9 +6099,9 @@ dependencies = [ [[package]] name = "gix-actor" -version = "0.31.2" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69c59d392c7e6c94385b6fd6089d6df0fe945f32b4357687989f3aee253cd7f" +checksum = "d9b8ee65074b2bbb91d9d97c15d172ea75043aefebf9869b5b329149dc76501c" dependencies = [ "bstr 1.9.1", "gix-date", @@ -6433,9 +6458,9 @@ dependencies = [ [[package]] name = "gix-mailmap" -version = "0.23.3" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f69655c4706db2545f2d78723db30ac15738811de0bc14963135d06666392279" +checksum = "7cb2da346958252cbc8656529f5479830a3bc6046f3d86405c9e77f71dfdf7b2" dependencies = [ "bstr 1.9.1", "gix-actor", @@ -6461,9 +6486,9 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.42.2" +version = "0.42.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe2dc4a41191c680c942e6ebd630c8107005983c4679214fdb1007dcf5ae1df" +checksum = "25da2f46b4e7c2fa7b413ce4dffb87f69eaf89c2057e386491f4c55cadbfe386" dependencies = [ "bstr 1.9.1", "gix-actor", @@ -7349,9 +7374,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" dependencies = [ "bytes", "futures-channel", @@ -7430,7 +7455,7 @@ checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.3.1", + "hyper 1.4.0", "hyper-util", "rustls 0.23.10", "rustls-pki-types", @@ -7473,7 +7498,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.3.1", + "hyper 1.4.0", "hyper-util", "native-tls", "tokio", @@ -7483,16 +7508,16 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" dependencies = [ "bytes", "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.0", - "hyper 1.3.1", + "hyper 1.4.0", "pin-project-lite", "socket2 0.5.7", "tokio", @@ -7632,12 +7657,12 @@ dependencies = [ [[package]] name = "imara-diff" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8" +checksum = "af13c8ceb376860ff0c6a66d83a8cdd4ecd9e464da24621bbffcd02b49619434" dependencies = [ "ahash", - "hashbrown 0.12.3", + "hashbrown 0.14.5", ] [[package]] @@ -8430,8 +8455,6 @@ dependencies = [ "anyhow", "assert_matches", "async-trait", - "cairo-lang-casm 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cairo-lang-starknet 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-vm 0.9.2", "convert_case 0.6.0", "derive_more", @@ -8447,13 +8470,14 @@ dependencies = [ "katana-tasks", "lazy_static", "metrics", + "num-traits 0.2.19", "parking_lot 0.12.3", "rand", "reqwest 0.12.5", "serde", "serde_json", "serde_with 2.3.3", - "starknet", + "starknet 0.11.0", "starknet_api", "tempfile", "thiserror", @@ -8478,7 +8502,7 @@ dependencies = [ "roaring", "serde", "serde_json", - "starknet", + "starknet 0.11.0", "starknet_api", "tempfile", "thiserror", @@ -8504,7 +8528,7 @@ dependencies = [ "rstest_reuse", "serde_json", "similar-asserts", - "starknet", + "starknet 0.11.0", "starknet_api", "thiserror", "tokio", @@ -8536,13 +8560,14 @@ dependencies = [ "flate2", "katana-cairo", "lazy_static", + "num-traits 0.2.19", "rand", "serde", "serde_json", "serde_with 2.3.3", "similar-asserts", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "starknet_api", "strum 0.25.0", "strum_macros 0.25.3", @@ -8567,7 +8592,7 @@ dependencies = [ "rstest 0.18.2", "rstest_reuse", "serde_json", - "starknet", + "starknet 0.11.0", "tempfile", "thiserror", "tokio", @@ -8582,7 +8607,7 @@ dependencies = [ "alloy", "anyhow", "assert_matches", - "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "cairo-lang-starknet 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", "cairo-lang-starknet-classes 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", "dojo-metrics", @@ -8603,11 +8628,12 @@ dependencies = [ "katana-runner", "katana-tasks", "metrics", + "num-traits 0.2.19", "rand", "serde", "serde_json", "serde_with 2.3.3", - "starknet", + "starknet 0.11.0", "starknet_api", "tempfile", "thiserror", @@ -8626,7 +8652,7 @@ dependencies = [ "katana-core", "katana-primitives", "katana-rpc-types", - "starknet", + "starknet 0.11.0", ] [[package]] @@ -8642,11 +8668,12 @@ dependencies = [ "katana-executor", "katana-primitives", "katana-provider", + "num-traits 0.2.19", "rstest 0.18.2", "serde", "serde_json", "serde_with 2.3.3", - "starknet", + "starknet 0.11.0", "thiserror", ] @@ -8659,7 +8686,7 @@ dependencies = [ "katana-primitives", "katana-provider", "katana-rpc-types", - "starknet", + "starknet 0.11.0", ] [[package]] @@ -8673,7 +8700,7 @@ dependencies = [ "runner-macro", "serde", "serde_json", - "starknet", + "starknet 0.11.0", "tokio", "url", ] @@ -8690,7 +8717,7 @@ dependencies = [ "katana-primitives", "serde_json", "slot", - "starknet", + "starknet 0.11.0", "tracing", ] @@ -8798,18 +8825,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb5d4f22241504f7c7b8d2c3a7d7835d7c07117f10bff2a7d96a9ef6ef217c3" dependencies = [ - "lambdaworks-math 0.7.0", + "lambdaworks-math", "serde", "sha2 0.10.8", "sha3", ] -[[package]] -name = "lambdaworks-math" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee7dcab3968c71896b8ee4dc829147acc918cffe897af6265b1894527fe3add" - [[package]] name = "lambdaworks-math" version = "0.7.0" @@ -8859,7 +8880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" dependencies = [ "cfg-if", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -9506,9 +9527,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" dependencies = [ "value-bag", ] @@ -9717,9 +9738,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -10125,9 +10146,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits 0.2.19", @@ -10311,9 +10332,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] @@ -10549,7 +10570,7 @@ dependencies = [ "libc", "redox_syscall 0.5.2", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -10638,9 +10659,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -10649,9 +10670,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -10659,9 +10680,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", @@ -10672,9 +10693,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -11310,7 +11331,7 @@ dependencies = [ "reqwest_cookie_store", "serde", "serde_json", - "serde_with 3.8.1", + "serde_with 3.8.3", "thiserror", "tokio", "tracing", @@ -11772,7 +11793,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.0", "http-body-util", - "hyper 1.3.1", + "hyper 1.4.0", "hyper-rustls 0.27.2", "hyper-tls 0.6.0", "hyper-util", @@ -11875,9 +11896,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.37" +version = "0.8.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +checksum = "a7439be6844e40133eda024efd85bf07f59d0dd2f59b10c00dd6cfb92cc5c741" dependencies = [ "bytemuck", ] @@ -11933,9 +11954,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7699249cc2c7d71939f30868f47e9d7add0bdc030d90ee10bfd16887ff8bb1c8" +checksum = "8f4b84ba6e838ceb47b41de5194a60244fac43d9fe03b71dbe8c5a201081d6d1" dependencies = [ "bytemuck", "byteorder", @@ -12245,7 +12266,7 @@ dependencies = [ "once_cell", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.4", + "rustls-webpki 0.102.5", "subtle", "zeroize", ] @@ -12299,9 +12320,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.102.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -12412,8 +12433,8 @@ dependencies = [ "katana-rpc-api", "saya-core", "serde_json", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "tokio", "tracing", "tracing-subscriber", @@ -12426,6 +12447,7 @@ version = "0.7.3" dependencies = [ "anyhow", "async-trait", + "bigdecimal 0.4.5", "cairo-felt", "cairo-proof-parser", "cairo-vm 0.9.2", @@ -12453,9 +12475,9 @@ dependencies = [ "serde", "serde_json", "serde_with 2.3.3", - "starknet", - "starknet-crypto 0.6.2", - "starknet-types-core 0.0.9", + "starknet 0.11.0", + "starknet-crypto 0.7.1", + "starknet-types-core", "starknet_api", "thiserror", "tokio", @@ -12482,10 +12504,11 @@ dependencies = [ "katana-rpc-api", "katana-rpc-types", "lazy_static", + "num-traits 0.2.19", "serde", "serde_json", "serde_with 2.3.3", - "starknet", + "starknet 0.11.0", "starknet_api", "thiserror", "tokio", @@ -12872,9 +12895,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.118" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -12952,9 +12975,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.8.1" +version = "3.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +checksum = "e73139bc5ec2d45e6c5fd85be5a46949c1c39a4c18e56915f5eb4c12f975e377" dependencies = [ "base64 0.22.1", "chrono", @@ -12964,7 +12987,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "serde_with_macros 3.8.1", + "serde_with_macros 3.8.3", "time", ] @@ -12982,9 +13005,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.1" +version = "3.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +checksum = "b80d3d6b56b64335c0180e5ffde23b3c5e08c14c585b51a15bd0e95393f46703" dependencies = [ "darling 0.20.9", "proc-macro2", @@ -13204,7 +13227,7 @@ dependencies = [ [[package]] name = "slot" version = "0.8.0" -source = "git+https://github.com/cartridge-gg/slot?rev=1d0c9f7#1d0c9f79122202bb448279f68c97092413e72cd3" +source = "git+https://github.com/cartridge-gg/slot?rev=4c1165d#4c1165d8308495f8de57a8ac52362ce8322e545b" dependencies = [ "anyhow", "axum", @@ -13215,7 +13238,7 @@ dependencies = [ "serde", "serde_json", "serde_with 2.3.3", - "starknet", + "starknet 0.11.0", "tempfile", "thiserror", "tokio", @@ -13325,7 +13348,7 @@ dependencies = [ "assert_fs", "async-trait", "bigdecimal 0.4.5", - "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "cairo-lang-compiler 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", "cairo-lang-defs 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", "cairo-lang-filesystem 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", @@ -13367,8 +13390,8 @@ dependencies = [ "smol_str", "snapbox", "sozo-ops", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "thiserror", "tokio", "tracing", @@ -13384,7 +13407,8 @@ dependencies = [ "anyhow", "assert_fs", "async-trait", - "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "bigdecimal 0.4.5", + "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "cairo-lang-compiler 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", "cairo-lang-defs 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", "cairo-lang-filesystem 2.6.3 (git+https://github.com/starkware-libs/cairo?rev=d9984ef58e2f704909e271f2f01327f520ded632)", @@ -13408,6 +13432,8 @@ dependencies = [ "futures", "ipfs-api-backend-hyper", "katana-runner", + "num-bigint", + "num-traits 0.2.19", "rpassword", "scarb", "scarb-ui", @@ -13416,8 +13442,8 @@ dependencies = [ "serde_json", "serde_with 2.3.3", "smol_str", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "thiserror", "tokio", "toml 0.8.14", @@ -13430,7 +13456,7 @@ name = "sozo-signers" version = "0.7.3" dependencies = [ "anyhow", - "starknet", + "starknet 0.11.0", ] [[package]] @@ -13697,14 +13723,29 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20b9a7b7bfd87287af85854f7458b8170ba6aa59c39113436532b7ff3d2fcbd8" dependencies = [ - "starknet-accounts", - "starknet-contract", - "starknet-core", + "starknet-accounts 0.9.0", + "starknet-contract 0.9.0", + "starknet-core 0.10.0", "starknet-crypto 0.6.2", "starknet-ff", - "starknet-macros", - "starknet-providers", - "starknet-signers", + "starknet-macros 0.1.7", + "starknet-providers 0.10.0", + "starknet-signers 0.8.0", +] + +[[package]] +name = "starknet" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e633a772f59214c296d5037c95c36b72792c9360323818da2b625c7b4ec4b49" +dependencies = [ + "starknet-accounts 0.10.0", + "starknet-contract 0.10.0", + "starknet-core 0.11.1", + "starknet-crypto 0.7.1", + "starknet-macros 0.2.0", + "starknet-providers 0.11.0", + "starknet-signers 0.9.0", ] [[package]] @@ -13715,9 +13756,24 @@ checksum = "2095d7584608ae1707bd1cf2889368ab3734d9f54e4fcef4765cba1f3b3f7618" dependencies = [ "async-trait", "auto_impl", - "starknet-core", - "starknet-providers", - "starknet-signers", + "starknet-core 0.10.0", + "starknet-providers 0.10.0", + "starknet-signers 0.8.0", + "thiserror", +] + +[[package]] +name = "starknet-accounts" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee8a6b588a22c7e79f5d8d4e33413387db63a8beb98be8610138541794cc0a5" +dependencies = [ + "async-trait", + "auto_impl", + "starknet-core 0.11.1", + "starknet-crypto 0.7.1", + "starknet-providers 0.11.0", + "starknet-signers 0.9.0", "thiserror", ] @@ -13730,9 +13786,24 @@ dependencies = [ "serde", "serde_json", "serde_with 2.3.3", - "starknet-accounts", - "starknet-core", - "starknet-providers", + "starknet-accounts 0.9.0", + "starknet-core 0.10.0", + "starknet-providers 0.10.0", + "thiserror", +] + +[[package]] +name = "starknet-contract" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5f91344f1e0b81873b6dc235c50ae4d084c6ea4dd4a1e3e27ad895803adb610" +dependencies = [ + "serde", + "serde_json", + "serde_with 2.3.3", + "starknet-accounts 0.10.0", + "starknet-core 0.11.1", + "starknet-providers 0.11.0", "thiserror", ] @@ -13754,6 +13825,24 @@ dependencies = [ "starknet-ff", ] +[[package]] +name = "starknet-core" +version = "0.11.1" +source = "git+https://github.com/kariy/starknet-rs?branch=dojo-patch#a8ed922690258ca218c80154007aa446ad03929c" +dependencies = [ + "base64 0.21.7", + "crypto-bigint", + "flate2", + "hex", + "serde", + "serde_json", + "serde_json_pythonic", + "serde_with 2.3.3", + "sha3", + "starknet-crypto 0.7.0", + "starknet-types-core", +] + [[package]] name = "starknet-crypto" version = "0.5.2" @@ -13768,7 +13857,7 @@ dependencies = [ "num-traits 0.2.19", "rfc6979", "sha2 0.10.8", - "starknet-crypto-codegen", + "starknet-crypto-codegen 0.3.3", "starknet-curve 0.3.0", "starknet-ff", "zeroize", @@ -13788,12 +13877,51 @@ dependencies = [ "num-traits 0.2.19", "rfc6979", "sha2 0.10.8", - "starknet-crypto-codegen", + "starknet-crypto-codegen 0.3.3", "starknet-curve 0.4.2", "starknet-ff", "zeroize", ] +[[package]] +name = "starknet-crypto" +version = "0.7.0" +source = "git+https://github.com/kariy/starknet-rs?branch=dojo-patch#a8ed922690258ca218c80154007aa446ad03929c" +dependencies = [ + "crypto-bigint", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits 0.2.19", + "rfc6979", + "sha2 0.10.8", + "starknet-crypto-codegen 0.4.0 (git+https://github.com/kariy/starknet-rs?branch=dojo-patch)", + "starknet-curve 0.5.0 (git+https://github.com/kariy/starknet-rs?branch=dojo-patch)", + "starknet-types-core", + "zeroize", +] + +[[package]] +name = "starknet-crypto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2a821ad8d98c6c3e4d0e5097f3fe6e2ed120ada9d32be87cd1330c7923a2f0" +dependencies = [ + "crypto-bigint", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits 0.2.19", + "rfc6979", + "sha2 0.10.8", + "starknet-crypto-codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "starknet-curve 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "starknet-types-core", + "zeroize", +] + [[package]] name = "starknet-crypto-codegen" version = "0.3.3" @@ -13805,6 +13933,27 @@ dependencies = [ "syn 2.0.68", ] +[[package]] +name = "starknet-crypto-codegen" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e179dedc3fa6da064e56811d3e05d446aa2f7459e4eb0e3e49378a337235437" +dependencies = [ + "starknet-curve 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "starknet-types-core", + "syn 2.0.68", +] + +[[package]] +name = "starknet-crypto-codegen" +version = "0.4.0" +source = "git+https://github.com/kariy/starknet-rs?branch=dojo-patch#a8ed922690258ca218c80154007aa446ad03929c" +dependencies = [ + "starknet-curve 0.5.0 (git+https://github.com/kariy/starknet-rs?branch=dojo-patch)", + "starknet-types-core", + "syn 2.0.68", +] + [[package]] name = "starknet-curve" version = "0.3.0" @@ -13823,6 +13972,23 @@ dependencies = [ "starknet-ff", ] +[[package]] +name = "starknet-curve" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56935b306dcf0b8f14bb2a1257164b8478bb8be4801dfae0923f5b266d1b457c" +dependencies = [ + "starknet-types-core", +] + +[[package]] +name = "starknet-curve" +version = "0.5.0" +source = "git+https://github.com/kariy/starknet-rs?branch=dojo-patch#a8ed922690258ca218c80154007aa446ad03929c" +dependencies = [ + "starknet-types-core", +] + [[package]] name = "starknet-ff" version = "0.3.7" @@ -13844,7 +14010,17 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95d549d3078bdbe775d0deaa8ddb57a19942989ce7c1f2dfd60beeb322bb4945" dependencies = [ - "starknet-core", + "starknet-core 0.10.0", + "syn 2.0.68", +] + +[[package]] +name = "starknet-macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fe4f8d615329410578cbedcdbaa4a36c7f28f68c3f3ac56006cfbdaeaa2b41" +dependencies = [ + "starknet-core 0.11.1", "syn 2.0.68", ] @@ -13863,7 +14039,28 @@ dependencies = [ "serde", "serde_json", "serde_with 2.3.3", - "starknet-core", + "starknet-core 0.10.0", + "thiserror", + "url", +] + +[[package]] +name = "starknet-providers" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c85e0a0f4563ae95dfeae14ea0f0c70610efc0ec2462505c64eff5765e7b97" +dependencies = [ + "async-trait", + "auto_impl", + "ethereum-types", + "flate2", + "getrandom", + "log", + "reqwest 0.11.27", + "serde", + "serde_json", + "serde_with 2.3.3", + "starknet-core 0.11.1", "thiserror", "url", ] @@ -13879,34 +14076,35 @@ dependencies = [ "crypto-bigint", "eth-keystore", "rand", - "starknet-core", + "starknet-core 0.10.0", "starknet-crypto 0.6.2", "thiserror", ] [[package]] -name = "starknet-types-core" -version = "0.0.9" +name = "starknet-signers" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d53160556d1f23425100f42b3230df747ea05763efee685a2cd939dfb640701" +checksum = "c17da2139119dbe3aacf1d5d4338798a5c489d17f424916ceb9d2efd83554f87" dependencies = [ - "bitvec", - "lambdaworks-math 0.5.0", - "lazy_static", - "num-bigint", - "num-integer", - "num-traits 0.2.19", - "serde", + "async-trait", + "auto_impl", + "crypto-bigint", + "eth-keystore", + "getrandom", + "rand", + "starknet-core 0.11.1", + "starknet-crypto 0.7.1", + "thiserror", ] [[package]] name = "starknet-types-core" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65799574816ba83cb04b21a3cb16f791b9882687cd9093415fd1b3821dbac29d" +version = "0.1.5" +source = "git+https://github.com/dojoengine/types-rs?rev=289e2f0#289e2f0bfd5f01a98e7273ff7ce8902a23b5f9d5" dependencies = [ "lambdaworks-crypto", - "lambdaworks-math 0.7.0", + "lambdaworks-math", "lazy_static", "num-bigint", "num-integer", @@ -13920,7 +14118,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "365ec5c0662466f299762bd012012da30e9a28319000cfade372b8787111f202" dependencies = [ - "cairo-lang-starknet-classes 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-starknet-classes 2.6.4", "derive_more", "hex", "indexmap 2.2.6", @@ -14750,8 +14948,8 @@ dependencies = [ "serde", "serde_json", "sqlx", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "tokio", "tokio-stream", "tokio-util", @@ -14780,13 +14978,14 @@ dependencies = [ "futures", "futures-util", "libp2p-gossipsub 0.46.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.19", "parking_lot 0.12.3", "prost 0.11.9", "prost 0.12.6", "serde", "serde_json", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "thiserror", "tokio", "tonic 0.10.2", @@ -14803,7 +15002,7 @@ dependencies = [ "anyhow", "async-trait", "base64 0.21.7", - "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "camino", "chrono", "crypto-bigint", @@ -14816,6 +15015,7 @@ dependencies = [ "katana-runner", "lazy_static", "log", + "num-traits 0.2.19", "once_cell", "reqwest 0.12.5", "scarb", @@ -14825,8 +15025,8 @@ dependencies = [ "slab", "sozo-ops", "sqlx", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "thiserror", "tokio", "tokio-stream", @@ -14859,8 +15059,8 @@ dependencies = [ "serial_test", "sozo-ops", "sqlx", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "strum 0.25.0", "strum_macros 0.25.3", "thiserror", @@ -14888,6 +15088,7 @@ dependencies = [ "futures-util", "hex", "hyper 0.14.29", + "num-traits 0.2.19", "parking_lot 0.12.3", "prost 0.11.9", "prost 0.12.6", @@ -14898,8 +15099,8 @@ dependencies = [ "serde_json", "sozo-ops", "sqlx", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "strum 0.25.0", "strum_macros 0.25.3", "thiserror", @@ -14924,7 +15125,7 @@ version = "0.7.3" dependencies = [ "anyhow", "async-trait", - "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?rev=ec18eea5)", + "cainome 0.2.3 (git+https://github.com/cartridge-gg/cainome?tag=v0.3.0)", "chrono", "crypto-bigint", "dojo-test-utils", @@ -14940,8 +15141,8 @@ dependencies = [ "serde", "serde_json", "sqlx", - "starknet", - "starknet-crypto 0.6.2", + "starknet 0.11.0", + "starknet-crypto 0.7.1", "tempfile", "thiserror", "tokio", @@ -16093,7 +16294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core 0.52.0", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -16111,7 +16312,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -16138,7 +16339,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -16173,18 +16374,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -16201,9 +16402,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -16219,9 +16420,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -16237,15 +16438,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -16261,9 +16462,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -16279,9 +16480,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -16297,9 +16498,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -16315,9 +16516,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -16456,9 +16657,9 @@ checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852" [[package]] name = "xxhash-rust" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927da81e25be1e1a2901d59b81b37dd2efd1fc9c9345a55007f09bf5a2d3ee03" +checksum = "63658493314859b4dfdf3fb8c1defd61587839def09582db50b8a4e93afca6bb" [[package]] name = "yamux" @@ -16508,18 +16709,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a5e69e673c..a63f5e5799 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ inherits = "release" lto = "fat" [workspace.dependencies] -cainome = { git = "https://github.com/cartridge-gg/cainome", rev = "ec18eea5", features = [ "abigen-rs" ] } +cainome = { git = "https://github.com/cartridge-gg/cainome", tag = "v0.3.0", features = [ "abigen-rs" ] } common = { path = "crates/common" } # metrics @@ -113,6 +113,7 @@ assert_matches = "1.5.0" async-trait = "0.1.77" auto_impl = "1.2.0" base64 = "0.21.2" +bigdecimal = "0.4.1" bytes = "1.6" cairo-lang-compiler = { git = "https://github.com/starkware-libs/cairo", rev = "d9984ef58e2f704909e271f2f01327f520ded632" } cairo-lang-debug = { git = "https://github.com/starkware-libs/cairo", rev = "d9984ef58e2f704909e271f2f01327f520ded632" } @@ -136,7 +137,7 @@ cairo-lang-test-plugin = { git = "https://github.com/starkware-libs/cairo", rev cairo-lang-test-runner = { git = "https://github.com/starkware-libs/cairo", rev = "d9984ef58e2f704909e271f2f01327f520ded632" } cairo-lang-test-utils = { git = "https://github.com/starkware-libs/cairo", rev = "d9984ef58e2f704909e271f2f01327f520ded632" } cairo-lang-utils = { git = "https://github.com/starkware-libs/cairo", rev = "d9984ef58e2f704909e271f2f01327f520ded632" } -cairo-proof-parser = { git = "https://github.com/cartridge-gg/cairo-proof-parser", tag = "v0.3.0" } +cairo-proof-parser = { git = "https://github.com/cartridge-gg/cairo-proof-parser", branch = "v0.3.0/new-felt" } cairo-vm = "0.9.2" camino = { version = "1.1.2", features = [ "serde1" ] } chrono = { version = "0.4.24", features = [ "serde" ] } @@ -180,8 +181,13 @@ serde_with = "2.3" similar-asserts = "1.5.0" smol_str = { version = "0.2.0", features = [ "serde" ] } sqlx = { version = "0.7.2", features = [ "chrono", "macros", "regexp", "runtime-async-std", "runtime-tokio", "sqlite", "uuid" ] } -starknet = "0.10.0" -starknet-crypto = "0.6.2" +starknet = "0.11.0" +starknet-crypto = "0.7.0" +# `starknet-rs` is using `starknet-types-core` 0.1.3, but we need >=0.1.4 because +# we need this . So we put strict +# requirement here to prevent from being downgraded. +# We can remove this requirement once `starknet-rs` is using >=0.1.4 +starknet-types-core = "~0.1.4" starknet_api = "0.11.0" strum = "0.25" strum_macros = "0.25" @@ -219,8 +225,8 @@ alloy-sol-types = { version = "0.7.6", default-features = false } criterion = "0.5.1" # Controller integration -account_sdk = { git = "https://github.com/cartridge-gg/controller", rev = "e8276cfffe48b5d09f0598026d13635374204b72" } -slot = { git = "https://github.com/cartridge-gg/slot", rev = "1d0c9f7" } +account_sdk = { git = "https://github.com/cartridge-gg/controller", branch = "bump-starknet" } +slot = { git = "https://github.com/cartridge-gg/slot", rev = "4c1165d" } [patch.crates-io] cairo-felt = { git = "https://github.com/dojoengine/cairo-rs.git", rev = "1031381" } @@ -233,3 +239,10 @@ alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "4655f8e4372 alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "4655f8e4372ecc0b056e83abbc60c3912902ee64" } alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "4655f8e4372ecc0b056e83abbc60c3912902ee64" } alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "4655f8e4372ecc0b056e83abbc60c3912902ee64" } + +# Remove this patch once the following PR is merged: +# +# To enable std feature on `starknet-types-core`. +# To re-export the entire `felt` module from `starknet-types-core`. +starknet-core = { git = "https://github.com/kariy/starknet-rs", branch = "dojo-patch" } +starknet-types-core = { git = "https://github.com/dojoengine/types-rs", rev = "289e2f0" } diff --git a/bin/saya/src/args/mod.rs b/bin/saya/src/args/mod.rs index b16fce3cdc..2e14cdb297 100644 --- a/bin/saya/src/args/mod.rs +++ b/bin/saya/src/args/mod.rs @@ -161,7 +161,7 @@ impl TryFrom for SayaConfig { #[cfg(test)] mod tests { - use katana_primitives::FieldElement; + use katana_primitives::felt::FieldElement; use super::*; use crate::args::data_availability::CelestiaOptions; @@ -226,12 +226,12 @@ mod tests { let expected = StarknetAccountData { starknet_url: Url::parse("http://localhost:5030").unwrap(), - chain_id: FieldElement::from_hex_be("0x534e5f5345504f4c4941").unwrap(), - signer_address: FieldElement::from_hex_be( + chain_id: FieldElement::from_hex("0x534e5f5345504f4c4941").unwrap(), + signer_address: FieldElement::from_hex( "0x3aa0a12c62a46a200b1a1211e8cd09b520164104e76d79648ca459cf05db94", ) .unwrap(), - signer_key: FieldElement::from_hex_be( + signer_key: FieldElement::from_hex( "0x6b41bfa82e791a8b4e6b3ee058cb25b89714e4a23bd9a1ad6e6ba0bbc0b145b", ) .unwrap(), diff --git a/bin/saya/src/args/proof.rs b/bin/saya/src/args/proof.rs index 23375d1dc2..41afd9d6ee 100644 --- a/bin/saya/src/args/proof.rs +++ b/bin/saya/src/args/proof.rs @@ -1,5 +1,5 @@ use clap::Args; -use katana_primitives::FieldElement; +use katana_primitives::felt::FieldElement; use url::Url; #[derive(Debug, Args, Clone)] diff --git a/bin/saya/src/args/starknet_account.rs b/bin/saya/src/args/starknet_account.rs index 45d772ce08..ce03441e7f 100644 --- a/bin/saya/src/args/starknet_account.rs +++ b/bin/saya/src/args/starknet_account.rs @@ -1,7 +1,7 @@ //! Data availability options. use clap::Args; -use katana_primitives::FieldElement; +use katana_primitives::felt::FieldElement; use url::Url; #[derive(Debug, Args, Clone)] diff --git a/bin/saya/src/tests.rs b/bin/saya/src/tests.rs index fbb9b4b727..b32fa3f66f 100644 --- a/bin/saya/src/tests.rs +++ b/bin/saya/src/tests.rs @@ -12,7 +12,7 @@ use saya_core::prover::{ ProverIdentifier, ProvingState, Scheduler, }; use saya_core::ProverAccessKey; -use starknet_crypto::FieldElement; +use starknet_crypto::Felt; use tokio::time::sleep; fn prover_identifier() -> ProverIdentifier { @@ -37,69 +37,64 @@ where #[tokio::test] async fn test_program_input_from_program_output() -> anyhow::Result<()> { let mut input = ProgramInput { - prev_state_root: FieldElement::from_str("101").unwrap(), + prev_state_root: Felt::from_str("101").unwrap(), block_number: 102, - block_hash: FieldElement::from_str("103").unwrap(), - config_hash: FieldElement::from_str("104").unwrap(), + block_hash: Felt::from_str("103").unwrap(), + config_hash: Felt::from_str("104").unwrap(), message_to_starknet_segment: vec![ MessageToStarknet { - from_address: ContractAddress::from(FieldElement::from_str("105").unwrap()), - to_address: ContractAddress::from(FieldElement::from_str("106").unwrap()), - payload: vec![FieldElement::from_str("107").unwrap()], + from_address: ContractAddress::from(Felt::from_str("105").unwrap()), + to_address: ContractAddress::from(Felt::from_str("106").unwrap()), + payload: vec![Felt::from_str("107").unwrap()], }, MessageToStarknet { - from_address: ContractAddress::from(FieldElement::from_str("105").unwrap()), - to_address: ContractAddress::from(FieldElement::from_str("106").unwrap()), - payload: vec![FieldElement::from_str("107").unwrap()], + from_address: ContractAddress::from(Felt::from_str("105").unwrap()), + to_address: ContractAddress::from(Felt::from_str("106").unwrap()), + payload: vec![Felt::from_str("107").unwrap()], }, ], message_to_appchain_segment: vec![ MessageToAppchain { - from_address: ContractAddress::from(FieldElement::from_str("108").unwrap()), - to_address: ContractAddress::from(FieldElement::from_str("109").unwrap()), - nonce: FieldElement::from_str("110").unwrap(), - selector: FieldElement::from_str("111").unwrap(), - payload: vec![FieldElement::from_str("112").unwrap()], + from_address: ContractAddress::from(Felt::from_str("108").unwrap()), + to_address: ContractAddress::from(Felt::from_str("109").unwrap()), + nonce: Felt::from_str("110").unwrap(), + selector: Felt::from_str("111").unwrap(), + payload: vec![Felt::from_str("112").unwrap()], }, MessageToAppchain { - from_address: ContractAddress::from(FieldElement::from_str("108").unwrap()), - to_address: ContractAddress::from(FieldElement::from_str("109").unwrap()), - nonce: FieldElement::from_str("110").unwrap(), - selector: FieldElement::from_str("111").unwrap(), - payload: vec![FieldElement::from_str("112").unwrap()], + from_address: ContractAddress::from(Felt::from_str("108").unwrap()), + to_address: ContractAddress::from(Felt::from_str("109").unwrap()), + nonce: Felt::from_str("110").unwrap(), + selector: Felt::from_str("111").unwrap(), + payload: vec![Felt::from_str("112").unwrap()], }, ], state_updates: StateUpdates { nonce_updates: { let mut map = std::collections::HashMap::new(); map.insert( - ContractAddress::from(FieldElement::from_str("1111").unwrap()), - FieldElement::from_str("22222").unwrap(), + ContractAddress::from(Felt::from_str("1111").unwrap()), + Felt::from_str("22222").unwrap(), ); map }, storage_updates: vec![( - ContractAddress::from(FieldElement::from_str("333")?), - vec![(FieldElement::from_str("4444")?, FieldElement::from_str("555")?)] - .into_iter() - .collect(), + ContractAddress::from(Felt::from_str("333")?), + vec![(Felt::from_str("4444")?, Felt::from_str("555")?)].into_iter().collect(), )] .into_iter() .collect(), contract_updates: { let mut map = std::collections::HashMap::new(); map.insert( - ContractAddress::from(FieldElement::from_str("66666").unwrap()), - FieldElement::from_str("7777").unwrap(), + ContractAddress::from(Felt::from_str("66666").unwrap()), + Felt::from_str("7777").unwrap(), ); map }, declared_classes: { let mut map = std::collections::HashMap::new(); - map.insert( - FieldElement::from_str("88888").unwrap(), - FieldElement::from_str("99999").unwrap(), - ); + map.insert(Felt::from_str("88888").unwrap(), Felt::from_str("99999").unwrap()); map }, }, @@ -256,7 +251,7 @@ async fn test_combine_proofs() { .map(|s| serde_json::from_str::(s).unwrap()) .collect::>(); - let world = FieldElement::from_dec_str("333").unwrap(); + let world = Felt::from_dec_str("333").unwrap(); for input in &mut inputs { input.fill_da(world) } @@ -286,7 +281,7 @@ async fn test_combine_proofs() { #[ignore] #[tokio::test] async fn test_4_combine_proofs() -> anyhow::Result<()> { - let world = FieldElement::from_dec_str("42")?; + let world = Felt::from_dec_str("42")?; let input_1 = r#"{ "prev_state_root": "101", diff --git a/bin/scheduler/src/main.rs b/bin/scheduler/src/main.rs index 275b4036ed..b94ace2f71 100644 --- a/bin/scheduler/src/main.rs +++ b/bin/scheduler/src/main.rs @@ -2,7 +2,7 @@ use std::fs; use std::sync::Arc; use clap::Parser; -use katana_primitives::FieldElement; +use katana_primitives::felt::FieldElement; use saya_core::prover::{HttpProverParams, ProgramInput, ProverIdentifier, Scheduler}; use saya_core::ProverAccessKey; use serde::{Deserialize, Serialize}; diff --git a/bin/sozo/Cargo.toml b/bin/sozo/Cargo.toml index 64fb08de3c..6d7b3c651a 100644 --- a/bin/sozo/Cargo.toml +++ b/bin/sozo/Cargo.toml @@ -11,7 +11,7 @@ slot = { workspace = true, optional = true } anyhow.workspace = true async-trait.workspace = true -bigdecimal = "0.4.1" +bigdecimal.workspace = true cairo-lang-compiler.workspace = true cairo-lang-defs.workspace = true cairo-lang-filesystem.workspace = true diff --git a/bin/sozo/src/commands/account.rs b/bin/sozo/src/commands/account.rs index 63b3206960..806e07e264 100644 --- a/bin/sozo/src/commands/account.rs +++ b/bin/sozo/src/commands/account.rs @@ -4,8 +4,8 @@ use anyhow::Result; use clap::{Args, Subcommand}; use scarb::core::Config; use sozo_ops::account; +use starknet::core::types::Felt; use starknet::signers::LocalWallet; -use starknet_crypto::FieldElement; use tracing::trace; use super::options::signer::SignerOptions; @@ -53,7 +53,7 @@ pub enum AccountCommand { estimate_only: bool, #[clap(long, help = "Provide transaction nonce manually")] - nonce: Option, + nonce: Option, #[clap( long, @@ -82,7 +82,7 @@ pub enum AccountCommand { output: PathBuf, #[clap(help = "Contract address")] - address: FieldElement, + address: Felt, }, } diff --git a/bin/sozo/src/commands/auth.rs b/bin/sozo/src/commands/auth.rs index 01e3c6189d..554f7fe945 100644 --- a/bin/sozo/src/commands/auth.rs +++ b/bin/sozo/src/commands/auth.rs @@ -188,7 +188,7 @@ mod tests { use std::str::FromStr; use dojo_world::contracts::cairo_utils; - use starknet_crypto::FieldElement; + use starknet::core::types::Felt; use super::*; @@ -196,7 +196,7 @@ mod tests { fn test_owner_resource_from_str() { // Test valid input let input = "contract:path::to::contract,0x1234"; - let expected_owner = FieldElement::from_hex_be("0x1234").unwrap(); + let expected_owner = Felt::from_hex("0x1234").unwrap(); let expected_resource = auth::ResourceType::Contract("path::to::contract".to_string()); let expected = auth::OwnerResource { owner: expected_owner, resource: expected_resource }; let result = auth::OwnerResource::from_str(input).unwrap(); @@ -204,7 +204,7 @@ mod tests { // Test valid input with model let input = "model:model_name,0x1234"; - let expected_owner = FieldElement::from_hex_be("0x1234").unwrap(); + let expected_owner = Felt::from_hex("0x1234").unwrap(); let expected_model = cairo_utils::str_to_felt("model_name").unwrap(); let expected_resource = auth::ResourceType::Model(expected_model); let expected = auth::OwnerResource { owner: expected_owner, resource: expected_resource }; diff --git a/bin/sozo/src/commands/call.rs b/bin/sozo/src/commands/call.rs index dd7c944cec..e4caf0b554 100644 --- a/bin/sozo/src/commands/call.rs +++ b/bin/sozo/src/commands/call.rs @@ -1,7 +1,7 @@ use anyhow::Result; use clap::Args; use scarb::core::Config; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use tracing::trace; use super::options::starknet::StarknetOptions; @@ -21,7 +21,7 @@ pub struct CallArgs { #[arg(value_delimiter = ',')] #[arg(help = "The calldata to be passed to the entrypoint. Comma separated values e.g., \ 0x12345,0x69420.")] - pub calldata: Vec, + pub calldata: Vec, #[arg(short, long)] #[arg(help = "The block ID (could be a hash, a number, 'pending' or 'latest')")] diff --git a/bin/sozo/src/commands/calldata_decoder.rs b/bin/sozo/src/commands/calldata_decoder.rs index 86a5b095f2..082f50d7cd 100644 --- a/bin/sozo/src/commands/calldata_decoder.rs +++ b/bin/sozo/src/commands/calldata_decoder.rs @@ -1,7 +1,7 @@ use anyhow::{self, Result}; use cainome::cairo_serde::{ByteArray, CairoSerde}; use num_bigint::BigUint; -use starknet::core::types::{FieldElement, FromStrError}; +use starknet::core::types::{Felt, FromStrError}; use starknet::core::utils::cairo_short_string_to_felt; /// An error that occurs while decoding calldata. @@ -26,16 +26,16 @@ pub type DecoderResult = Result; const ITEM_DELIMITER: char = ','; const ITEM_PREFIX_DELIMITER: char = ':'; -/// A trait for decoding calldata into a vector of FieldElements. +/// A trait for decoding calldata into a vector of Felts. trait CalldataDecoder { - fn decode(&self, input: &str) -> DecoderResult>; + fn decode(&self, input: &str) -> DecoderResult>; } -/// Decodes a u256 string into a [`FieldElement`]s array representing +/// Decodes a u256 string into a [`Felt`]s array representing /// a u256 value split into two 128-bit words. struct U256CalldataDecoder; impl CalldataDecoder for U256CalldataDecoder { - fn decode(&self, input: &str) -> DecoderResult> { + fn decode(&self, input: &str) -> DecoderResult> { let bigint = if let Some(hex_str) = input.strip_prefix("0x") { let unsigned_bytes = if hex_str.len() % 2 == 0 { hex::decode(hex_str)? @@ -68,46 +68,46 @@ impl CalldataDecoder for U256CalldataDecoder { let low = &bigint % &u128_max_plus_1; // Unwrapping is safe as these are never out of range - let high = FieldElement::from_byte_slice_be(&high.to_bytes_be()).unwrap(); - let low = FieldElement::from_byte_slice_be(&low.to_bytes_be()).unwrap(); + let high = Felt::from_bytes_be_slice(&high.to_bytes_be()); + let low = Felt::from_bytes_be_slice(&low.to_bytes_be()); Ok(vec![low, high]) } } -/// Decodes a string (ByteArray) into a [`FieldElement`]s array representing +/// Decodes a string (ByteArray) into a [`Felt`]s array representing /// a serialized Cairo ByteArray. struct StrCalldataDecoder; impl CalldataDecoder for StrCalldataDecoder { - fn decode(&self, input: &str) -> DecoderResult> { + fn decode(&self, input: &str) -> DecoderResult> { let ba = ByteArray::from_string(input)?; Ok(ByteArray::cairo_serialize(&ba)) } } -/// Decodes a cairo short string into a [`FieldElement`]. +/// Decodes a cairo short string into a [`Felt`]. struct ShortStrCalldataDecoder; impl CalldataDecoder for ShortStrCalldataDecoder { - fn decode(&self, input: &str) -> DecoderResult> { + fn decode(&self, input: &str) -> DecoderResult> { Ok(vec![cairo_short_string_to_felt(input)?]) } } -/// Decodes a string into a [`FieldElement`], either from hexadecimal or decimal string. +/// Decodes a string into a [`Felt`], either from hexadecimal or decimal string. struct DefaultCalldataDecoder; impl CalldataDecoder for DefaultCalldataDecoder { - fn decode(&self, input: &str) -> DecoderResult> { + fn decode(&self, input: &str) -> DecoderResult> { let felt = if let Some(hex_str) = input.strip_prefix("0x") { - FieldElement::from_hex_be(hex_str)? + Felt::from_hex(hex_str)? } else { - FieldElement::from_dec_str(input)? + Felt::from_dec_str(input)? }; Ok(vec![felt]) } } -/// Decodes a string of calldata items into a vector of FieldElements. +/// Decodes a string of calldata items into a vector of Felts. /// /// # Arguments: /// @@ -115,7 +115,7 @@ impl CalldataDecoder for DefaultCalldataDecoder { /// prefixes to indicate the type of the item. /// /// # Returns -/// A vector of [`FieldElement`]s. +/// A vector of [`Felt`]s. /// /// # Example /// @@ -123,7 +123,7 @@ impl CalldataDecoder for DefaultCalldataDecoder { /// let input = "u256:0x1,str:hello,64"; /// let result = decode_calldata(input).unwrap(); /// ``` -pub fn decode_calldata(input: &str) -> DecoderResult> { +pub fn decode_calldata(input: &str) -> DecoderResult> { let items = input.split(ITEM_DELIMITER); let mut calldata = vec![]; @@ -134,15 +134,15 @@ pub fn decode_calldata(input: &str) -> DecoderResult> { Ok(calldata) } -/// Decodes a single item of calldata into a vector of FieldElements. +/// Decodes a single item of calldata into a vector of Felts. /// /// # Arguments /// /// * `item` - The item to decode. /// /// # Returns -/// A vector of [`FieldElement`]s. -fn decode_inner(item: &str) -> DecoderResult> { +/// A vector of [`Felt`]s. +fn decode_inner(item: &str) -> DecoderResult> { let item = item.trim(); let felts = if let Some((prefix, value)) = item.split_once(ITEM_PREFIX_DELIMITER) { @@ -168,7 +168,7 @@ mod tests { #[test] fn test_u256_decoder_hex() { let input = "u256:0x1"; - let expected = vec![FieldElement::ONE, FieldElement::ZERO]; + let expected = vec![Felt::ONE, Felt::ZERO]; let result = decode_calldata(input).unwrap(); assert_eq!(result, expected); } diff --git a/bin/sozo/src/commands/migrate.rs b/bin/sozo/src/commands/migrate.rs index 4ab758ed9e..c4dfc43fb5 100644 --- a/bin/sozo/src/commands/migrate.rs +++ b/bin/sozo/src/commands/migrate.rs @@ -7,7 +7,7 @@ use katana_rpc_api::starknet::RPC_SPEC_VERSION; use scarb::core::{Config, Workspace}; use sozo_ops::migration; use starknet::accounts::{Account, ConnectedAccount}; -use starknet::core::types::{BlockId, BlockTag, FieldElement, StarknetError}; +use starknet::core::types::{BlockId, BlockTag, Felt, StarknetError}; use starknet::core::utils::parse_cairo_short_string; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::{JsonRpcClient, Provider, ProviderError}; @@ -156,7 +156,7 @@ pub async fn setup_env<'a>( world: WorldOptions, name: &str, env: Option<&'a Environment>, -) -> Result<(Option, SozoAccount>, String)> { +) -> Result<(Option, SozoAccount>, String)> { trace!("Setting up environment."); let ui = ws.config().ui(); diff --git a/bin/sozo/src/commands/model.rs b/bin/sozo/src/commands/model.rs index c14297034a..d004cf7f13 100644 --- a/bin/sozo/src/commands/model.rs +++ b/bin/sozo/src/commands/model.rs @@ -2,7 +2,7 @@ use anyhow::Result; use clap::{Args, Subcommand}; use scarb::core::Config; use sozo_ops::model; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use tracing::trace; use super::options::starknet::StarknetOptions; @@ -52,7 +52,7 @@ hashes, called 'hash' in the following documentation. fixed layout key = parent_key struct layout field key = hash(parent_key, field_selector) tuple layout item key = hash(parent_key, item_index) - enum layout + enum layout variant key = parent_key data key = hash(parent_key, variant_index) array layout @@ -96,7 +96,7 @@ hashes, called 'hash' in the following documentation. #[arg(value_name = "KEYS")] #[arg(value_delimiter = ',')] #[arg(help = "Comma seperated values e.g., 0x12345,0x69420,...")] - keys: Vec, + keys: Vec, #[command(flatten)] world: WorldOptions, diff --git a/bin/sozo/src/commands/options/account/controller.rs b/bin/sozo/src/commands/options/account/controller.rs index f110a9b7f3..3cdd75fad2 100644 --- a/bin/sozo/src/commands/options/account/controller.rs +++ b/bin/sozo/src/commands/options/account/controller.rs @@ -9,7 +9,7 @@ use dojo_world::migration::strategy::generate_salt; use scarb::core::Config; use slot::session::Policy; use starknet::core::types::contract::{AbiEntry, StateMutability}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::core::utils::{cairo_short_string_to_felt, get_contract_address}; use starknet::macros::short_string; use starknet::providers::Provider; @@ -121,7 +121,7 @@ where /// project's base manifest ( `/manifests//base` ) and convert them into policies. fn collect_policies( world_addr_or_name: WorldAddressOrName, - user_address: FieldElement, + user_address: Felt, config: &Config, ) -> Result> { let root_dir = config.root(); @@ -140,7 +140,7 @@ fn get_project_base_manifest(root_dir: &Utf8Path, profile: &str) -> Result Result> { @@ -182,7 +182,7 @@ fn collect_policies_from_base_manifest( fn policies_from_abis( policies: &mut Vec, contract_name: &str, - contract_address: FieldElement, + contract_address: Felt, entries: &[AbiEntry], ) { for entry in entries { @@ -205,10 +205,7 @@ fn policies_from_abis( } } -fn get_dojo_contract_address( - world_address: FieldElement, - manifest: &Manifest, -) -> FieldElement { +fn get_dojo_contract_address(world_address: Felt, manifest: &Manifest) -> Felt { if let Some(address) = manifest.inner.address { address } else { @@ -220,7 +217,7 @@ fn get_dojo_contract_address( fn get_dojo_world_address( world_address: WorldAddressOrName, manifest: &BaseManifest, -) -> Result { +) -> Result { match world_address { WorldAddressOrName::Address(addr) => Ok(addr), WorldAddressOrName::Name(name) => { @@ -230,7 +227,7 @@ fn get_dojo_world_address( salt, manifest.world.inner.original_class_hash, &[manifest.base.inner.original_class_hash], - FieldElement::ZERO, + Felt::ZERO, ); Ok(address) } diff --git a/bin/sozo/src/commands/options/account/mod.rs b/bin/sozo/src/commands/options/account/mod.rs index 8a33772848..0e68b02a3c 100644 --- a/bin/sozo/src/commands/options/account/mod.rs +++ b/bin/sozo/src/commands/options/account/mod.rs @@ -5,7 +5,7 @@ use clap::Args; use dojo_world::metadata::Environment; use scarb::core::Config; use starknet::accounts::{ExecutionEncoding, SingleOwnerAccount}; -use starknet::core::types::{BlockId, BlockTag, FieldElement}; +use starknet::core::types::{BlockId, BlockTag, Felt}; use starknet::providers::Provider; use starknet::signers::LocalWallet; use tracing::trace; @@ -28,7 +28,7 @@ pub use r#type::*; /// Else if it's an address, it will be used directly. #[derive(Debug)] pub enum WorldAddressOrName { - Address(FieldElement), + Address(Felt), Name(String), } @@ -42,7 +42,7 @@ pub enum WorldAddressOrName { pub struct AccountOptions { #[arg(long, env = DOJO_ACCOUNT_ADDRESS_ENV_VAR)] #[arg(global = true)] - pub account_address: Option, + pub account_address: Option, #[arg(global = true)] #[arg(long = "slot.controller")] @@ -132,13 +132,13 @@ impl AccountOptions { Ok(account) } - pub fn account_address(&self, env_metadata: Option<&Environment>) -> Result { + pub fn account_address(&self, env_metadata: Option<&Environment>) -> Result { if let Some(address) = self.account_address { trace!(?address, "Account address found."); Ok(address) } else if let Some(address) = env_metadata.and_then(|env| env.account_address()) { trace!(address, "Account address found in environment metadata."); - Ok(FieldElement::from_str(address)?) + Ok(Felt::from_str(address)?) } else { Err(anyhow!( "Could not find account address. Please specify it with --account-address or in \ @@ -152,7 +152,7 @@ impl AccountOptions { mod tests { use clap::Parser; use starknet::accounts::{Call, ExecutionEncoder}; - use starknet_crypto::FieldElement; + use starknet_crypto::Felt; use super::{AccountOptions, DOJO_ACCOUNT_ADDRESS_ENV_VAR}; @@ -167,16 +167,13 @@ mod tests { std::env::set_var(DOJO_ACCOUNT_ADDRESS_ENV_VAR, "0x0"); let cmd = Command::parse_from([""]); - assert_eq!(cmd.account.account_address, Some(FieldElement::from_hex_be("0x0").unwrap())); + assert_eq!(cmd.account.account_address, Some(Felt::from_hex("0x0").unwrap())); } #[test] fn account_address_from_args() { let cmd = Command::parse_from(["sozo", "--account-address", "0x0"]); - assert_eq!( - cmd.account.account_address(None).unwrap(), - FieldElement::from_hex_be("0x0").unwrap() - ); + assert_eq!(cmd.account.account_address(None).unwrap(), Felt::from_hex("0x0").unwrap()); } #[test] @@ -189,7 +186,7 @@ mod tests { let cmd = Command::parse_from([""]); assert_eq!( cmd.account.account_address(Some(&env_metadata)).unwrap(), - FieldElement::from_hex_be("0x0").unwrap() + Felt::from_hex("0x0").unwrap() ); } @@ -203,7 +200,7 @@ mod tests { let cmd = Command::parse_from(["sozo", "--account-address", "0x1"]); assert_eq!( cmd.account.account_address(Some(&env_metadata)).unwrap(), - FieldElement::from_hex_be("0x1").unwrap() + Felt::from_hex("0x1").unwrap() ); } @@ -224,12 +221,9 @@ mod tests { "0x1", ]); let dummy_call = vec![Call { - to: FieldElement::from_hex_be("0x0").unwrap(), - selector: FieldElement::from_hex_be("0x1").unwrap(), - calldata: vec![ - FieldElement::from_hex_be("0x2").unwrap(), - FieldElement::from_hex_be("0x3").unwrap(), - ], + to: Felt::from_hex("0x0").unwrap(), + selector: Felt::from_hex("0x1").unwrap(), + calldata: vec![Felt::from_hex("0x2").unwrap(), Felt::from_hex("0x3").unwrap()], }]; // HACK: SingleOwnerAccount doesn't expose a way to check `encoding` type used in struct, so @@ -237,19 +231,16 @@ mod tests { let account = cmd.account.std_account(runner.provider(), None).await.unwrap(); let result = account.encode_calls(&dummy_call); // 0x0 is the data offset. - assert!(*result.get(3).unwrap() == FieldElement::from_hex_be("0x0").unwrap()); + assert!(*result.get(3).unwrap() == Felt::from_hex("0x0").unwrap()); } #[katana_runner::katana_test(2, true)] async fn without_legacy_flag_works_as_expected() { let cmd = Command::parse_from(["sozo", "--account-address", "0x0", "--private-key", "0x1"]); let dummy_call = vec![Call { - to: FieldElement::from_hex_be("0x0").unwrap(), - selector: FieldElement::from_hex_be("0x1").unwrap(), - calldata: vec![ - FieldElement::from_hex_be("0xf2").unwrap(), - FieldElement::from_hex_be("0xf3").unwrap(), - ], + to: Felt::from_hex("0x0").unwrap(), + selector: Felt::from_hex("0x1").unwrap(), + calldata: vec![Felt::from_hex("0xf2").unwrap(), Felt::from_hex("0xf3").unwrap()], }]; // HACK: SingleOwnerAccount doesn't expose a way to check `encoding` type used in struct, so @@ -257,6 +248,6 @@ mod tests { let account = cmd.account.std_account(runner.provider(), None).await.unwrap(); let result = account.encode_calls(&dummy_call); // 0x2 is the Calldata len. - assert!(*result.get(3).unwrap() == FieldElement::from_hex_be("0x2").unwrap()); + assert!(*result.get(3).unwrap() == Felt::from_hex("0x2").unwrap()); } } diff --git a/bin/sozo/src/commands/options/account/type.rs b/bin/sozo/src/commands/options/account/type.rs index 0a45328600..a0fda6fbc0 100644 --- a/bin/sozo/src/commands/options/account/type.rs +++ b/bin/sozo/src/commands/options/account/type.rs @@ -1,15 +1,15 @@ use std::sync::Arc; use async_trait::async_trait; -use starknet::accounts::single_owner::SignError; use starknet::accounts::{ - Account, Call, ConnectedAccount, Declaration, Execution, ExecutionEncoder, LegacyDeclaration, - RawDeclaration, RawExecution, RawLegacyDeclaration, SingleOwnerAccount, + single_owner, Account, Call, ConnectedAccount, DeclarationV2, DeclarationV3, ExecutionEncoder, + ExecutionV1, ExecutionV3, LegacyDeclaration, RawDeclarationV2, RawDeclarationV3, + RawExecutionV1, RawExecutionV3, RawLegacyDeclaration, SingleOwnerAccount, }; use starknet::core::types::contract::legacy::LegacyContractClass; -use starknet::core::types::{BlockId, FieldElement, FlattenedSierraClass}; +use starknet::core::types::{BlockId, Felt, FlattenedSierraClass}; use starknet::providers::Provider; -use starknet::signers::LocalWallet; +use starknet::signers::{local_wallet, LocalWallet}; #[cfg(feature = "controller")] use super::controller::ControllerSessionAccount; @@ -17,7 +17,7 @@ use super::controller::ControllerSessionAccount; #[derive(Debug, thiserror::Error)] pub enum SozoAccountSignError { #[error(transparent)] - Standard(#[from] SignError), + Standard(#[from] single_owner::SignError), #[cfg(feature = "controller")] #[error(transparent)] @@ -51,7 +51,7 @@ where { type SignError = SozoAccountSignError; - fn address(&self) -> FieldElement { + fn address(&self) -> Felt { match self { Self::Standard(account) => account.address(), #[cfg(feature = "controller")] @@ -59,7 +59,7 @@ where } } - fn chain_id(&self) -> FieldElement { + fn chain_id(&self) -> Felt { match self { Self::Standard(account) => account.chain_id(), #[cfg(feature = "controller")] @@ -67,47 +67,71 @@ where } } + fn declare_legacy( + &self, + contract_class: Arc, + ) -> LegacyDeclaration<'_, Self> { + LegacyDeclaration::new(contract_class, self) + } + fn declare( &self, contract_class: Arc, - compiled_class_hash: FieldElement, - ) -> Declaration<'_, Self> { - Declaration::new(contract_class, compiled_class_hash, self) + compiled_class_hash: Felt, + ) -> DeclarationV2<'_, Self> { + DeclarationV2::new(contract_class, compiled_class_hash, self) } - fn declare_legacy( + fn declare_v2( &self, - contract_class: Arc, - ) -> LegacyDeclaration<'_, Self> { - LegacyDeclaration::new(contract_class, self) + contract_class: Arc, + compiled_class_hash: Felt, + ) -> DeclarationV2<'_, Self> { + DeclarationV2::new(contract_class, compiled_class_hash, self) + } + + fn declare_v3( + &self, + contract_class: Arc, + compiled_class_hash: Felt, + ) -> DeclarationV3<'_, Self> { + DeclarationV3::new(contract_class, compiled_class_hash, self) } - fn execute(&self, calls: Vec) -> Execution<'_, Self> { - Execution::new(calls, self) + fn execute(&self, calls: Vec) -> ExecutionV1<'_, Self> { + ExecutionV1::new(calls, self) } - async fn sign_execution( + fn execute_v1(&self, calls: Vec) -> ExecutionV1<'_, Self> { + ExecutionV1::new(calls, self) + } + + fn execute_v3(&self, calls: Vec) -> ExecutionV3<'_, Self> { + ExecutionV3::new(calls, self) + } + + async fn sign_execution_v1( &self, - execution: &RawExecution, + execution: &RawExecutionV1, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let result = match self { - Self::Standard(account) => account.sign_execution(execution, query_only).await?, + Self::Standard(account) => account.sign_execution_v1(execution, query_only).await?, #[cfg(feature = "controller")] - Self::Controller(account) => account.sign_execution(execution, query_only).await?, + Self::Controller(account) => account.sign_execution_v1(execution, query_only).await?, }; Ok(result) } - async fn sign_declaration( + async fn sign_execution_v3( &self, - declaration: &RawDeclaration, + execution: &RawExecutionV3, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { let result = match self { - Self::Standard(account) => account.sign_declaration(declaration, query_only).await?, + Self::Standard(account) => account.sign_execution_v3(execution, query_only).await?, #[cfg(feature = "controller")] - Self::Controller(account) => account.sign_declaration(declaration, query_only).await?, + Self::Controller(account) => account.sign_execution_v3(execution, query_only).await?, }; Ok(result) } @@ -116,7 +140,7 @@ where &self, declaration: &RawLegacyDeclaration, query_only: bool, - ) -> Result, Self::SignError> { + ) -> Result, Self::SignError> { match self { Self::Standard(account) => { let result = account.sign_legacy_declaration(declaration, query_only).await?; @@ -129,6 +153,38 @@ where } } } + + async fn sign_declaration_v2( + &self, + declaration: &RawDeclarationV2, + query_only: bool, + ) -> Result, Self::SignError> { + let result = match self { + Self::Standard(account) => account.sign_declaration_v2(declaration, query_only).await?, + + #[cfg(feature = "controller")] + Self::Controller(account) => { + account.sign_declaration_v2(declaration, query_only).await? + } + }; + Ok(result) + } + + async fn sign_declaration_v3( + &self, + declaration: &RawDeclarationV3, + query_only: bool, + ) -> Result, Self::SignError> { + let result = match self { + Self::Standard(account) => account.sign_declaration_v3(declaration, query_only).await?, + + #[cfg(feature = "controller")] + Self::Controller(account) => { + account.sign_declaration_v3(declaration, query_only).await? + } + }; + Ok(result) + } } impl

ExecutionEncoder for SozoAccount

@@ -136,7 +192,7 @@ where P: Provider, P: Send + Sync, { - fn encode_calls(&self, calls: &[Call]) -> Vec { + fn encode_calls(&self, calls: &[Call]) -> Vec { match self { Self::Standard(account) => account.encode_calls(calls), #[cfg(feature = "controller")] diff --git a/bin/sozo/src/commands/options/signer.rs b/bin/sozo/src/commands/options/signer.rs index 04b59b913b..8f3e6492c2 100644 --- a/bin/sozo/src/commands/options/signer.rs +++ b/bin/sozo/src/commands/options/signer.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use anyhow::{anyhow, Result}; use clap::Args; use dojo_world::metadata::Environment; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::signers::{LocalWallet, SigningKey}; use tracing::trace; @@ -46,7 +46,7 @@ impl SignerOptions { if let Some(private_key) = self.private_key(env_metadata) { trace!(private_key, "Signing using private key."); return Ok(LocalWallet::from_signing_key(SigningKey::from_secret_scalar( - FieldElement::from_str(&private_key)?, + Felt::from_str(&private_key)?, ))); } @@ -102,7 +102,7 @@ mod tests { use clap::Parser; use starknet::signers::{LocalWallet, Signer, SigningKey}; - use starknet_crypto::FieldElement; + use starknet_crypto::Felt; use super::{SignerOptions, DOJO_KEYSTORE_PASSWORD_ENV_VAR, DOJO_PRIVATE_KEY_ENV_VAR}; @@ -135,7 +135,7 @@ mod tests { let cmd = Command::parse_from(["sozo", "--private-key", private_key]); let result_wallet = cmd.signer.signer(None, true).unwrap(); let expected_wallet = LocalWallet::from_signing_key(SigningKey::from_secret_scalar( - FieldElement::from_str(private_key).unwrap(), + Felt::from_str(private_key).unwrap(), )); let result_public_key = result_wallet.get_public_key().await.unwrap(); @@ -154,7 +154,7 @@ mod tests { let cmd = Command::parse_from(["sozo"]); let result_wallet = cmd.signer.signer(Some(&env_metadata), true).unwrap(); let expected_wallet = LocalWallet::from_signing_key(SigningKey::from_secret_scalar( - FieldElement::from_str(private_key).unwrap(), + Felt::from_str(private_key).unwrap(), )); let result_public_key = result_wallet.get_public_key().await.unwrap(); @@ -177,7 +177,7 @@ mod tests { ]); let result_wallet = cmd.signer.signer(None, true).unwrap(); let expected_wallet = LocalWallet::from_signing_key(SigningKey::from_secret_scalar( - FieldElement::from_str(private_key).unwrap(), + Felt::from_str(private_key).unwrap(), )); let result_public_key = result_wallet.get_public_key().await.unwrap(); @@ -199,7 +199,7 @@ mod tests { let cmd = Command::parse_from(["sozo", "--password", keystore_password]); let result_wallet = cmd.signer.signer(Some(&env_metadata), true).unwrap(); let expected_wallet = LocalWallet::from_signing_key(SigningKey::from_secret_scalar( - FieldElement::from_str(private_key).unwrap(), + Felt::from_str(private_key).unwrap(), )); let result_public_key = result_wallet.get_public_key().await.unwrap(); @@ -221,7 +221,7 @@ mod tests { let cmd = Command::parse_from(["sozo", "--keystore", keystore_path]); let result_wallet = cmd.signer.signer(Some(&env_metadata), true).unwrap(); let expected_wallet = LocalWallet::from_signing_key(SigningKey::from_secret_scalar( - FieldElement::from_str(private_key).unwrap(), + Felt::from_str(private_key).unwrap(), )); let result_public_key = result_wallet.get_public_key().await.unwrap(); diff --git a/bin/sozo/src/commands/options/transaction.rs b/bin/sozo/src/commands/options/transaction.rs index f3fb1d9534..bca724fd39 100644 --- a/bin/sozo/src/commands/options/transaction.rs +++ b/bin/sozo/src/commands/options/transaction.rs @@ -1,7 +1,7 @@ use anyhow::{bail, Result}; use clap::Args; use dojo_world::migration::{TxnAction, TxnConfig}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use tracing::trace; #[derive(Debug, Args, Default)] @@ -20,7 +20,7 @@ pub struct TransactionOptions { #[arg(help = "Maximum raw value to be used for fees, in Wei.")] #[arg(conflicts_with = "fee_estimate_multiplier")] #[arg(global = true)] - pub max_fee_raw: Option, + pub max_fee_raw: Option, #[arg(long)] #[arg(help = "Wait until the transaction is accepted by the sequencer, returning the status \ diff --git a/bin/sozo/src/commands/options/world.rs b/bin/sozo/src/commands/options/world.rs index 88f1bbd5f2..0d75ee653c 100644 --- a/bin/sozo/src/commands/options/world.rs +++ b/bin/sozo/src/commands/options/world.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use anyhow::{anyhow, Result}; use clap::Args; use dojo_world::metadata::Environment; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use tracing::trace; use super::DOJO_WORLD_ADDRESS_ENV_VAR; @@ -14,17 +14,17 @@ pub struct WorldOptions { #[arg(help = "The address of the World contract.")] #[arg(long = "world", env = DOJO_WORLD_ADDRESS_ENV_VAR)] #[arg(global = true)] - pub world_address: Option, + pub world_address: Option, } impl WorldOptions { - pub fn address(&self, env_metadata: Option<&Environment>) -> Result { + pub fn address(&self, env_metadata: Option<&Environment>) -> Result { if let Some(world_address) = self.world_address { trace!(?world_address, "Loaded world_address."); Ok(world_address) } else if let Some(world_address) = env_metadata.and_then(|env| env.world_address()) { trace!(world_address, "Loaded world_address from env metadata."); - Ok(FieldElement::from_str(world_address)?) + Ok(Felt::from_str(world_address)?) } else { Err(anyhow!( "Could not find World address. Please specify it with --world, environment \ @@ -38,7 +38,7 @@ impl WorldOptions { mod tests { use clap::Parser; - use starknet_crypto::FieldElement; + use starknet_crypto::Felt; use super::{WorldOptions, DOJO_WORLD_ADDRESS_ENV_VAR}; @@ -53,13 +53,13 @@ mod tests { std::env::set_var(DOJO_WORLD_ADDRESS_ENV_VAR, "0x0"); let cmd = Command::parse_from([""]); - assert_eq!(cmd.inner.world_address, Some(FieldElement::from_hex_be("0x0").unwrap())); + assert_eq!(cmd.inner.world_address, Some(Felt::from_hex("0x0").unwrap())); } #[test] fn world_address_from_args() { let cmd = Command::parse_from(["sozo", "--world", "0x0"]); - assert_eq!(cmd.inner.address(None).unwrap(), FieldElement::from_hex_be("0x0").unwrap()); + assert_eq!(cmd.inner.address(None).unwrap(), Felt::from_hex("0x0").unwrap()); } #[test] @@ -70,10 +70,7 @@ mod tests { }; let cmd = Command::parse_from([""]); - assert_eq!( - cmd.inner.address(Some(&env_metadata)).unwrap(), - FieldElement::from_hex_be("0x0").unwrap() - ); + assert_eq!(cmd.inner.address(Some(&env_metadata)).unwrap(), Felt::from_hex("0x0").unwrap()); } #[test] @@ -84,10 +81,7 @@ mod tests { }; let cmd = Command::parse_from(["sozo", "--world", "0x1"]); - assert_eq!( - cmd.inner.address(Some(&env_metadata)).unwrap(), - FieldElement::from_hex_be("0x1").unwrap() - ); + assert_eq!(cmd.inner.address(Some(&env_metadata)).unwrap(), Felt::from_hex("0x1").unwrap()); } #[test] diff --git a/bin/sozo/src/commands/register.rs b/bin/sozo/src/commands/register.rs index f69fac41d2..0f019643bb 100644 --- a/bin/sozo/src/commands/register.rs +++ b/bin/sozo/src/commands/register.rs @@ -4,7 +4,7 @@ use dojo_world::contracts::WorldContractReader; use scarb::core::Config; use sozo_ops::register; use starknet::accounts::ConnectedAccount; -use starknet::core::types::{BlockId, BlockTag, FieldElement}; +use starknet::core::types::{BlockId, BlockTag, Felt}; use tracing::trace; use super::options::account::AccountOptions; @@ -27,7 +27,7 @@ pub enum RegisterCommand { #[arg(required = true)] #[arg(value_name = "CLASS_HASH")] #[arg(help = "The class hash of the models to register.")] - models: Vec, + models: Vec, #[command(flatten)] world: WorldOptions, diff --git a/bin/torii/src/main.rs b/bin/torii/src/main.rs index d3c85d63d7..2346771da7 100644 --- a/bin/torii/src/main.rs +++ b/bin/torii/src/main.rs @@ -20,7 +20,7 @@ use dojo_metrics::{metrics_process, prometheus_exporter}; use dojo_world::contracts::world::WorldContractReader; use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; use sqlx::SqlitePool; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; use tokio::sync::broadcast; @@ -49,7 +49,7 @@ pub(crate) const LOG_TARGET: &str = "torii::cli"; struct Args { /// The world to index #[arg(short, long = "world", env = "DOJO_WORLD_ADDRESS")] - world_address: FieldElement, + world_address: Felt, /// The sequencer rpc endpoint to index. #[arg(long, value_name = "URL", default_value = ":5050", value_parser = parse_url)] diff --git a/crates/benches/src/deployer.rs b/crates/benches/src/deployer.rs index 2a3aa0e08c..9dcf7e961e 100644 --- a/crates/benches/src/deployer.rs +++ b/crates/benches/src/deployer.rs @@ -12,12 +12,12 @@ use scarb::compiler::CompilerRepository; use scarb::core::Config; use sozo::args::SozoArgs; use sozo::commands::Commands; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use tokio::process::Command; use crate::{CONTRACT, CONTRACT_RELATIVE_TO_TESTS, RUNTIME}; -pub async fn deploy(runner: &KatanaRunner) -> Result { +pub async fn deploy(runner: &KatanaRunner) -> Result { if let Some(contract) = runner.contract().await { return Ok(contract); } @@ -37,15 +37,12 @@ pub async fn deploy(runner: &KatanaRunner) -> Result { Ok(address) } -pub fn deploy_sync(runner: &KatanaRunner) -> Result { +pub fn deploy_sync(runner: &KatanaRunner) -> Result { let _rt = RUNTIME.enter(); block_on(async move { deploy(runner).await }) } -async fn deploy_contract( - runner: &KatanaRunner, - manifest_and_script: (&str, &str), -) -> Result { +async fn deploy_contract(runner: &KatanaRunner, manifest_and_script: (&str, &str)) -> Result { let args = SozoArgs::parse_from([ "sozo", "migrate", @@ -72,7 +69,7 @@ async fn deploy_contract( Ok(constract_address) } -async fn prepare_migration_args(args: SozoArgs) -> Result { +async fn prepare_migration_args(args: SozoArgs) -> Result { // Preparing config, as in https://github.com/dojoengine/dojo/blob/25fbb7fc973cff4ce1273625c4664545d9b088e9/bin/sozo/src/main.rs#L28-L29 let mut compilers = CompilerRepository::std(); let cairo_plugins = CairoPluginRepository::default(); diff --git a/crates/benches/src/helpers.rs b/crates/benches/src/helpers.rs index 24ed166dae..29ffd444a1 100644 --- a/crates/benches/src/helpers.rs +++ b/crates/benches/src/helpers.rs @@ -3,7 +3,7 @@ use std::io::Write; use anyhow::{Context, Result}; use starknet::accounts::{Account, Call, ConnectedAccount, SingleOwnerAccount}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::core::utils::get_selector_from_name; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; @@ -12,12 +12,12 @@ use tokio::sync::OnceCell; pub type OwnerAccount = SingleOwnerAccount, LocalWallet>; #[derive(Clone)] -pub struct BenchCall(pub &'static str, pub Vec); +pub struct BenchCall(pub &'static str, pub Vec); // Because no calls are actually executed in the benchmark, we can use the same nonce for all of // them -pub async fn cached_nonce(account: &OwnerAccount) -> FieldElement { - static NONCE: OnceCell = OnceCell::const_new(); +pub async fn cached_nonce(account: &OwnerAccount) -> Felt { + static NONCE: OnceCell = OnceCell::const_new(); *NONCE.get_or_init(|| async { account.get_nonce().await.unwrap() }).await } @@ -34,7 +34,7 @@ pub fn log(name: &str, gas: u64, calldata: &str) { file.flush().unwrap(); } -pub fn parse_calls(calls: Vec, to: FieldElement) -> Vec { +pub fn parse_calls(calls: Vec, to: Felt) -> Vec { calls .into_iter() .map(|BenchCall(name, calldata)| Call { @@ -45,9 +45,9 @@ pub fn parse_calls(calls: Vec, to: FieldElement) -> Vec { .collect() } -pub async fn estimate_calls(account: &OwnerAccount, calls: Vec) -> Result { +pub async fn estimate_calls(account: &OwnerAccount, calls: Vec) -> Result { let fee = account - .execute(calls) + .execute_v1(calls) .nonce(cached_nonce(account).await) .estimate_fee() .await @@ -56,12 +56,8 @@ pub async fn estimate_calls(account: &OwnerAccount, calls: Vec) -> Result< Ok(fee.gas_consumed) } -pub async fn execute_calls( - account: OwnerAccount, - calls: Vec, - nonce: FieldElement, -) -> Result<()> { - account.execute(calls).nonce(nonce).send().await.context("Failed to execute").unwrap(); +pub async fn execute_calls(account: OwnerAccount, calls: Vec, nonce: Felt) -> Result<()> { + account.execute_v1(calls).nonce(nonce).send().await.context("Failed to execute").unwrap(); Ok(()) } diff --git a/crates/benches/src/lib.rs b/crates/benches/src/lib.rs index e7597cafac..7471444fde 100644 --- a/crates/benches/src/lib.rs +++ b/crates/benches/src/lib.rs @@ -10,7 +10,7 @@ use futures::future; pub use helpers::*; pub use katana_runner::runner; use lazy_static::lazy_static; -pub use starknet::core::types::FieldElement; +pub use starknet::core::types::Felt; use tokio::runtime::Runtime; pub const ENOUGH_GAS: &str = "0x100000000000000000"; @@ -25,8 +25,8 @@ lazy_static! { pub fn estimate_gas_last( account: &OwnerAccount, calls: Vec, - contract: FieldElement, -) -> Result { + contract: Felt, +) -> Result { let mut calls = parse_calls(calls, contract); let all = calls.clone(); calls.pop().expect("Empty calls vector"); // remove last call @@ -39,11 +39,7 @@ pub fn estimate_gas_last( }) } -pub fn estimate_gas( - account: &OwnerAccount, - call: BenchCall, - contract: FieldElement, -) -> Result { +pub fn estimate_gas(account: &OwnerAccount, call: BenchCall, contract: Felt) -> Result { let calls = parse_calls(vec![call], contract); let _rt = RUNTIME.enter(); block_on(async move { estimate_calls(account, calls).await }) @@ -52,8 +48,8 @@ pub fn estimate_gas( pub fn estimate_gas_multiple( account: &OwnerAccount, calls: Vec, - contract: FieldElement, -) -> Result { + contract: Felt, +) -> Result { let calls = parse_calls(calls, contract); let _rt = RUNTIME.enter(); block_on(async move { estimate_calls(account, calls).await }) @@ -62,8 +58,8 @@ pub fn estimate_gas_multiple( pub async fn estimate_gas_async( account: &OwnerAccount, calls: Vec, - contract: FieldElement, -) -> Result { + contract: Felt, +) -> Result { let calls = parse_calls(calls, contract); estimate_calls(account, calls).await } @@ -96,7 +92,7 @@ mod tests { let fee = estimate_gas_last(&runner.account(1), vec![ BenchCall("spawn", vec![]), - BenchCall("move", vec![FieldElement::from_hex_be(&c).unwrap()]) + BenchCall("move", vec![Felt::from_hex_be(&c).unwrap()]) ], contract_address).unwrap(); log("bench_move", fee, &c); diff --git a/crates/benches/src/spammer.rs b/crates/benches/src/spammer.rs index 752c32aae0..541a20ae82 100644 --- a/crates/benches/src/spammer.rs +++ b/crates/benches/src/spammer.rs @@ -3,7 +3,7 @@ use std::time::Duration; use futures::future::join_all; use katana_runner::KatanaRunner; use starknet::accounts::{Account, SingleOwnerAccount}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; use starknet::signers::LocalWallet; @@ -15,24 +15,24 @@ use crate::{parse_calls, BenchCall, ENOUGH_GAS}; async fn spam_no_stats( runner: &KatanaRunner, accounts: &[SingleOwnerAccount, LocalWallet>], - contract_address: FieldElement, + contract_address: Felt, calldata: Vec, wait_time: Duration, -) -> FieldElement { - let max_fee = FieldElement::from_hex_be(ENOUGH_GAS).unwrap(); - let mut nonce = FieldElement::ONE; +) -> Felt { + let max_fee = Felt::from_hex(ENOUGH_GAS).unwrap(); + let mut nonce = Felt::ONE; for call in parse_calls(calldata, contract_address) { let transactions = accounts .iter() - .map(|account| account.execute(vec![call.clone()]).nonce(nonce).max_fee(max_fee)) + .map(|account| account.execute_v1(vec![call.clone()]).nonce(nonce).max_fee(max_fee)) .collect::>(); join_all(transactions.iter().map(|t| t.send())).await; sleep(wait_time).await; runner.blocks_until_empty().await; - nonce += FieldElement::ONE; + nonce += Felt::ONE; } nonce @@ -40,12 +40,12 @@ async fn spam_no_stats( pub async fn spam_katana( runner: KatanaRunner, - contract_address: FieldElement, + contract_address: Felt, mut calldata: Vec, additional_sleep: u64, sequential: bool, ) -> BenchSummary { - let max_fee = FieldElement::from_hex_be(ENOUGH_GAS).unwrap(); + let max_fee = Felt::from_hex(ENOUGH_GAS).unwrap(); let transaction_sum_before: u32 = runner.block_sizes().await.iter().sum(); let steps_before = runner.steps().await; @@ -78,7 +78,7 @@ pub async fn spam_katana( let final_transactions = accounts .iter() .map(|account| { - let move_call = account.execute(calls.clone()).nonce(nonce).max_fee(max_fee); + let move_call = account.execute_v1(calls.clone()).nonce(nonce).max_fee(max_fee); move_call }) .collect::>(); diff --git a/crates/benches/tests/basic.rs b/crates/benches/tests/basic.rs index a2d8d8e25e..6f86fdafe9 100644 --- a/crates/benches/tests/basic.rs +++ b/crates/benches/tests/basic.rs @@ -4,7 +4,7 @@ mod imports { pub use hex::ToHex; pub use katana_runner::runner; pub use proptest::prelude::*; - pub use starknet::core::types::FieldElement; + pub use starknet::core::types::Felt; } #[cfg(not(feature = "skip-gas-benchmarks"))] @@ -17,7 +17,7 @@ proptest! { runner!(bench_basic_emit); let contract_address = deploy_sync(runner).unwrap(); - let s_hex = FieldElement::from_hex_be(&format!("0x{}", s.as_bytes().encode_hex::())).unwrap(); + let s_hex = Felt::from_hex_be(&format!("0x{}", s.as_bytes().encode_hex::())).unwrap(); let fee = estimate_gas( &runner.account(1), @@ -32,7 +32,7 @@ proptest! { runner!(bench_basic_set); let contract_address = deploy_sync(runner).unwrap(); - let s_hex = FieldElement::from_hex_be(&format!("0x{}", s.as_bytes().encode_hex::())).unwrap(); + let s_hex = Felt::from_hex_be(&format!("0x{}", s.as_bytes().encode_hex::())).unwrap(); let fee = estimate_gas(&runner.account(1), BenchCall("bench_basic_set", vec![s_hex]), contract_address @@ -46,7 +46,7 @@ proptest! { runner!(bench_basic_double_set); let contract_address = deploy_sync(runner).unwrap(); - let s_hex = FieldElement::from_hex_be(&format!("0x{}", s.as_bytes().encode_hex::())).unwrap(); + let s_hex = Felt::from_hex_be(&format!("0x{}", s.as_bytes().encode_hex::())).unwrap(); let fee = estimate_gas(&runner.account(1), BenchCall("bench_basic_double_set", vec![s_hex]), contract_address @@ -60,7 +60,7 @@ proptest! { runner!(bench_basic_get); let contract_address = deploy_sync(runner).unwrap(); - let s_hex = FieldElement::from_hex_be(&format!("0x{}", s.as_bytes().encode_hex::())).unwrap(); + let s_hex = Felt::from_hex_be(&format!("0x{}", s.as_bytes().encode_hex::())).unwrap(); let fee = estimate_gas_last(&runner.account(1), vec![ BenchCall("bench_basic_set", vec![s_hex]), BenchCall("bench_basic_get", vec![]) diff --git a/crates/benches/tests/character.rs b/crates/benches/tests/character.rs index 01c5b98270..b5004c1832 100644 --- a/crates/benches/tests/character.rs +++ b/crates/benches/tests/character.rs @@ -1,7 +1,6 @@ #[cfg(not(feature = "skip-gas-benchmarks"))] pub use benches::{ - deploy, deploy_sync, estimate_gas, estimate_gas_last, log, runner, BenchCall, FieldElement, - CONTRACT, + deploy, deploy_sync, estimate_gas, estimate_gas_last, log, runner, BenchCall, Felt, CONTRACT, }; #[cfg(not(feature = "skip-gas-benchmarks"))] pub use proptest::prelude::*; @@ -30,7 +29,7 @@ proptest! { let points = s.chars() .map(|c| c.to_digit(10).unwrap()) - .map(FieldElement::from) + .map(Felt::from) .collect(); let fee = estimate_gas(&runner.account(1), @@ -45,7 +44,7 @@ proptest! { runner!(bench_complex_update_minimal); let contract_address = deploy_sync(runner).unwrap(); - let calldata = FieldElement::from(s.parse::().unwrap()); + let calldata = Felt::from(s.parse::().unwrap()); let fee = estimate_gas_last(&runner.account(1), vec![ BenchCall("bench_complex_set_default", vec![]), BenchCall("bench_complex_update_minimal", vec![calldata]) @@ -59,7 +58,7 @@ proptest! { runner!(bench_complex_update_minimal_nested); let contract_address = deploy_sync(runner).unwrap(); - let calldata = FieldElement::from(w as u32); + let calldata = Felt::from(w as u32); let fee = estimate_gas_last(&runner.account(1), vec![ BenchCall("bench_complex_set_default", vec![]), BenchCall("bench_complex_update_minimal_nested", vec![calldata]) @@ -75,7 +74,7 @@ proptest! { let calldata = s.chars() .map(|c| c.to_digit(10).unwrap()) - .map(FieldElement::from) + .map(Felt::from) .collect(); let fee = estimate_gas_last(&runner.account(1), vec![ BenchCall("bench_complex_set_with_smaller", calldata), @@ -90,7 +89,7 @@ proptest! { runner!(bench_complex_get_minimal); let contract_address = deploy_sync(runner).unwrap(); - let calldata = FieldElement::from(s.parse::().unwrap()); + let calldata = Felt::from(s.parse::().unwrap()); let fee = estimate_gas_last(&runner.account(1), vec![ BenchCall("bench_complex_set_default", vec![]), BenchCall("bench_complex_update_minimal", vec![calldata]), @@ -107,11 +106,11 @@ proptest! { let abilities = s.chars() .map(|c| c.to_digit(10).unwrap()) - .map(FieldElement::from) + .map(Felt::from) .collect(); - let ability = FieldElement::from(a as u32); - let threshold = FieldElement::from(t as u32); + let ability = Felt::from(a as u32); + let threshold = Felt::from(t as u32); let fee = estimate_gas_last(&runner.account(1), vec![ BenchCall("bench_complex_set_with_smaller", abilities), diff --git a/crates/benches/tests/heavy.rs b/crates/benches/tests/heavy.rs index 45c49aace6..22e14899a3 100644 --- a/crates/benches/tests/heavy.rs +++ b/crates/benches/tests/heavy.rs @@ -2,12 +2,12 @@ mod katana_benchmarks { use benches::spammer::spam_katana; use benches::{deploy, BenchCall}; - use starknet::core::types::FieldElement; + use starknet::core::types::Felt; #[katana_runner::katana_test(1, true, "../../target/release/katana")] async fn katana_heavy_prime_single() { let contract_address = deploy(&runner).await.unwrap(); - let arg = FieldElement::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); + let arg = Felt::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); let result = spam_katana( runner, @@ -25,7 +25,7 @@ mod katana_benchmarks { #[katana_runner::katana_test(100, true, "../../target/release/katana")] async fn katana_heavy_prime_100() { let contract_address = deploy(&runner).await.unwrap(); - let arg = FieldElement::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); + let arg = Felt::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); let result = spam_katana( runner, @@ -43,7 +43,7 @@ mod katana_benchmarks { #[katana_runner::katana_test(1000, true, "../../target/release/katana")] async fn katana_heavy_prime_1000_a() { let contract_address = deploy(&runner).await.unwrap(); - let arg = FieldElement::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); + let arg = Felt::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); let result = spam_katana( runner, @@ -61,7 +61,7 @@ mod katana_benchmarks { #[katana_runner::katana_test(1000, true, "../../target/release/katana")] async fn katana_heavy_prime_1000_b() { let contract_address = deploy(&runner).await.unwrap(); - let arg = FieldElement::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); + let arg = Felt::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); let result = spam_katana( runner, @@ -79,7 +79,7 @@ mod katana_benchmarks { #[katana_runner::katana_test(1000, true, "../../target/release/katana")] async fn katana_heavy_prime_1000_c() { let contract_address = deploy(&runner).await.unwrap(); - let arg = FieldElement::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); + let arg = Felt::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); let result = spam_katana( runner, @@ -97,7 +97,7 @@ mod katana_benchmarks { #[katana_runner::katana_test(2000, true, "../../target/release/katana")] async fn katana_heavy_prime_2000_a() { let contract_address = deploy(&runner).await.unwrap(); - let arg = FieldElement::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); + let arg = Felt::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); let result = spam_katana( runner, @@ -115,7 +115,7 @@ mod katana_benchmarks { #[katana_runner::katana_test(2000, true, "../../target/release/katana")] async fn katana_heavy_prime_2000_b() { let contract_address = deploy(&runner).await.unwrap(); - let arg = FieldElement::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); + let arg = Felt::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); let result = spam_katana( runner, @@ -133,7 +133,7 @@ mod katana_benchmarks { #[katana_runner::katana_test(2000, true, "../../target/release/katana")] async fn katana_heavy_prime_2000_c() { let contract_address = deploy(&runner).await.unwrap(); - let arg = FieldElement::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); + let arg = Felt::from_dec_str(&(2111u64 * 2111u64).to_string()).unwrap(); let result = spam_katana( runner, @@ -151,7 +151,7 @@ mod katana_benchmarks { #[katana_runner::katana_test(2000, true, "../../target/release/katana")] async fn katana_heavy_multicall_2000() { let contract_address = deploy(&runner).await.unwrap(); - let arg = FieldElement::from_dec_str(&(109u64 * 109u64).to_string()).unwrap(); + let arg = Felt::from_dec_str(&(109u64 * 109u64).to_string()).unwrap(); let calls = (0..23).map(|_| BenchCall("is_prime", vec![arg])).collect(); let result = spam_katana(runner, contract_address, calls, 120000, true).await; diff --git a/crates/benches/tests/katana_ramp_up.rs b/crates/benches/tests/katana_ramp_up.rs index 852733f710..c92b32d9b1 100644 --- a/crates/benches/tests/katana_ramp_up.rs +++ b/crates/benches/tests/katana_ramp_up.rs @@ -5,11 +5,11 @@ mod katana_benchmarks { use benches::summary::BenchSummary; use benches::{deploy, BenchCall}; use katana_runner::KatanaRunner; - use starknet::core::types::FieldElement; + use starknet::core::types::Felt; - async fn run(runner: KatanaRunner, contract_address: FieldElement) -> BenchSummary { + async fn run(runner: KatanaRunner, contract_address: Felt) -> BenchSummary { let spawn = BenchCall("spawn", vec![]); - let calldata_move = BenchCall("move", vec![FieldElement::from_hex_be("0x3").unwrap()]); + let calldata_move = BenchCall("move", vec![Felt::from_hex_be("0x3").unwrap()]); spam_katana(runner, contract_address, vec![spawn, calldata_move], 0, true).await } diff --git a/crates/benches/tests/primitive.rs b/crates/benches/tests/primitive.rs index 4c5e65e545..cbe85425a4 100644 --- a/crates/benches/tests/primitive.rs +++ b/crates/benches/tests/primitive.rs @@ -1,5 +1,5 @@ #[cfg(not(feature = "skip-gas-benchmarks"))] -use benches::{deploy_sync, estimate_gas, log, runner, BenchCall, FieldElement}; +use benches::{deploy_sync, estimate_gas, log, runner, BenchCall, Felt}; #[cfg(not(feature = "skip-gas-benchmarks"))] use proptest::prelude::*; @@ -13,7 +13,7 @@ proptest! { let args = s.chars().map(|c| { let c = String::from(c); let hex = format!("0x{}", c); - FieldElement::from_hex_be(&hex).unwrap() + Felt::from_hex_be(&hex).unwrap() }).collect::>(); let fee = estimate_gas(&runner.account(1), @@ -29,7 +29,7 @@ proptest! { let contract_address = deploy_sync(runner).unwrap(); let s = format!("{}", s); - let s_hex = FieldElement::from_dec_str(&s).unwrap(); + let s_hex = Felt::from_dec_str(&s).unwrap(); let fee = estimate_gas(&runner.account(1), BenchCall("bench_primitive_iter", vec![s_hex]), contract_address @@ -46,7 +46,7 @@ proptest! { let a = format!("{}", a); let b = format!("{}", b); let c = format!("{}", c); - let args = vec![a.clone(), b.clone(), c.clone()].into_iter().map(|d| FieldElement::from_dec_str(&d).unwrap()).collect::>(); + let args = vec![a.clone(), b.clone(), c.clone()].into_iter().map(|d| Felt::from_dec_str(&d).unwrap()).collect::>(); let fee = estimate_gas(&runner.account(1), BenchCall("bench_primitive_hash", args), contract_address diff --git a/crates/dojo-lang/src/compiler.rs b/crates/dojo-lang/src/compiler.rs index e21edfe2bb..a0eac5529b 100644 --- a/crates/dojo-lang/src/compiler.rs +++ b/crates/dojo-lang/src/compiler.rs @@ -32,7 +32,7 @@ use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use smol_str::SmolStr; use starknet::core::types::contract::SierraClass; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use tracing::{debug, trace, trace_span}; use crate::inline_macros::utils::{SYSTEM_READS, SYSTEM_WRITES}; @@ -112,8 +112,7 @@ impl Compiler for DojoCompiler { }; // (contract name, class hash) - let mut compiled_classes: HashMap)> = - HashMap::new(); + let mut compiled_classes: HashMap)> = HashMap::new(); for (decl, class) in zip(contracts, classes) { let contract_full_path = decl.module_id().full_path(db.upcast_mut()); @@ -154,7 +153,7 @@ impl Compiler for DojoCompiler { } } -fn compute_class_hash_of_contract_class(class: &ContractClass) -> Result { +fn compute_class_hash_of_contract_class(class: &ContractClass) -> Result { let class_str = serde_json::to_string(&class)?; let sierra_class = serde_json::from_str::(&class_str) .map_err(|e| anyhow!("error parsing Sierra class: {e}"))?; @@ -228,7 +227,7 @@ fn update_manifest( db: &RootDatabase, ws: &Workspace<'_>, crate_ids: &[CrateId], - compiled_artifacts: HashMap)>, + compiled_artifacts: HashMap)>, external_contracts: Option>, ) -> anyhow::Result<()> { let profile_name = @@ -240,9 +239,9 @@ fn update_manifest( let manifest_dir = ws.manifest_path().parent().unwrap().to_path_buf(); fn get_compiled_artifact_from_map<'a>( - artifacts: &'a HashMap)>, + artifacts: &'a HashMap)>, artifact_name: &str, - ) -> anyhow::Result<&'a (FieldElement, Option)> { + ) -> anyhow::Result<&'a (Felt, Option)> { artifacts.get(artifact_name).context(format!( "Contract `{artifact_name}` not found. Did you include `dojo` as a dependency?", )) @@ -357,7 +356,7 @@ fn get_dojo_model_artifacts( db: &RootDatabase, aux_data: &DojoAuxData, module_id: ModuleId, - compiled_classes: &HashMap)>, + compiled_classes: &HashMap)>, ) -> anyhow::Result, Option)>> { let mut models = HashMap::with_capacity(aux_data.models.len()); @@ -425,7 +424,7 @@ fn get_dojo_contract_artifacts( db: &RootDatabase, module_id: &ModuleId, aux_data: &StarkNetContractAuxData, - compiled_classes: &HashMap)>, + compiled_classes: &HashMap)>, ) -> anyhow::Result, Option)>> { let contract_name = &aux_data.contract_name; diff --git a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/Scarb.lock b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/Scarb.lock index 815d300273..aaf6fd8731 100644 --- a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/Scarb.lock +++ b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/Scarb.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "dojo" -version = "0.7.2" +version = "0.7.3" dependencies = [ "dojo_plugin", ] diff --git a/crates/dojo-test-utils/Cargo.toml b/crates/dojo-test-utils/Cargo.toml index 7df12f7709..2986b743b8 100644 --- a/crates/dojo-test-utils/Cargo.toml +++ b/crates/dojo-test-utils/Cargo.toml @@ -22,6 +22,7 @@ katana-executor = { workspace = true, features = [ "blockifier" ] } katana-primitives = { path = "../katana/primitives" } katana-rpc = { path = "../katana/rpc/rpc" } katana-rpc-api = { path = "../katana/rpc/rpc-api" } +katana-starknet = { package = "starknet", version = "=0.10.0" } scarb-ui.workspace = true scarb.workspace = true serde.workspace = true diff --git a/crates/dojo-test-utils/src/migration.rs b/crates/dojo-test-utils/src/migration.rs index d0ecc91126..c57f4f75b3 100644 --- a/crates/dojo-test-utils/src/migration.rs +++ b/crates/dojo-test-utils/src/migration.rs @@ -3,7 +3,7 @@ use camino::Utf8PathBuf; use dojo_world::manifest::{BaseManifest, OverlayManifest, BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR}; use dojo_world::migration::strategy::{prepare_for_migration, MigrationStrategy}; use dojo_world::migration::world::WorldDiff; -use katana_primitives::FieldElement; +use starknet::core::types::Felt; use starknet::core::utils::cairo_short_string_to_felt; use starknet::macros::felt; @@ -43,7 +43,7 @@ pub fn prepare_migration( pub fn prepare_migration_with_world_and_seed( manifest_dir: Utf8PathBuf, target_dir: Utf8PathBuf, - world_address: Option, + world_address: Option, seed: &str, ) -> Result { // In testing, profile name is always dev. diff --git a/crates/dojo-test-utils/src/sequencer.rs b/crates/dojo-test-utils/src/sequencer.rs index 086d4dc26b..0e2307d5fe 100644 --- a/crates/dojo-test-utils/src/sequencer.rs +++ b/crates/dojo-test-utils/src/sequencer.rs @@ -15,15 +15,15 @@ use katana_rpc::{spawn, NodeHandle}; use katana_rpc_api::ApiKind; use starknet::accounts::{ExecutionEncoding, SingleOwnerAccount}; use starknet::core::chain_id; -use starknet::core::types::{BlockId, BlockTag, FieldElement}; +use starknet::core::types::{BlockId, BlockTag, Felt}; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; use starknet::signers::{LocalWallet, SigningKey}; use url::Url; pub struct TestAccount { - pub private_key: FieldElement, - pub account_address: FieldElement, + pub private_key: Felt, + pub account_address: Felt, } #[allow(unused)] @@ -85,8 +85,8 @@ impl TestSequencer { let account = sequencer.backend.config.genesis.accounts().next().unwrap(); let account = TestAccount { - private_key: account.1.private_key().unwrap(), - account_address: (*account.0).into(), + private_key: Felt::from_bytes_be(&account.1.private_key().unwrap().to_bytes_be()), + account_address: Felt::from_bytes_be(&account.0.to_bytes_be()), }; TestSequencer { sequencer, account, handle, url } @@ -97,11 +97,11 @@ impl TestSequencer { JsonRpcClient::new(HttpTransport::new(self.url.clone())), LocalWallet::from_signing_key(SigningKey::from_secret_scalar(self.account.private_key)), self.account.account_address, - chain_id::TESTNET, + chain_id::SEPOLIA, ExecutionEncoding::New, ); - account.set_block_id(BlockId::Tag(BlockTag::Pending)); + account.set_block_id(starknet::core::types::BlockId::Tag(BlockTag::Pending)); account } @@ -117,14 +117,14 @@ impl TestSequencer { let accounts: Vec<_> = self.sequencer.backend.config.genesis.accounts().collect::<_>(); let account = accounts[index]; - let private_key = account.1.private_key().unwrap(); - let address: FieldElement = (*(account.0)).into(); + let private_key = Felt::from_bytes_be(&account.1.private_key().unwrap().to_bytes_be()); + let address: Felt = Felt::from_bytes_be(&account.0.to_bytes_be()); let mut account = SingleOwnerAccount::new( JsonRpcClient::new(HttpTransport::new(self.url.clone())), LocalWallet::from_signing_key(SigningKey::from_secret_scalar(private_key)), address, - chain_id::TESTNET, + chain_id::SEPOLIA, ExecutionEncoding::New, ); @@ -149,7 +149,7 @@ impl TestSequencer { pub fn get_default_test_starknet_config() -> StarknetConfig { StarknetConfig { disable_fee: true, - env: Environment { chain_id: ChainId::GOERLI, ..Default::default() }, + env: Environment { chain_id: ChainId::SEPOLIA, ..Default::default() }, ..Default::default() } } diff --git a/crates/dojo-types/Cargo.toml b/crates/dojo-types/Cargo.toml index 4603f32e83..4ee140db0f 100644 --- a/crates/dojo-types/Cargo.toml +++ b/crates/dojo-types/Cargo.toml @@ -9,6 +9,7 @@ version.workspace = true crypto-bigint.workspace = true hex.workspace = true itertools.workspace = true +num-traits.workspace = true serde.workspace = true starknet.workspace = true strum.workspace = true diff --git a/crates/dojo-types/src/event.rs b/crates/dojo-types/src/event.rs index 38319ff684..9693676840 100644 --- a/crates/dojo-types/src/event.rs +++ b/crates/dojo-types/src/event.rs @@ -1,31 +1,31 @@ -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; /// The event emitted when a World is spawned. #[derive(Clone, Debug)] pub struct WorldSpawned { - pub address: FieldElement, - pub caller: FieldElement, + pub address: Felt, + pub caller: Felt, } /// The event emitted when a model is registered to a World. #[derive(Clone, Debug)] pub struct ModelRegistered { pub name: String, - pub class_hash: FieldElement, + pub class_hash: Felt, } /// The event emmitted when a model value of an entity is set. #[derive(Clone, Debug)] pub struct StoreSetRecord { - pub table_id: FieldElement, - pub keys: Vec, + pub table_id: Felt, + pub keys: Vec, pub offset: u8, - pub value: Vec, + pub value: Vec, } /// The event emmitted when a model is deleted from an entity. #[derive(Clone, Debug)] pub struct StoreDelRecord { - pub table_id: FieldElement, - pub keys: Vec, + pub table_id: Felt, + pub keys: Vec, } diff --git a/crates/dojo-types/src/lib.rs b/crates/dojo-types/src/lib.rs index bb73984aa1..31b65f3332 100644 --- a/crates/dojo-types/src/lib.rs +++ b/crates/dojo-types/src/lib.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use schema::ModelMetadata; use serde::Serialize; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; pub mod event; pub mod packing; @@ -14,8 +14,8 @@ pub mod system; /// Represents the metadata of a World #[derive(Debug, Clone, Serialize, Default)] pub struct WorldMetadata { - pub world_address: FieldElement, - pub world_class_hash: FieldElement, + pub world_address: Felt, + pub world_class_hash: Felt, pub models: HashMap, } diff --git a/crates/dojo-types/src/packing.rs b/crates/dojo-types/src/packing.rs index c231107dcc..6817bb5447 100644 --- a/crates/dojo-types/src/packing.rs +++ b/crates/dojo-types/src/packing.rs @@ -1,21 +1,23 @@ +use std::any::type_name; use std::str::FromStr; use crypto_bigint::U256; -use starknet::core::types::{FieldElement, FromStrError, ValueOutOfRangeError}; +use num_traits::ToPrimitive; +use starknet::core::types::{Felt, FromStrError}; use starknet::core::utils::{ cairo_short_string_to_felt, parse_cairo_short_string, CairoShortStringToFeltError, ParseCairoShortStringError, }; -use crate::primitive::Primitive; +use crate::primitive::{Primitive, PrimitiveError}; use crate::schema::{self, EnumOption, Ty}; #[derive(Debug, thiserror::Error)] pub enum ParseError { #[error("Invalid schema: {0}")] InvalidSchema(String), - #[error("Error when parsing felt: {0}")] - ValueOutOfRange(#[from] ValueOutOfRangeError), + #[error("Value out of range")] + Primitive(#[from] PrimitiveError), #[error("Error when parsing felt: {0}")] FromStr(#[from] FromStrError), #[error(transparent)] @@ -40,6 +42,8 @@ pub enum PackingError { Parse(#[from] ParseError), #[error("Error when unpacking entity")] UnpackingEntityError, + #[error(transparent)] + Primitive(#[from] PrimitiveError), } /// Unpacks a vector of packed values according to a given layout. @@ -51,28 +55,29 @@ pub enum PackingError { /// /// # Returns /// -/// * `Result, PackingError>` - A Result containing a vector of unpacked -/// FieldElement values if successful, or an error if unsuccessful. -pub fn unpack( - mut packed: Vec, - layout: Vec, -) -> Result, PackingError> { +/// * `Result, PackingError>` - A Result containing a vector of unpacked Felt values if +/// successful, or an error if unsuccessful. +pub fn unpack(mut packed: Vec, layout: Vec) -> Result, PackingError> { packed.reverse(); let mut unpacked = vec![]; - let mut unpacking: U256 = - packed.pop().ok_or(PackingError::UnpackingEntityError)?.as_ref().into(); + let felt = packed.pop().ok_or(PackingError::UnpackingEntityError)?; + let mut unpacking = U256::from_be_slice(&felt.to_bytes_be()); let mut offset = 0; - // Iterate over the layout. for size in layout { - let size: u8 = size.try_into().map_err(ParseError::ValueOutOfRange)?; + let size: u8 = size.to_u8().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: size, + })?; + let size: usize = size.into(); let remaining_bits = 251 - offset; // If there are less remaining bits than the size, move to the next felt for unpacking. if remaining_bits < size { - unpacking = packed.pop().ok_or(PackingError::UnpackingEntityError)?.as_ref().into(); + let felt = packed.pop().ok_or(PackingError::UnpackingEntityError)?; + unpacking = U256::from_be_slice(&felt.to_bytes_be()); offset = 0; } @@ -82,8 +87,7 @@ pub fn unpack( } let result = mask & (unpacking >> offset); - let result_fe = - FieldElement::from_hex_be(&result.to_string()).map_err(ParseError::FromStr)?; + let result_fe = Felt::from_hex(&result.to_string()).map_err(ParseError::FromStr)?; unpacked.push(result_fe); // Update unpacking to be the shifted value after extracting the result. @@ -94,7 +98,7 @@ pub fn unpack( } /// Parse a raw schema of a model into a Cairo type, [Ty] -pub fn parse_ty(data: &[FieldElement]) -> Result { +pub fn parse_ty(data: &[Felt]) -> Result { if data.is_empty() { return Err(ParseError::invalid_schema_with_msg( "The function parse_ty expects at least one felt to know the member type variant, \ @@ -102,7 +106,11 @@ pub fn parse_ty(data: &[FieldElement]) -> Result { )); } - let member_type: u8 = data[0].try_into()?; + let member_type: u8 = data[0].to_u8().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: data[0], + })?; + match member_type { 0 => parse_simple(&data[1..]), 1 => parse_struct(&data[1..]), @@ -117,7 +125,7 @@ pub fn parse_ty(data: &[FieldElement]) -> Result { } } -fn parse_simple(data: &[FieldElement]) -> Result { +fn parse_simple(data: &[Felt]) -> Result { let ty = parse_cairo_short_string(&data[0])?; let primitive = match Primitive::from_str(&ty) { Ok(primitive) => primitive, @@ -132,7 +140,7 @@ fn parse_simple(data: &[FieldElement]) -> Result { Ok(Ty::Primitive(primitive)) } -fn parse_struct(data: &[FieldElement]) -> Result { +fn parse_struct(data: &[Felt]) -> Result { // A struct has at least 3 elements: name, attrs len, and children len. if data.len() < 3 { return Err(ParseError::invalid_schema_with_msg(&format!( @@ -144,12 +152,18 @@ fn parse_struct(data: &[FieldElement]) -> Result { let name = parse_cairo_short_string(&data[0])?; - let attrs_len: u32 = data[1].try_into()?; + let attrs_len: u32 = data[1].to_u32().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: data[1], + })?; let attrs_slice_start = 2; let attrs_slice_end = attrs_slice_start + attrs_len as usize; let _attrs = &data[attrs_slice_start..attrs_slice_end]; - let children_len: u32 = data[attrs_slice_end].try_into()?; + let children_len: u32 = data[attrs_slice_end].to_u32().ok_or_else(|| { + PrimitiveError::ValueOutOfRange { r#type: type_name::(), value: data[attrs_slice_end] } + })?; + let children_len = children_len as usize; let mut children = vec![]; @@ -157,7 +171,10 @@ fn parse_struct(data: &[FieldElement]) -> Result { for i in 0..children_len { let start = i + offset; - let len: u32 = data[start].try_into()?; + let len: u32 = data[start].to_u32().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: data[start], + })?; let slice_start = start + 1; let slice_end = slice_start + len as usize; children.push(parse_member(&data[slice_start..slice_end])?); @@ -167,7 +184,7 @@ fn parse_struct(data: &[FieldElement]) -> Result { Ok(Ty::Struct(schema::Struct { name, children })) } -fn parse_member(data: &[FieldElement]) -> Result { +fn parse_member(data: &[Felt]) -> Result { if data.len() < 3 { return Err(ParseError::invalid_schema_with_msg(&format!( "The function parse_member expects at least three felts: name, attributes len, and \ @@ -178,7 +195,10 @@ fn parse_member(data: &[FieldElement]) -> Result { let name = parse_cairo_short_string(&data[0])?; - let attributes_len: u32 = data[1].try_into()?; + let attributes_len: u32 = data[1].to_u32().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: data[1], + })?; let slice_start = 2; let slice_end = slice_start + attributes_len as usize; let attributes = &data[slice_start..slice_end]; @@ -189,7 +209,7 @@ fn parse_member(data: &[FieldElement]) -> Result { Ok(schema::Member { name, ty, key }) } -fn parse_enum(data: &[FieldElement]) -> Result { +fn parse_enum(data: &[Felt]) -> Result { if data.len() < 3 { return Err(ParseError::invalid_schema_with_msg(&format!( "The function parse_enum expects at least three felts: name, attributes len, and \ @@ -200,12 +220,17 @@ fn parse_enum(data: &[FieldElement]) -> Result { let name = parse_cairo_short_string(&data[0])?; - let attrs_len: u32 = data[1].try_into()?; + let attrs_len: u32 = data[1].to_u32().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: data[1], + })?; let attrs_slice_start = 2; let attrs_slice_end = attrs_slice_start + attrs_len as usize; let _attrs = &data[attrs_slice_start..attrs_slice_end]; - let values_len: u32 = data[attrs_slice_end].try_into()?; + let values_len: u32 = data[attrs_slice_end].to_u32().ok_or_else(|| { + PrimitiveError::ValueOutOfRange { r#type: type_name::(), value: data[attrs_slice_end] } + })?; let values_len = values_len as usize; let mut values = vec![]; @@ -215,7 +240,10 @@ fn parse_enum(data: &[FieldElement]) -> Result { let start = i + offset; let name = parse_cairo_short_string(&data[start])?; let slice_start = start + 2; - let len: u32 = data[start + 3].try_into()?; + let len: u32 = data[start + 3].to_u32().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: data[start + 3], + })?; let len = len + 1; // Account for Ty enum index let slice_end = slice_start + len as usize; @@ -226,13 +254,16 @@ fn parse_enum(data: &[FieldElement]) -> Result { Ok(Ty::Enum(schema::Enum { name, option: None, options: values })) } -fn parse_tuple(data: &[FieldElement]) -> Result { +fn parse_tuple(data: &[Felt]) -> Result { if data.is_empty() { // The unit type is defined as an empty tuple. return Ok(Ty::Tuple(vec![])); } - let children_len: u32 = data[0].try_into()?; + let children_len: u32 = data[0].to_u32().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: data[0], + })?; let children_len = children_len as usize; let mut children = vec![]; @@ -240,7 +271,10 @@ fn parse_tuple(data: &[FieldElement]) -> Result { for i in 0..children_len { let start = i + offset; - let len: u32 = data[start].try_into()?; + let len: u32 = data[start].to_u32().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: data[start], + })?; let slice_start = start + 1; let slice_end = slice_start + len as usize; children.push(parse_ty(&data[slice_start..slice_end])?); @@ -250,7 +284,7 @@ fn parse_tuple(data: &[FieldElement]) -> Result { Ok(Ty::Tuple(children)) } -fn parse_array(data: &[FieldElement]) -> Result { +fn parse_array(data: &[Felt]) -> Result { if data.is_empty() || data.len() != 2 { return Err(ParseError::invalid_schema_with_msg( "The function parse_array expects exactly one felt to know the item type, empty input \ @@ -273,14 +307,14 @@ fn parse_byte_array() -> Result { #[cfg(test)] mod tests { - use starknet::core::types::FieldElement; + use starknet::core::types::Felt; use starknet::core::utils::cairo_short_string_to_felt; use super::*; #[test] fn parse_simple_with_invalid_value() { - let data = [FieldElement::default()]; + let data = [Felt::default()]; assert!(parse_simple(&data).is_err()); } @@ -297,17 +331,14 @@ mod tests { assert!(parse_struct(&data).is_err()); // Only with attr len. - let data = [cairo_short_string_to_felt("bad_struct").unwrap(), FieldElement::default()]; + let data = [cairo_short_string_to_felt("bad_struct").unwrap(), Felt::default()]; assert!(parse_struct(&data).is_err()); } #[test] fn parse_struct_empty() { - let data = [ - cairo_short_string_to_felt("empty_struct").unwrap(), - FieldElement::default(), - FieldElement::default(), - ]; + let data = + [cairo_short_string_to_felt("empty_struct").unwrap(), Felt::default(), Felt::default()]; assert_eq!( parse_struct(&data).unwrap(), @@ -317,7 +348,7 @@ mod tests { #[test] fn parse_array_with_invalid_value() { - let data = [FieldElement::default()]; + let data = [Felt::default()]; assert!(parse_array(&data).is_err()); } } diff --git a/crates/dojo-types/src/primitive.rs b/crates/dojo-types/src/primitive.rs index b3cd87477d..6192c107e3 100644 --- a/crates/dojo-types/src/primitive.rs +++ b/crates/dojo-types/src/primitive.rs @@ -1,6 +1,9 @@ +use std::any::type_name; + use crypto_bigint::{Encoding, U256}; +use num_traits::ToPrimitive; use serde::{Deserialize, Serialize}; -use starknet::core::types::{FieldElement, ValueOutOfRangeError}; +use starknet::core::types::Felt; use strum::IntoEnumIterator; use strum_macros::{AsRefStr, Display, EnumIter, EnumString}; @@ -30,11 +33,11 @@ pub enum Primitive { U256(Option), USize(Option), Bool(Option), - Felt252(Option), + Felt252(Option), #[strum(serialize = "ClassHash")] - ClassHash(Option), + ClassHash(Option), #[strum(serialize = "ContractAddress")] - ContractAddress(Option), + ContractAddress(Option), } #[derive(Debug, thiserror::Error)] @@ -47,8 +50,8 @@ pub enum PrimitiveError { UnsupportedType, #[error("Set value type mismatch")] TypeMismatch, - #[error(transparent)] - ValueOutOfRange(#[from] ValueOutOfRangeError), + #[error("Felt value ({value:#x}) out of range for {r#type}")] + ValueOutOfRange { value: Felt, r#type: &'static str }, #[error(transparent)] CairoSerde(#[from] cainome::cairo_serde::Error), #[error(transparent)] @@ -101,9 +104,9 @@ impl Primitive { as_primitive!(as_u256, U256, U256); as_primitive!(as_bool, Bool, bool); as_primitive!(as_usize, USize, u32); - as_primitive!(as_felt252, Felt252, FieldElement); - as_primitive!(as_class_hash, ClassHash, FieldElement); - as_primitive!(as_contract_address, ContractAddress, FieldElement); + as_primitive!(as_felt252, Felt252, Felt); + as_primitive!(as_class_hash, ClassHash, Felt); + as_primitive!(as_contract_address, ContractAddress, Felt); set_primitive!(set_u8, U8, u8); set_primitive!(set_u16, U16, u16); @@ -113,9 +116,9 @@ impl Primitive { set_primitive!(set_u256, U256, U256); set_primitive!(set_bool, Bool, bool); set_primitive!(set_usize, USize, u32); - set_primitive!(set_felt252, Felt252, FieldElement); - set_primitive!(set_class_hash, ClassHash, FieldElement); - set_primitive!(set_contract_address, ContractAddress, FieldElement); + set_primitive!(set_felt252, Felt252, Felt); + set_primitive!(set_class_hash, ClassHash, Felt); + set_primitive!(set_contract_address, ContractAddress, Felt); pub fn to_numeric(&self) -> usize { match self { @@ -189,41 +192,65 @@ impl Primitive { } } - pub fn deserialize(&mut self, felts: &mut Vec) -> Result<(), PrimitiveError> { + pub fn deserialize(&mut self, felts: &mut Vec) -> Result<(), PrimitiveError> { if felts.is_empty() { return Err(PrimitiveError::MissingFieldElement); } match self { Primitive::U8(ref mut value) => { - *value = Some(felts.remove(0).try_into().map_err(PrimitiveError::ValueOutOfRange)?); - Ok(()) + let felt = felts.remove(0); + *value = Some(felt.to_u8().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: felt, + })?); } + Primitive::U16(ref mut value) => { - *value = Some(felts.remove(0).try_into().map_err(PrimitiveError::ValueOutOfRange)?); - Ok(()) + let felt = felts.remove(0); + *value = Some(felt.to_u16().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: felt, + })?); } + Primitive::U32(ref mut value) => { - *value = Some(felts.remove(0).try_into().map_err(PrimitiveError::ValueOutOfRange)?); - Ok(()) + let felt = felts.remove(0); + *value = Some(felt.to_u32().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: felt, + })?); } + Primitive::U64(ref mut value) => { - *value = Some(felts.remove(0).try_into().map_err(PrimitiveError::ValueOutOfRange)?); - Ok(()) + let felt = felts.remove(0); + *value = Some(felt.to_u64().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: felt, + })?); } + Primitive::USize(ref mut value) => { - *value = Some(felts.remove(0).try_into().map_err(PrimitiveError::ValueOutOfRange)?); - Ok(()) + let felt = felts.remove(0); + *value = Some(felt.to_u32().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: felt, + })?); } + Primitive::Bool(ref mut value) => { let raw = felts.remove(0); - *value = Some(raw == FieldElement::ONE); - Ok(()) + *value = Some(raw == Felt::ONE); } + Primitive::U128(ref mut value) => { - *value = Some(felts.remove(0).try_into().map_err(PrimitiveError::ValueOutOfRange)?); - Ok(()) + let felt = felts.remove(0); + *value = Some(felt.to_u128().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value: felt, + })?); } + Primitive::U256(ref mut value) => { if felts.len() < 2 { return Err(PrimitiveError::NotEnoughFieldElements); @@ -236,45 +263,46 @@ impl Primitive { bytes[16..].copy_from_slice(&value0_bytes[16..]); bytes[..16].copy_from_slice(&value1_bytes[16..]); *value = Some(U256::from_be_bytes(bytes)); - Ok(()) } + Primitive::ContractAddress(ref mut value) => { *value = Some(felts.remove(0)); - Ok(()) } + Primitive::ClassHash(ref mut value) => { *value = Some(felts.remove(0)); - Ok(()) } + Primitive::Felt252(ref mut value) => { *value = Some(felts.remove(0)); - Ok(()) } } + + Ok(()) } - pub fn serialize(&self) -> Result, PrimitiveError> { + pub fn serialize(&self) -> Result, PrimitiveError> { match self { Primitive::U8(value) => value - .map(|v| Ok(vec![FieldElement::from(v)])) + .map(|v| Ok(vec![Felt::from(v)])) .unwrap_or(Err(PrimitiveError::MissingFieldElement)), Primitive::U16(value) => value - .map(|v| Ok(vec![FieldElement::from(v)])) + .map(|v| Ok(vec![Felt::from(v)])) .unwrap_or(Err(PrimitiveError::MissingFieldElement)), Primitive::U32(value) => value - .map(|v| Ok(vec![FieldElement::from(v)])) + .map(|v| Ok(vec![Felt::from(v)])) .unwrap_or(Err(PrimitiveError::MissingFieldElement)), Primitive::U64(value) => value - .map(|v| Ok(vec![FieldElement::from(v)])) + .map(|v| Ok(vec![Felt::from(v)])) .unwrap_or(Err(PrimitiveError::MissingFieldElement)), Primitive::USize(value) => value - .map(|v| Ok(vec![FieldElement::from(v)])) + .map(|v| Ok(vec![Felt::from(v)])) .unwrap_or(Err(PrimitiveError::MissingFieldElement)), Primitive::Bool(value) => value - .map(|v| Ok(vec![if v { FieldElement::ONE } else { FieldElement::ZERO }])) + .map(|v| Ok(vec![if v { Felt::ONE } else { Felt::ZERO }])) .unwrap_or(Err(PrimitiveError::MissingFieldElement)), Primitive::U128(value) => value - .map(|v| Ok(vec![FieldElement::from(v)])) + .map(|v| Ok(vec![Felt::from(v)])) .unwrap_or(Err(PrimitiveError::MissingFieldElement)), Primitive::U256(value) => value .map(|v| { @@ -285,8 +313,8 @@ impl Primitive { let mut value1_array = [0u8; 32]; value0_array[16..].copy_from_slice(value0_slice); value1_array[16..].copy_from_slice(value1_slice); - let value0 = FieldElement::from_bytes_be(&value0_array).unwrap(); - let value1 = FieldElement::from_bytes_be(&value1_array).unwrap(); + let value0 = Felt::from_bytes_be(&value0_array); + let value1 = Felt::from_bytes_be(&value1_array); Ok(vec![value0, value1]) }) .unwrap_or(Err(PrimitiveError::MissingFieldElement)), @@ -308,7 +336,7 @@ mod tests { use std::str::FromStr; use crypto_bigint::U256; - use starknet::core::types::FieldElement; + use starknet::core::types::Felt; use super::Primitive; @@ -327,8 +355,8 @@ mod tests { assert_eq!( serialized, vec![ - FieldElement::from_str("0xccccccccccccccccdddddddddddddddd").unwrap(), - FieldElement::from_str("0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb").unwrap() + Felt::from_str("0xccccccccccccccccdddddddddddddddd").unwrap(), + Felt::from_str("0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb").unwrap() ] ); assert_eq!(deserialized, primitive) @@ -361,13 +389,13 @@ mod tests { primitive.set_bool(Some(true)).unwrap(); assert_eq!(primitive.as_bool(), Some(true)); let mut primitive = Primitive::Felt252(None); - primitive.set_felt252(Some(FieldElement::from(1u128))).unwrap(); - assert_eq!(primitive.as_felt252(), Some(FieldElement::from(1u128))); + primitive.set_felt252(Some(Felt::from(1u128))).unwrap(); + assert_eq!(primitive.as_felt252(), Some(Felt::from(1u128))); let mut primitive = Primitive::ClassHash(None); - primitive.set_class_hash(Some(FieldElement::from(1u128))).unwrap(); - assert_eq!(primitive.as_class_hash(), Some(FieldElement::from(1u128))); + primitive.set_class_hash(Some(Felt::from(1u128))).unwrap(); + assert_eq!(primitive.as_class_hash(), Some(Felt::from(1u128))); let mut primitive = Primitive::ContractAddress(None); - primitive.set_contract_address(Some(FieldElement::from(1u128))).unwrap(); - assert_eq!(primitive.as_contract_address(), Some(FieldElement::from(1u128))); + primitive.set_contract_address(Some(Felt::from(1u128))).unwrap(); + assert_eq!(primitive.as_contract_address(), Some(Felt::from(1u128))); } } diff --git a/crates/dojo-types/src/schema.rs b/crates/dojo-types/src/schema.rs index fa4f2819e7..162ce295c1 100644 --- a/crates/dojo-types/src/schema.rs +++ b/crates/dojo-types/src/schema.rs @@ -1,7 +1,10 @@ +use std::any::type_name; + use cainome::cairo_serde::{ByteArray, CairoSerde}; use itertools::Itertools; +use num_traits::ToPrimitive; use serde::{Deserialize, Serialize}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use strum_macros::AsRefStr; use crate::primitive::{Primitive, PrimitiveError}; @@ -16,7 +19,7 @@ pub struct Member { } impl Member { - pub fn serialize(&self) -> Result, PrimitiveError> { + pub fn serialize(&self) -> Result, PrimitiveError> { self.ty.serialize() } } @@ -27,9 +30,9 @@ pub struct ModelMetadata { pub name: String, pub packed_size: u32, pub unpacked_size: u32, - pub class_hash: FieldElement, - pub contract_address: FieldElement, - pub layout: Vec, + pub class_hash: Felt, + pub contract_address: Felt, + pub layout: Vec, } /// Represents all possible types in Cairo @@ -113,10 +116,10 @@ impl Ty { } } - pub fn serialize(&self) -> Result, PrimitiveError> { + pub fn serialize(&self) -> Result, PrimitiveError> { let mut felts = vec![]; - fn serialize_inner(ty: &Ty, felts: &mut Vec) -> Result<(), PrimitiveError> { + fn serialize_inner(ty: &Ty, felts: &mut Vec) -> Result<(), PrimitiveError> { match ty { Ty::Primitive(c) => { felts.extend(c.serialize()?); @@ -129,7 +132,7 @@ impl Ty { Ty::Enum(e) => { let option = e .option - .map(|v| Ok(vec![FieldElement::from(v)])) + .map(|v| Ok(vec![Felt::from(v)])) .unwrap_or(Err(PrimitiveError::MissingFieldElement))?; felts.extend(option); @@ -165,7 +168,7 @@ impl Ty { Ok(felts) } - pub fn deserialize(&mut self, felts: &mut Vec) -> Result<(), PrimitiveError> { + pub fn deserialize(&mut self, felts: &mut Vec) -> Result<(), PrimitiveError> { match self { Ty::Primitive(c) => { c.deserialize(felts)?; @@ -176,8 +179,11 @@ impl Ty { } } Ty::Enum(e) => { - e.option = - Some(felts.remove(0).try_into().map_err(PrimitiveError::ValueOutOfRange)?); + let value = felts.remove(0); + e.option = Some(value.to_u8().ok_or_else(|| PrimitiveError::ValueOutOfRange { + r#type: type_name::(), + value, + })?); match &e.options[e.option.unwrap() as usize].ty { // Skip deserializing the enum option if it has no type - unit type @@ -193,8 +199,10 @@ impl Ty { } } Ty::Array(items_ty) => { - let arr_len: u32 = - felts.remove(0).try_into().map_err(PrimitiveError::ValueOutOfRange)?; + let value = felts.remove(0); + let arr_len: u32 = value.to_u32().ok_or_else(|| { + PrimitiveError::ValueOutOfRange { r#type: type_name::(), value } + })?; let item_ty = items_ty.pop().unwrap(); for _ in 0..arr_len { diff --git a/crates/dojo-types/src/storage.rs b/crates/dojo-types/src/storage.rs index 037d8a85fa..8ae4c2820a 100644 --- a/crates/dojo-types/src/storage.rs +++ b/crates/dojo-types/src/storage.rs @@ -1,7 +1,7 @@ -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; #[derive(Clone, Debug)] pub struct Query { pub address_domain: u32, - pub keys: Vec, + pub keys: Vec, } diff --git a/crates/dojo-world/Cargo.toml b/crates/dojo-world/Cargo.toml index 8504077caa..3c440ef24d 100644 --- a/crates/dojo-world/Cargo.toml +++ b/crates/dojo-world/Cargo.toml @@ -16,6 +16,7 @@ cairo-lang-starknet.workspace = true camino.workspace = true convert_case.workspace = true futures.workspace = true +num-traits = { workspace = true, optional = true } serde.workspace = true serde_json.workspace = true serde_with.workspace = true @@ -46,7 +47,7 @@ tempfile.workspace = true tokio.workspace = true [features] -contracts = [ "dep:dojo-types", "dep:http" ] +contracts = [ "dep:dojo-types", "dep:http", "dep:num-traits" ] manifest = [ "contracts", "dep:dojo-types", "dep:url" ] metadata = [ "dep:ipfs-api-backend-hyper", "dep:scarb", "dep:url" ] migration = [ "dep:tokio" ] diff --git a/crates/dojo-world/src/contracts/cairo_utils.rs b/crates/dojo-world/src/contracts/cairo_utils.rs index 3a67953299..d1afd89750 100644 --- a/crates/dojo-world/src/contracts/cairo_utils.rs +++ b/crates/dojo-world/src/contracts/cairo_utils.rs @@ -1,9 +1,9 @@ use anyhow::{anyhow, Result}; use http::uri::Uri; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::core::utils::cairo_short_string_to_felt; -pub fn str_to_felt(string: &str) -> Result { +pub fn str_to_felt(string: &str) -> Result { cairo_short_string_to_felt(string).map_err(|e| { anyhow!(format!("Failed to convert string `{}` to cairo short string: {}", string, e)) }) diff --git a/crates/dojo-world/src/contracts/model.rs b/crates/dojo-world/src/contracts/model.rs index 13bb96ea14..902bf4c558 100644 --- a/crates/dojo-world/src/contracts/model.rs +++ b/crates/dojo-world/src/contracts/model.rs @@ -6,7 +6,7 @@ use cainome::cairo_serde::{CairoSerde as _, ContractAddress, Error as CainomeErr use dojo_types::packing::{PackingError, ParseError}; use dojo_types::primitive::{Primitive, PrimitiveError}; use dojo_types::schema::{Enum, EnumOption, Member, Struct, Ty}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::core::utils::{ cairo_short_string_to_felt, get_selector_from_name, parse_cairo_short_string, CairoShortStringToFeltError, NonAsciiNameError, ParseCairoShortStringError, @@ -55,9 +55,9 @@ pub trait ModelReader { // TODO: kept for compatibility but should be removed // because it returns the model name hash and not the model name itself. fn name(&self) -> String; - fn selector(&self) -> FieldElement; - fn class_hash(&self) -> FieldElement; - fn contract_address(&self) -> FieldElement; + fn selector(&self) -> Felt; + fn class_hash(&self) -> Felt; + fn contract_address(&self) -> Felt; async fn schema(&self) -> Result; async fn packed_size(&self) -> Result; async fn unpacked_size(&self) -> Result; @@ -66,11 +66,11 @@ pub trait ModelReader { pub struct ModelRPCReader<'a, P: Provider + Sync + Send> { /// The name of the model - name: FieldElement, + name: Felt, /// The class hash of the model - class_hash: FieldElement, + class_hash: Felt, /// The contract address of the model - contract_address: FieldElement, + contract_address: Felt, /// Contract reader of the World that the model is registered to. world_reader: &'a WorldContractReader

, /// Contract reader of the model. @@ -92,7 +92,7 @@ where // World Cairo contract won't raise an error in case of unknown/unregistered // model so raise an error here in case of zero address. - if contract_address == ContractAddress(FieldElement::ZERO) { + if contract_address == ContractAddress(Felt::ZERO) { return Err(ModelError::ModelNotFound); } @@ -107,10 +107,7 @@ where }) } - pub async fn entity_storage( - &self, - keys: &[FieldElement], - ) -> Result, ModelError> { + pub async fn entity_storage(&self, keys: &[Felt]) -> Result, ModelError> { // As the dojo::database::introspect::Layout type has been pasted // in both `model` and `world` ABI by abigen, the compiler sees both types // as different even if they are strictly identical. @@ -122,7 +119,7 @@ where Ok(self.world_reader.entity(&self.selector(), &keys.to_vec(), &layout).call().await?) } - pub async fn entity(&self, keys: &[FieldElement]) -> Result { + pub async fn entity(&self, keys: &[Felt]) -> Result { let mut schema = self.schema().await?; let values = self.entity_storage(keys).await?; @@ -144,15 +141,15 @@ where self.name.to_string() } - fn selector(&self) -> FieldElement { + fn selector(&self) -> Felt { self.name } - fn class_hash(&self) -> FieldElement { + fn class_hash(&self) -> Felt { self.class_hash } - fn contract_address(&self) -> FieldElement { + fn contract_address(&self) -> Felt { self.contract_address } diff --git a/crates/dojo-world/src/contracts/world_test.rs b/crates/dojo-world/src/contracts/world_test.rs index 5680d52c45..91ee527423 100644 --- a/crates/dojo-world/src/contracts/world_test.rs +++ b/crates/dojo-world/src/contracts/world_test.rs @@ -4,7 +4,7 @@ use camino::Utf8PathBuf; use dojo_test_utils::compiler; use katana_runner::KatanaRunner; use starknet::accounts::{Account, ConnectedAccount}; -use starknet::core::types::{BlockId, BlockTag, FieldElement}; +use starknet::core::types::{BlockId, BlockTag, Felt}; use super::{WorldContract, WorldContractReader}; use crate::manifest::{BaseManifest, OverlayManifest, BASE_DIR, MANIFESTS_DIR, OVERLAYS_DIR}; @@ -49,7 +49,7 @@ pub async fn deploy_world( manifest_dir: &Utf8PathBuf, target_dir: &Utf8PathBuf, skip_migration: Option>, -) -> FieldElement { +) -> Felt { // Dev profile is used by default for testing: let profile_name = "dev"; @@ -74,13 +74,8 @@ pub async fn deploy_world( let account = sequencer.account(0); - let mut strategy = prepare_for_migration( - None, - FieldElement::from_hex_be("0x12345").unwrap(), - target_dir, - world, - ) - .unwrap(); + let mut strategy = + prepare_for_migration(None, Felt::from_hex("0x12345").unwrap(), target_dir, world).unwrap(); strategy.resolve_variable(strategy.world_address().unwrap()).unwrap(); let base_class_hash = @@ -118,7 +113,7 @@ pub async fn deploy_world( .map(|o| world.register_model_getcall(&o.class_hash.into())) .collect::>(); - let _ = account.execute(calls).send().await.unwrap(); + let _ = account.execute_v1(calls).send().await.unwrap(); // wait for the tx to be mined tokio::time::sleep(Duration::from_millis(250)).await; diff --git a/crates/dojo-world/src/manifest/manifest_test.rs b/crates/dojo-world/src/manifest/manifest_test.rs index b4894c453c..67b541796f 100644 --- a/crates/dojo-world/src/manifest/manifest_test.rs +++ b/crates/dojo-world/src/manifest/manifest_test.rs @@ -9,7 +9,7 @@ use serde_json::json; use smol_str::SmolStr; use starknet::accounts::ConnectedAccount; use starknet::core::types::contract::AbiEntry; -use starknet::core::types::{EmittedEvent, FieldElement}; +use starknet::core::types::{EmittedEvent, Felt}; use starknet::macros::{felt, selector}; use starknet::providers::jsonrpc::{JsonRpcClient, JsonRpcMethod}; @@ -41,7 +41,7 @@ async fn manifest_from_remote_throw_error_on_not_deployed() { ); let rpc = JsonRpcClient::new(mock_transport); - let err = DeploymentManifest::load_from_remote(rpc, FieldElement::ONE).await.unwrap_err(); + let err = DeploymentManifest::load_from_remote(rpc, Felt::ONE).await.unwrap_err(); match err { AbstractManifestError::RemoteWorldNotFound => { diff --git a/crates/dojo-world/src/manifest/mod.rs b/crates/dojo-world/src/manifest/mod.rs index 2ce8178ea3..1aa721bd6c 100644 --- a/crates/dojo-world/src/manifest/mod.rs +++ b/crates/dojo-world/src/manifest/mod.rs @@ -7,7 +7,7 @@ use camino::Utf8PathBuf; use serde::de::DeserializeOwned; use smol_str::SmolStr; use starknet::core::types::{ - BlockId, BlockTag, EmittedEvent, EventFilter, FieldElement, FunctionCall, StarknetError, + BlockId, BlockTag, EmittedEvent, EventFilter, Felt, FunctionCall, StarknetError, }; use starknet::core::utils::{ parse_cairo_short_string, starknet_keccak, CairoShortStringToFeltError, @@ -259,7 +259,7 @@ impl DeploymentManifest { self.contracts.iter_mut().for_each(|contract| { let previous_contract = previous.contracts.iter().find(|c| c.name == contract.name); if let Some(previous_contract) = previous_contract { - if previous_contract.inner.base_class_hash != FieldElement::ZERO { + if previous_contract.inner.base_class_hash != Felt::ZERO { contract.inner.base_class_hash = previous_contract.inner.base_class_hash; } } @@ -310,7 +310,7 @@ impl DeploymentManifest { /// * `world_address` - The address of the remote World contract. pub async fn load_from_remote

( provider: P, - world_address: FieldElement, + world_address: Felt, ) -> Result where P: Provider + Send + Sync, @@ -370,7 +370,7 @@ impl DeploymentManifest { // impl RemoteLoadable

for DeploymentManifest {} async fn get_remote_models_and_contracts

( - world: FieldElement, + world: Felt, provider: P, ) -> Result<(Vec>, Vec>), AbstractManifestError> where @@ -441,8 +441,8 @@ where async fn get_events( provider: P, - world: FieldElement, - keys: Vec>, + world: Felt, + keys: Vec>, ) -> Result, ProviderError> { const DEFAULT_CHUNK_SIZE: u64 = 100; @@ -471,11 +471,9 @@ fn parse_contracts_events( deployed: Vec, upgraded: Vec, ) -> Vec> { - fn retain_only_latest_upgrade_events( - events: Vec, - ) -> HashMap { + fn retain_only_latest_upgrade_events(events: Vec) -> HashMap { // addr -> (block_num, class_hash) - let mut upgrades: HashMap = HashMap::new(); + let mut upgrades: HashMap = HashMap::new(); events.into_iter().for_each(|event| { let mut data = event.data.into_iter(); @@ -531,7 +529,7 @@ fn parse_contracts_events( } fn parse_models_events(events: Vec) -> Vec> { - let mut models: HashMap = HashMap::with_capacity(events.len()); + let mut models: HashMap = HashMap::with_capacity(events.len()); for e in events { let model_event = match e.try_into() { @@ -650,15 +648,15 @@ impl ManifestMethods for DojoContract { self.abi = abi; } - fn class_hash(&self) -> &FieldElement { + fn class_hash(&self) -> &Felt { self.class_hash.as_ref() } - fn set_class_hash(&mut self, class_hash: FieldElement) { + fn set_class_hash(&mut self, class_hash: Felt) { self.class_hash = class_hash; } - fn original_class_hash(&self) -> &FieldElement { + fn original_class_hash(&self) -> &Felt { self.original_class_hash.as_ref() } @@ -689,15 +687,15 @@ impl ManifestMethods for DojoModel { self.abi = abi; } - fn class_hash(&self) -> &FieldElement { + fn class_hash(&self) -> &Felt { self.class_hash.as_ref() } - fn set_class_hash(&mut self, class_hash: FieldElement) { + fn set_class_hash(&mut self, class_hash: Felt) { self.class_hash = class_hash; } - fn original_class_hash(&self) -> &FieldElement { + fn original_class_hash(&self) -> &Felt { self.original_class_hash.as_ref() } @@ -719,15 +717,15 @@ impl ManifestMethods for WorldContract { self.abi = abi; } - fn class_hash(&self) -> &FieldElement { + fn class_hash(&self) -> &Felt { self.class_hash.as_ref() } - fn set_class_hash(&mut self, class_hash: FieldElement) { + fn set_class_hash(&mut self, class_hash: Felt) { self.class_hash = class_hash; } - fn original_class_hash(&self) -> &FieldElement { + fn original_class_hash(&self) -> &Felt { self.original_class_hash.as_ref() } @@ -749,15 +747,15 @@ impl ManifestMethods for Class { self.abi = abi; } - fn class_hash(&self) -> &FieldElement { + fn class_hash(&self) -> &Felt { self.class_hash.as_ref() } - fn set_class_hash(&mut self, class_hash: FieldElement) { + fn set_class_hash(&mut self, class_hash: Felt) { self.class_hash = class_hash; } - fn original_class_hash(&self) -> &FieldElement { + fn original_class_hash(&self) -> &Felt { self.original_class_hash.as_ref() } diff --git a/crates/dojo-world/src/manifest/types.rs b/crates/dojo-world/src/manifest/types.rs index 5eb3e67d0c..b576c6e557 100644 --- a/crates/dojo-world/src/manifest/types.rs +++ b/crates/dojo-world/src/manifest/types.rs @@ -6,7 +6,7 @@ use serde_with::serde_as; use smol_str::SmolStr; use starknet::core::serde::unsigned_field_element::UfeHex; use starknet::core::types::contract::AbiEntry; -use starknet_crypto::FieldElement; +use starknet::core::types::Felt; use crate::manifest::AbstractManifestError; @@ -61,9 +61,9 @@ pub trait ManifestMethods { type OverlayType; fn abi(&self) -> Option<&AbiFormat>; fn set_abi(&mut self, abi: Option); - fn class_hash(&self) -> &FieldElement; - fn set_class_hash(&mut self, class_hash: FieldElement); - fn original_class_hash(&self) -> &FieldElement; + fn class_hash(&self) -> &Felt; + fn set_class_hash(&mut self, class_hash: Felt); + fn original_class_hash(&self) -> &Felt; /// This method is called when during compilation base manifest file already exists. /// Manifest generated during compilation won't contains properties manually updated by users @@ -86,14 +86,14 @@ where #[serde(tag = "kind")] pub struct DojoContract { #[serde_as(as = "Option")] - pub address: Option, + pub address: Option, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "UfeHex")] - pub original_class_hash: FieldElement, + pub original_class_hash: Felt, // base class hash used to deploy the contract #[serde_as(as = "UfeHex")] - pub base_class_hash: FieldElement, + pub base_class_hash: Felt, pub abi: Option, #[serde(default)] pub reads: Vec, @@ -113,9 +113,9 @@ pub struct DojoContract { pub struct DojoModel { pub members: Vec, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "UfeHex")] - pub original_class_hash: FieldElement, + pub original_class_hash: Felt, pub abi: Option, } @@ -125,14 +125,14 @@ pub struct DojoModel { #[serde(tag = "kind")] pub struct WorldContract { #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "UfeHex")] - pub original_class_hash: FieldElement, + pub original_class_hash: Felt, pub abi: Option, #[serde_as(as = "Option")] - pub address: Option, + pub address: Option, #[serde_as(as = "Option")] - pub transaction_hash: Option, + pub transaction_hash: Option, pub block_number: Option, pub seed: String, pub metadata: Option, @@ -144,9 +144,9 @@ pub struct WorldContract { #[serde(tag = "kind")] pub struct Class { #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "UfeHex")] - pub original_class_hash: FieldElement, + pub original_class_hash: Felt, pub abi: Option, } @@ -155,7 +155,7 @@ pub struct Class { #[cfg_attr(test, derive(PartialEq))] pub struct OverlayDojoContract { pub name: SmolStr, - pub original_class_hash: Option, + pub original_class_hash: Option, pub reads: Option>, pub writes: Option>, pub init_calldata: Option>, @@ -166,7 +166,7 @@ pub struct OverlayDojoContract { #[cfg_attr(test, derive(PartialEq))] pub struct OverlayDojoModel { pub name: SmolStr, - pub original_class_hash: Option, + pub original_class_hash: Option, } #[serde_as] @@ -174,7 +174,7 @@ pub struct OverlayDojoModel { #[cfg_attr(test, derive(PartialEq))] pub struct OverlayContract { pub name: SmolStr, - pub original_class_hash: Option, + pub original_class_hash: Option, } #[serde_as] @@ -182,7 +182,7 @@ pub struct OverlayContract { #[cfg_attr(test, derive(PartialEq))] pub struct OverlayClass { pub name: SmolStr, - pub original_class_hash: Option, + pub original_class_hash: Option, } // Types used by manifest diff --git a/crates/dojo-world/src/migration/class.rs b/crates/dojo-world/src/migration/class.rs index e5b29f16d9..a342e6eb01 100644 --- a/crates/dojo-world/src/migration/class.rs +++ b/crates/dojo-world/src/migration/class.rs @@ -2,7 +2,7 @@ use std::fmt::Display; use std::path::PathBuf; use async_trait::async_trait; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use super::{Declarable, MigrationType, StateDiff}; @@ -10,9 +10,9 @@ use super::{Declarable, MigrationType, StateDiff}; #[derive(Debug, Default, Clone)] pub struct ClassDiff { pub name: String, - pub local_class_hash: FieldElement, - pub original_class_hash: FieldElement, - pub remote_class_hash: Option, + pub local_class_hash: Felt, + pub original_class_hash: Felt, + pub remote_class_hash: Option, } impl StateDiff for ClassDiff { diff --git a/crates/dojo-world/src/migration/contract.rs b/crates/dojo-world/src/migration/contract.rs index 59e6c929f9..6a0bb9ce35 100644 --- a/crates/dojo-world/src/migration/contract.rs +++ b/crates/dojo-world/src/migration/contract.rs @@ -2,7 +2,7 @@ use std::fmt::Display; use std::path::PathBuf; use async_trait::async_trait; -use starknet::core::types::{DeclareTransactionResult, FieldElement}; +use starknet::core::types::{DeclareTransactionResult, Felt}; use super::{Declarable, Deployable, MigrationType, StateDiff, Upgradable}; @@ -12,10 +12,10 @@ pub type DeclareOutput = DeclareTransactionResult; #[derive(Debug, Default, Clone)] pub struct ContractDiff { pub name: String, - pub local_class_hash: FieldElement, - pub original_class_hash: FieldElement, - pub base_class_hash: FieldElement, - pub remote_class_hash: Option, + pub local_class_hash: Felt, + pub original_class_hash: Felt, + pub base_class_hash: Felt, + pub remote_class_hash: Option, pub init_calldata: Vec, } @@ -47,10 +47,10 @@ impl Display for ContractDiff { // Represents a contract that needs to be migrated to the remote state #[derive(Debug, Default, Clone)] pub struct ContractMigration { - pub salt: FieldElement, + pub salt: Felt, pub diff: ContractDiff, pub artifact_path: PathBuf, - pub contract_address: FieldElement, + pub contract_address: Felt, } impl ContractMigration { @@ -75,7 +75,7 @@ impl Declarable for ContractMigration { #[async_trait] impl Deployable for ContractMigration { - fn salt(&self) -> FieldElement { + fn salt(&self) -> Felt { self.salt } } diff --git a/crates/dojo-world/src/migration/mod.rs b/crates/dojo-world/src/migration/mod.rs index 203b5d91de..e67dbafc32 100644 --- a/crates/dojo-world/src/migration/mod.rs +++ b/crates/dojo-world/src/migration/mod.rs @@ -10,8 +10,8 @@ use cairo_lang_starknet_classes::contract_class::ContractClass; use starknet::accounts::{Account, AccountError, Call, ConnectedAccount}; use starknet::core::types::contract::{CompiledClass, SierraClass}; use starknet::core::types::{ - BlockId, BlockTag, DeclareTransactionResult, FieldElement, FlattenedSierraClass, - InvokeTransactionResult, MaybePendingTransactionReceipt, StarknetError, TransactionReceipt, + BlockId, BlockTag, DeclareTransactionResult, Felt, FlattenedSierraClass, + InvokeTransactionResult, ReceiptBlock, StarknetError, TransactionReceiptWithBlockInfo, }; use starknet::core::utils::{get_contract_address, CairoShortStringToFeltError}; use starknet::macros::{felt, selector}; @@ -29,27 +29,27 @@ pub type DeclareOutput = DeclareTransactionResult; #[derive(Clone, Debug)] pub struct DeployOutput { - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub block_number: Option, - pub contract_address: FieldElement, + pub contract_address: Felt, pub declare: Option, // base class hash at time of deployment - pub base_class_hash: FieldElement, + pub base_class_hash: Felt, pub was_upgraded: bool, pub name: Option, } #[derive(Clone, Debug)] pub struct UpgradeOutput { - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub block_number: Option, - pub contract_address: FieldElement, + pub contract_address: Felt, pub declare: Option, } #[derive(Debug)] pub struct RegisterOutput { - pub transaction_hash: FieldElement, + pub transaction_hash: Felt, pub declare_output: Vec, pub registered_model_names: Vec, } @@ -61,7 +61,7 @@ pub enum MigrationError { #[error("Class already declared.")] ClassAlreadyDeclared, #[error("Contract already deployed.")] - ContractAlreadyDeployed(FieldElement), + ContractAlreadyDeployed(Felt), #[error(transparent)] Migrator(#[from] AccountError), #[error(transparent)] @@ -100,7 +100,7 @@ pub struct TxnConfig { pub fee_estimate_multiplier: Option, pub wait: bool, pub receipt: bool, - pub max_fee_raw: Option, + pub max_fee_raw: Option, } #[derive(Debug, Copy, Clone)] @@ -108,7 +108,7 @@ pub enum TxnAction { Send { wait: bool, receipt: bool, - max_fee_raw: Option, + max_fee_raw: Option, /// The multiplier for how much the actual transaction max fee should be relative to the /// estimated fee. If `None` is provided, the multiplier is set to `1.1`. fee_estimate_multiplier: Option, @@ -149,7 +149,7 @@ pub trait Declarable { } let DeclareTransactionResult { transaction_hash, class_hash } = account - .declare(Arc::new(flattened_class), casm_class_hash) + .declare_v2(Arc::new(flattened_class), casm_class_hash) .send_with_cfg(txn_config) .await .map_err(MigrationError::Migrator)?; @@ -169,9 +169,9 @@ pub trait Declarable { pub trait Deployable: Declarable + Sync { async fn deploy_dojo_contract( &self, - world_address: FieldElement, - class_hash: FieldElement, - base_class_hash: FieldElement, + world_address: Felt, + class_hash: Felt, + base_class_hash: Felt, account: A, txn_config: &TxnConfig, calldata: &[String], @@ -207,14 +207,13 @@ pub trait Deployable: Declarable + Sync { } Err(ProviderError::StarknetError(StarknetError::ContractNotFound)) => { - let init_calldata: Vec = calldata + let init_calldata: Vec = calldata .iter() - .map(|s| FieldElement::from_str(s)) + .map(|s| Felt::from_str(s)) .collect::, _>>() .map_err(|_| MigrationError::BadInitCalldata)?; - let mut calldata = - vec![self.salt(), class_hash, FieldElement::from(calldata.len())]; + let mut calldata = vec![self.salt(), class_hash, Felt::from(calldata.len())]; calldata.extend(init_calldata); Call { calldata, selector: selector!("deploy_contract"), to: world_address } } @@ -227,7 +226,7 @@ pub trait Deployable: Declarable + Sync { }; let InvokeTransactionResult { transaction_hash } = account - .execute(vec![call]) + .execute_v1(vec![call]) .send_with_cfg(txn_config) .await .map_err(MigrationError::Migrator)?; @@ -248,8 +247,8 @@ pub trait Deployable: Declarable + Sync { async fn deploy( &self, - class_hash: FieldElement, - constructor_calldata: Vec, + class_hash: Felt, + constructor_calldata: Vec, account: A, txn_config: &TxnConfig, ) -> Result::SignError>> @@ -265,21 +264,17 @@ pub trait Deployable: Declarable + Sync { let calldata = [ vec![ - class_hash, // class hash - self.salt(), // salt - FieldElement::ZERO, // unique - FieldElement::from(constructor_calldata.len()), // constructor calldata len + class_hash, // class hash + self.salt(), // salt + Felt::ZERO, // unique + Felt::from(constructor_calldata.len()), // constructor calldata len ], constructor_calldata.clone(), ] .concat(); - let contract_address = get_contract_address( - self.salt(), - class_hash, - &constructor_calldata, - FieldElement::ZERO, - ); + let contract_address = + get_contract_address(self.salt(), class_hash, &constructor_calldata, Felt::ZERO); match account .provider() @@ -291,7 +286,7 @@ pub trait Deployable: Declarable + Sync { Err(e) => return Err(MigrationError::Provider(e)), } - let txn = account.execute(vec![Call { + let txn = account.execute_v1(vec![Call { calldata, // devnet UDC address selector: selector!("deployContract"), @@ -309,13 +304,13 @@ pub trait Deployable: Declarable + Sync { block_number, contract_address, declare, - base_class_hash: FieldElement::default(), + base_class_hash: Felt::default(), was_upgraded: false, name: None, }) } - fn salt(&self) -> FieldElement; + fn salt(&self) -> Felt; } #[cfg_attr(not(target_arch = "wasm32"), async_trait)] @@ -323,9 +318,9 @@ pub trait Deployable: Declarable + Sync { pub trait Upgradable: Deployable + Declarable + Sync { async fn upgrade_world( &self, - class_hash: FieldElement, - original_class_hash: FieldElement, - original_base_class_hash: FieldElement, + class_hash: Felt, + original_class_hash: Felt, + original_base_class_hash: Felt, account: A, txn_config: &TxnConfig, ) -> Result::SignError>> @@ -344,7 +339,7 @@ pub trait Upgradable: Deployable + Declarable + Sync { self.salt(), original_class_hash, &original_constructor_calldata, - FieldElement::ZERO, + Felt::ZERO, ); match account @@ -359,7 +354,11 @@ pub trait Upgradable: Deployable + Declarable + Sync { let calldata = vec![class_hash]; let InvokeTransactionResult { transaction_hash } = account - .execute(vec![Call { calldata, selector: selector!("upgrade"), to: contract_address }]) + .execute_v1(vec![Call { + calldata, + selector: selector!("upgrade"), + to: contract_address, + }]) .send_with_cfg(txn_config) .await .map_err(MigrationError::Migrator)?; @@ -373,7 +372,7 @@ pub trait Upgradable: Deployable + Declarable + Sync { fn prepare_contract_declaration_params( artifact_path: &PathBuf, -) -> Result<(FlattenedSierraClass, FieldElement)> { +) -> Result<(FlattenedSierraClass, Felt)> { let flattened_class = read_class(artifact_path)? .flatten() .map_err(|e| anyhow!("error flattening the contract class: {e}"))?; @@ -389,7 +388,7 @@ pub fn read_class(artifact_path: &PathBuf) -> Result { Ok(contract_artifact) } -fn get_compiled_class_hash(artifact_path: &PathBuf) -> Result { +fn get_compiled_class_hash(artifact_path: &PathBuf) -> Result { let file = File::open(artifact_path)?; let casm_contract_class: ContractClass = serde_json::from_reader(file)?; let casm_contract = @@ -399,13 +398,9 @@ fn get_compiled_class_hash(artifact_path: &PathBuf) -> Result { Ok(compiled_class.class_hash()?) } -fn get_block_number_from_receipt(receipt: MaybePendingTransactionReceipt) -> Option { - match receipt { - MaybePendingTransactionReceipt::Receipt(receipt) => match receipt { - TransactionReceipt::Deploy(r) => Some(r.block_number), - TransactionReceipt::Invoke(r) => Some(r.block_number), - _ => None, - }, - MaybePendingTransactionReceipt::PendingReceipt(_receipt) => None, +fn get_block_number_from_receipt(receipt: TransactionReceiptWithBlockInfo) -> Option { + match receipt.block { + ReceiptBlock::Pending => None, + ReceiptBlock::Block { block_number, .. } => Some(block_number), } } diff --git a/crates/dojo-world/src/migration/strategy.rs b/crates/dojo-world/src/migration/strategy.rs index 258b34ea68..f0e79d8867 100644 --- a/crates/dojo-world/src/migration/strategy.rs +++ b/crates/dojo-world/src/migration/strategy.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use anyhow::{anyhow, bail, Context, Result}; use camino::Utf8PathBuf; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::core::utils::{cairo_short_string_to_felt, get_contract_address}; use starknet_crypto::{poseidon_hash_many, poseidon_hash_single}; @@ -20,7 +20,7 @@ pub enum MigrationMetadata { #[derive(Debug, Clone)] pub struct MigrationStrategy { - pub world_address: Option, + pub world_address: Option, pub world: Option, pub base: Option, pub contracts: Vec, @@ -35,7 +35,7 @@ pub struct MigrationItemsInfo { } impl MigrationStrategy { - pub fn world_address(&self) -> Result { + pub fn world_address(&self) -> Result { match &self.world { Some(c) => Ok(c.contract_address), None => self.world_address.ok_or(anyhow!("World address not found")), @@ -66,7 +66,7 @@ impl MigrationStrategy { MigrationItemsInfo { new, update } } - pub fn resolve_variable(&mut self, world_address: FieldElement) -> Result<()> { + pub fn resolve_variable(&mut self, world_address: Felt) -> Result<()> { for contract in self.contracts.iter_mut() { for field in contract.diff.init_calldata.iter_mut() { if let Some(dependency) = field.strip_prefix("$contract_address:") { @@ -101,8 +101,8 @@ impl MigrationStrategy { /// construct migration strategy /// evaluate which contracts/classes need to be declared/deployed pub fn prepare_for_migration( - world_address: Option, - seed: FieldElement, + world_address: Option, + seed: Felt, target_dir: &Utf8PathBuf, diff: WorldDiff, ) -> Result { @@ -152,7 +152,7 @@ pub fn prepare_for_migration( salt, diff.world.original_class_hash, &[base.as_ref().unwrap().diff.original_class_hash], - FieldElement::ZERO, + Felt::ZERO, ); if let Some(world_address) = world_address { @@ -264,7 +264,7 @@ fn find_artifact_path<'a>( .with_context(|| anyhow!("missing contract artifact for `{}` contract", contract_name)) } -pub fn generate_salt(value: &str) -> FieldElement { +pub fn generate_salt(value: &str) -> Felt { poseidon_hash_many( &value .chars() diff --git a/crates/dojo-world/src/migration/world.rs b/crates/dojo-world/src/migration/world.rs index 27adf6c69a..a19a7084a4 100644 --- a/crates/dojo-world/src/migration/world.rs +++ b/crates/dojo-world/src/migration/world.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::{bail, Result}; use convert_case::{Case, Casing}; -use starknet_crypto::FieldElement; +use starknet::core::types::Felt; use topological_sort::TopologicalSort; use super::class::ClassDiff; @@ -60,7 +60,7 @@ impl WorldDiff { .map(|contract| { let base_class_hash = { let class_hash = contract.inner.base_class_hash; - if class_hash != FieldElement::ZERO { + if class_hash != Felt::ZERO { class_hash } else { *local.base.inner.class_hash() @@ -129,7 +129,7 @@ impl WorldDiff { ts.add_dependency(dependency, curr_name); } else { // verify its a field element - match FieldElement::from_str(field) { + match Felt::from_str(field) { Ok(_) => continue, Err(e) => bail!(format!( "Expected init_calldata element to be a special variable (i.e. \ diff --git a/crates/dojo-world/src/utils.rs b/crates/dojo-world/src/utils.rs index 25e478bce0..16c7d59a64 100644 --- a/crates/dojo-world/src/utils.rs +++ b/crates/dojo-world/src/utils.rs @@ -5,13 +5,13 @@ use std::time::Duration; use futures::FutureExt; use starknet::accounts::{ - AccountDeployment, AccountError, AccountFactory, AccountFactoryError, ConnectedAccount, - Declaration, Execution, + AccountDeploymentV1, AccountError, AccountFactory, AccountFactoryError, ConnectedAccount, + DeclarationV2, ExecutionV1, }; use starknet::core::types::{ - DeclareTransactionResult, DeployAccountTransactionResult, ExecutionResult, FieldElement, - InvokeTransactionResult, MaybePendingTransactionReceipt, PendingTransactionReceipt, - StarknetError, TransactionFinalityStatus, TransactionReceipt, TransactionStatus, + DeclareTransactionResult, DeployAccountTransactionResult, ExecutionResult, Felt, + InvokeTransactionResult, ReceiptBlock, StarknetError, TransactionFinalityStatus, + TransactionReceipt, TransactionReceiptWithBlockInfo, TransactionStatus, }; use starknet::providers::{Provider, ProviderError}; use tokio::time::{Instant, Interval}; @@ -19,7 +19,7 @@ use tokio::time::{Instant, Interval}; use crate::migration::TxnConfig; type GetTxStatusResult = Result; -type GetTxReceiptResult = Result; +type GetTxReceiptResult = Result; type GetTxStatusFuture<'a> = Pin + Send + 'a>>; type GetTxReceiptFuture<'a> = Pin + Send + 'a>>; @@ -54,13 +54,13 @@ pub enum TransactionWaitingError { /// /// let provider = JsonRpcClient::new(HttpTransport::new(Url::parse("http://localhost:5000").unwrap())); /// -/// let tx_hash = FieldElement::from(0xbadbeefu64); +/// let tx_hash = Felt::from(0xbadbeefu64); /// let receipt = TransactionWaiter::new(tx_hash, &provider).with_tx_status(TransactionFinalityStatus::AcceptedOnL2).await.unwrap(); /// ``` #[must_use = "TransactionWaiter does nothing unless polled"] pub struct TransactionWaiter<'a, P: Provider> { /// The hash of the transaction to wait for. - tx_hash: FieldElement, + tx_hash: Felt, /// The transaction finality status to wait for. /// /// If not set, then it will wait until it is `ACCEPTED_ON_L2` whether it is reverted or not. @@ -97,7 +97,7 @@ where /// Interval for use with 3rd party provider without burning the API rate limit. const DEFAULT_INTERVAL: Duration = Duration::from_millis(2500); - pub fn new(tx: FieldElement, provider: &'a P) -> Self { + pub fn new(tx: Felt, provider: &'a P) -> Self { Self { provider, tx_hash: tx, @@ -130,12 +130,12 @@ where // Helper function to evaluate if the transaction receipt should be accepted yet or not, based // on the waiter's parameters. Used in the `Future` impl. fn evaluate_receipt_from_params( - receipt: MaybePendingTransactionReceipt, + receipt: TransactionReceiptWithBlockInfo, expected_finality_status: Option, must_succeed: bool, - ) -> Option> { - match &receipt { - MaybePendingTransactionReceipt::PendingReceipt(r) => { + ) -> Option> { + match &receipt.block { + ReceiptBlock::Pending => { // pending receipt doesn't include finality status, so we cant check it. if expected_finality_status.is_some() { return None; @@ -145,7 +145,7 @@ where return Some(Ok(receipt)); } - match execution_status_from_pending_receipt(r) { + match execution_status_from_receipt(&receipt.receipt) { ExecutionResult::Succeeded => Some(Ok(receipt)), ExecutionResult::Reverted { reason } => { Some(Err(TransactionWaitingError::TransactionReverted(reason.clone()))) @@ -153,9 +153,9 @@ where } } - MaybePendingTransactionReceipt::Receipt(r) => { + ReceiptBlock::Block { .. } => { if let Some(expected_status) = expected_finality_status { - match finality_status_from_receipt(r) { + match finality_status_from_receipt(&receipt.receipt) { TransactionFinalityStatus::AcceptedOnL2 if expected_status == TransactionFinalityStatus::AcceptedOnL1 => { @@ -167,7 +167,7 @@ where return Some(Ok(receipt)); } - match execution_status_from_receipt(r) { + match execution_status_from_receipt(&receipt.receipt) { ExecutionResult::Succeeded => Some(Ok(receipt)), ExecutionResult::Reverted { reason } => Some(Err( TransactionWaitingError::TransactionReverted(reason.clone()), @@ -187,7 +187,7 @@ impl<'a, P> Future for TransactionWaiter<'a, P> where P: Provider + Send, { - type Output = Result; + type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); @@ -255,9 +255,9 @@ where return Poll::Ready(Err(TransactionWaitingError::Provider(e))); } - Ok(receipt) => { + Ok(res) => { if let Some(res) = Self::evaluate_receipt_from_params( - receipt, + res, this.tx_finality_status, this.must_succeed, ) { @@ -281,19 +281,7 @@ where } #[inline] -pub fn execution_status_from_maybe_pending_receipt( - receipt: &MaybePendingTransactionReceipt, -) -> &ExecutionResult { - match &receipt { - MaybePendingTransactionReceipt::PendingReceipt(r) => { - execution_status_from_pending_receipt(r) - } - MaybePendingTransactionReceipt::Receipt(r) => execution_status_from_receipt(r), - } -} - -#[inline] -fn execution_status_from_receipt(receipt: &TransactionReceipt) -> &ExecutionResult { +pub fn execution_status_from_receipt(receipt: &TransactionReceipt) -> &ExecutionResult { match receipt { TransactionReceipt::Invoke(receipt) => &receipt.execution_result, TransactionReceipt::Deploy(receipt) => &receipt.execution_result, @@ -303,16 +291,6 @@ fn execution_status_from_receipt(receipt: &TransactionReceipt) -> &ExecutionResu } } -#[inline] -fn execution_status_from_pending_receipt(receipt: &PendingTransactionReceipt) -> &ExecutionResult { - match receipt { - PendingTransactionReceipt::Invoke(receipt) => &receipt.execution_result, - PendingTransactionReceipt::Declare(receipt) => &receipt.execution_result, - PendingTransactionReceipt::L1Handler(receipt) => &receipt.execution_result, - PendingTransactionReceipt::DeployAccount(receipt) => &receipt.execution_result, - } -} - #[inline] fn finality_status_from_receipt(receipt: &TransactionReceipt) -> TransactionFinalityStatus { match receipt { @@ -324,17 +302,6 @@ fn finality_status_from_receipt(receipt: &TransactionReceipt) -> TransactionFina } } -#[inline] -pub fn block_number_from_receipt(receipt: &TransactionReceipt) -> u64 { - match receipt { - TransactionReceipt::Invoke(tx) => tx.block_number, - TransactionReceipt::L1Handler(tx) => tx.block_number, - TransactionReceipt::Declare(tx) => tx.block_number, - TransactionReceipt::Deploy(tx) => tx.block_number, - TransactionReceipt::DeployAccount(tx) => tx.block_number, - } -} - /// Helper trait to abstract away setting `TxnConfig` configurations before sending a transaction /// Implemented by types from `starknet-accounts` like `Execution`, `Declaration`, etc... #[allow(async_fn_in_trait)] @@ -349,7 +316,7 @@ pub trait TransactionExt { async fn send_with_cfg(self, txn_config: &TxnConfig) -> Result; } -impl TransactionExt for Execution<'_, T> +impl TransactionExt for ExecutionV1<'_, T> where T: ConnectedAccount + Sync, { @@ -372,7 +339,7 @@ where } } -impl TransactionExt for Declaration<'_, T> +impl TransactionExt for DeclarationV2<'_, T> where T: ConnectedAccount + Sync, { @@ -395,7 +362,7 @@ where } } -impl TransactionExt for AccountDeployment<'_, T> +impl TransactionExt for AccountDeploymentV1<'_, T> where T: AccountFactory + Sync, { @@ -425,9 +392,9 @@ mod tests { get_default_test_starknet_config, SequencerConfig, TestSequencer, }; use starknet::core::types::{ - ExecutionResources, ExecutionResult, FeePayment, FieldElement, InvokeTransactionReceipt, - MaybePendingTransactionReceipt, PendingInvokeTransactionReceipt, PendingTransactionReceipt, - PriceUnit, TransactionFinalityStatus, TransactionReceipt, + ComputationResources, DataAvailabilityResources, DataResources, ExecutionResources, + ExecutionResult, FeePayment, Felt, InvokeTransactionReceipt, PriceUnit, ReceiptBlock, + TransactionFinalityStatus, TransactionReceipt, TransactionReceiptWithBlockInfo, }; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; @@ -443,44 +410,58 @@ mod tests { } const EXECUTION_RESOURCES: ExecutionResources = ExecutionResources { - steps: 0, - memory_holes: None, - ec_op_builtin_applications: Some(0), - ecdsa_builtin_applications: Some(0), - keccak_builtin_applications: Some(0), - bitwise_builtin_applications: Some(0), - pedersen_builtin_applications: Some(0), - poseidon_builtin_applications: Some(0), - range_check_builtin_applications: Some(0), - segment_arena_builtin: Some(0), + computation_resources: ComputationResources { + steps: 0, + memory_holes: None, + ec_op_builtin_applications: Some(0), + ecdsa_builtin_applications: Some(0), + keccak_builtin_applications: Some(0), + bitwise_builtin_applications: Some(0), + pedersen_builtin_applications: Some(0), + poseidon_builtin_applications: Some(0), + range_check_builtin_applications: Some(0), + segment_arena_builtin: Some(0), + }, + data_resources: DataResources { + data_availability: DataAvailabilityResources { l1_gas: 0, l1_data_gas: 0 }, + }, }; fn mock_receipt( finality_status: TransactionFinalityStatus, execution_result: ExecutionResult, - ) -> TransactionReceipt { - TransactionReceipt::Invoke(InvokeTransactionReceipt { + ) -> TransactionReceiptWithBlockInfo { + let receipt = TransactionReceipt::Invoke(InvokeTransactionReceipt { finality_status, execution_result, events: Default::default(), actual_fee: FeePayment { amount: Default::default(), unit: PriceUnit::Wei }, - block_hash: Default::default(), - block_number: Default::default(), messages_sent: Default::default(), transaction_hash: Default::default(), execution_resources: EXECUTION_RESOURCES, - }) + }); + + TransactionReceiptWithBlockInfo { + receipt, + block: ReceiptBlock::Block { + block_hash: Default::default(), + block_number: Default::default(), + }, + } } - fn mock_pending_receipt(execution_result: ExecutionResult) -> PendingTransactionReceipt { - PendingTransactionReceipt::Invoke(PendingInvokeTransactionReceipt { + fn mock_pending_receipt(execution_result: ExecutionResult) -> TransactionReceiptWithBlockInfo { + let receipt = TransactionReceipt::Invoke(InvokeTransactionReceipt { execution_result, events: Default::default(), + finality_status: TransactionFinalityStatus::AcceptedOnL2, actual_fee: FeePayment { amount: Default::default(), unit: PriceUnit::Wei }, messages_sent: Default::default(), transaction_hash: Default::default(), execution_resources: EXECUTION_RESOURCES, - }) + }); + + TransactionReceiptWithBlockInfo { receipt, block: ReceiptBlock::Pending } } #[tokio::test] @@ -488,7 +469,7 @@ mod tests { let (_sequencer, provider) = create_test_sequencer().await; assert_matches!( - TransactionWaiter::new(FieldElement::from_hex_be("0x1234").unwrap(), &provider) + TransactionWaiter::new(Felt::from_hex("0x1234").unwrap(), &provider) .with_timeout(Duration::from_secs(1)) .await, Err(super::TransactionWaitingError::Timeout) @@ -497,10 +478,8 @@ mod tests { #[test] fn wait_for_no_finality_status() { - let receipt = MaybePendingTransactionReceipt::Receipt(mock_receipt( - TransactionFinalityStatus::AcceptedOnL2, - ExecutionResult::Succeeded, - )); + let receipt = + mock_receipt(TransactionFinalityStatus::AcceptedOnL2, ExecutionResult::Succeeded); assert_eq!( TransactionWaiter::>::evaluate_receipt_from_params( @@ -532,10 +511,8 @@ mod tests { #[test] fn wait_for_finality_status_with_no_succeed() { { - let receipt = MaybePendingTransactionReceipt::Receipt(mock_receipt( - TransactionFinalityStatus::AcceptedOnL2, - ExecutionResult::Succeeded, - )); + let receipt = + mock_receipt(TransactionFinalityStatus::AcceptedOnL2, ExecutionResult::Succeeded); assert_eval_receipt!( (receipt.clone(), Some(TransactionFinalityStatus::AcceptedOnL2)), @@ -544,10 +521,8 @@ mod tests { } { - let receipt = MaybePendingTransactionReceipt::Receipt(mock_receipt( - TransactionFinalityStatus::AcceptedOnL2, - ExecutionResult::Succeeded, - )); + let receipt = + mock_receipt(TransactionFinalityStatus::AcceptedOnL2, ExecutionResult::Succeeded); assert!( TransactionWaiter::>::evaluate_receipt_from_params( @@ -560,10 +535,8 @@ mod tests { } { - let receipt = MaybePendingTransactionReceipt::Receipt(mock_receipt( - TransactionFinalityStatus::AcceptedOnL1, - ExecutionResult::Succeeded, - )); + let receipt = + mock_receipt(TransactionFinalityStatus::AcceptedOnL1, ExecutionResult::Succeeded); assert_eval_receipt!( (receipt.clone(), Some(TransactionFinalityStatus::AcceptedOnL2)), @@ -572,10 +545,8 @@ mod tests { } { - let receipt = MaybePendingTransactionReceipt::Receipt(mock_receipt( - TransactionFinalityStatus::AcceptedOnL1, - ExecutionResult::Succeeded, - )); + let receipt = + mock_receipt(TransactionFinalityStatus::AcceptedOnL1, ExecutionResult::Succeeded); assert_eval_receipt!( (receipt.clone(), Some(TransactionFinalityStatus::AcceptedOnL1)), @@ -587,10 +558,8 @@ mod tests { #[test] fn wait_for_finality_status_with_must_succeed() { { - let receipt = MaybePendingTransactionReceipt::Receipt(mock_receipt( - TransactionFinalityStatus::AcceptedOnL2, - ExecutionResult::Succeeded, - )); + let receipt = + mock_receipt(TransactionFinalityStatus::AcceptedOnL2, ExecutionResult::Succeeded); assert_eq!( TransactionWaiter::>::evaluate_receipt_from_params( @@ -605,10 +574,8 @@ mod tests { } { - let receipt = MaybePendingTransactionReceipt::Receipt(mock_receipt( - TransactionFinalityStatus::AcceptedOnL1, - ExecutionResult::Succeeded, - )); + let receipt = + mock_receipt(TransactionFinalityStatus::AcceptedOnL1, ExecutionResult::Succeeded); assert_eq!( TransactionWaiter::>::evaluate_receipt_from_params( @@ -623,10 +590,10 @@ mod tests { } { - let receipt = MaybePendingTransactionReceipt::Receipt(mock_receipt( + let receipt = mock_receipt( TransactionFinalityStatus::AcceptedOnL1, ExecutionResult::Reverted { reason: Default::default() }, - )); + ); let err = TransactionWaiter::>::evaluate_receipt_from_params( @@ -644,9 +611,7 @@ mod tests { #[test] fn wait_for_pending_tx() { { - let receipt = MaybePendingTransactionReceipt::PendingReceipt(mock_pending_receipt( - ExecutionResult::Succeeded, - )); + let receipt = mock_pending_receipt(ExecutionResult::Succeeded); assert!( TransactionWaiter::>::evaluate_receipt_from_params( @@ -659,9 +624,8 @@ mod tests { } { - let receipt = MaybePendingTransactionReceipt::PendingReceipt(mock_pending_receipt( - ExecutionResult::Reverted { reason: Default::default() }, - )); + let receipt = + mock_pending_receipt(ExecutionResult::Reverted { reason: Default::default() }); assert_eq!( TransactionWaiter::>::evaluate_receipt_from_params( @@ -676,9 +640,8 @@ mod tests { } { - let receipt = MaybePendingTransactionReceipt::PendingReceipt(mock_pending_receipt( - ExecutionResult::Reverted { reason: Default::default() }, - )); + let receipt = + mock_pending_receipt(ExecutionResult::Reverted { reason: Default::default() }); let err = TransactionWaiter::>::evaluate_receipt_from_params( diff --git a/crates/katana/controller/src/lib.rs b/crates/katana/controller/src/lib.rs index ec4716d891..bb5ddded59 100644 --- a/crates/katana/controller/src/lib.rs +++ b/crates/katana/controller/src/lib.rs @@ -50,7 +50,11 @@ fn add_controller_account_inner(genesis: &mut Genesis, user: slot::account::Acco storage: Some(get_contract_storage(credential_id, public_key, SignerType::Webauthn)?), }; - (ContractAddress::from(user.contract_address), GenesisAllocation::Contract(account)) + let address = ContractAddress::from(FieldElement::from_bytes_be( + &user.contract_address.to_bytes_be(), + )); + + (address, GenesisAllocation::Contract(account)) }; genesis.extend_allocations([(address, contract)]); @@ -102,7 +106,11 @@ pub mod json { )?), }; - (ContractAddress::from(user.account.contract_address), account) + let address = ContractAddress::from(FieldElement::from_bytes_be( + &user.account.contract_address.to_bytes_be(), + )); + + (address, account) }; genesis.contracts.insert(address, contract); diff --git a/crates/katana/core/Cargo.toml b/crates/katana/core/Cargo.toml index f3bb707825..7497cd7441 100644 --- a/crates/katana/core/Cargo.toml +++ b/crates/katana/core/Cargo.toml @@ -15,8 +15,6 @@ katana-tasks.workspace = true anyhow.workspace = true async-trait.workspace = true -cairo-lang-casm = "=2.6.3" -cairo-lang-starknet = "=2.6.3" cairo-vm.workspace = true convert_case.workspace = true derive_more.workspace = true @@ -26,6 +24,7 @@ futures.workspace = true k256 = { version = "0.13", default-features = false, features = [ "ecdsa", "std" ] } lazy_static.workspace = true metrics.workspace = true +num-traits.workspace = true parking_lot.workspace = true rand = { workspace = true, features = [ "small_rng" ] } reqwest.workspace = true diff --git a/crates/katana/core/src/backend/mod.rs b/crates/katana/core/src/backend/mod.rs index 209b58a2dc..b1a73c08ae 100644 --- a/crates/katana/core/src/backend/mod.rs +++ b/crates/katana/core/src/backend/mod.rs @@ -11,6 +11,7 @@ use katana_primitives::FieldElement; use katana_provider::providers::fork::ForkedProvider; use katana_provider::providers::in_memory::InMemoryProvider; use katana_provider::traits::block::{BlockHashProvider, BlockWriter}; +use num_traits::ToPrimitive; use parking_lot::RwLock; use starknet::core::types::{BlockId, BlockStatus, MaybePendingBlockWithTxHashes}; use starknet::core::utils::parse_cairo_short_string; @@ -73,9 +74,9 @@ impl Backend { config.genesis.timestamp = block.timestamp; config.genesis.sequencer_address = block.sequencer_address.into(); config.genesis.gas_prices.eth = - block.l1_gas_price.price_in_wei.try_into().expect("should fit in u128"); + block.l1_gas_price.price_in_wei.to_u128().expect("should fit in u128"); config.genesis.gas_prices.strk = - block.l1_gas_price.price_in_fri.try_into().expect("should fit in u128"); + block.l1_gas_price.price_in_fri.to_u128().expect("should fit in u128"); trace!( target: LOG_TARGET, diff --git a/crates/katana/core/src/pool.rs b/crates/katana/core/src/pool.rs index 8214e91657..c8c423cd70 100644 --- a/crates/katana/core/src/pool.rs +++ b/crates/katana/core/src/pool.rs @@ -2,8 +2,8 @@ use futures::channel::mpsc::{channel, Receiver, Sender}; use katana_primitives::transaction::ExecutableTxWithHash; +use katana_primitives::FieldElement; use parking_lot::RwLock; -use starknet::core::types::FieldElement; use tracing::{info, warn}; pub(crate) const LOG_TARGET: &str = "txpool"; diff --git a/crates/katana/core/src/service/messaging/starknet.rs b/crates/katana/core/src/service/messaging/starknet.rs index 6f85fe550a..fc5d9083ce 100644 --- a/crates/katana/core/src/service/messaging/starknet.rs +++ b/crates/katana/core/src/service/messaging/starknet.rs @@ -8,7 +8,7 @@ use katana_primitives::receipt::MessageToL1; use katana_primitives::transaction::L1HandlerTx; use katana_primitives::utils::transaction::compute_l2_to_l1_message_hash; use starknet::accounts::{Account, Call, ExecutionEncoding, SingleOwnerAccount}; -use starknet::core::types::{BlockId, BlockTag, EmittedEvent, EventFilter, FieldElement}; +use starknet::core::types::{BlockId, BlockTag, EmittedEvent, EventFilter, Felt}; use starknet::core::utils::starknet_keccak; use starknet::macros::{felt, selector}; use starknet::providers::jsonrpc::HttpTransport; @@ -24,17 +24,17 @@ use super::{Error, MessagingConfig, Messenger, MessengerResult, LOG_TARGET}; /// In the case of execution -> the felt 'EXE' will be passed. /// And for normal messages, the felt 'MSG' is used. /// Those values are very not likely a valid account address on starknet. -const MSG_MAGIC: FieldElement = felt!("0x4d5347"); -const EXE_MAGIC: FieldElement = felt!("0x455845"); +const MSG_MAGIC: Felt = felt!("0x4d5347"); +const EXE_MAGIC: Felt = felt!("0x455845"); -pub const HASH_EXEC: FieldElement = felt!("0xee"); +pub const HASH_EXEC: Felt = felt!("0xee"); pub struct StarknetMessaging { - chain_id: FieldElement, + chain_id: Felt, provider: AnyProvider, wallet: LocalWallet, - sender_account_address: FieldElement, - messaging_contract_address: FieldElement, + sender_account_address: Felt, + messaging_contract_address: Felt, } impl StarknetMessaging { @@ -43,13 +43,13 @@ impl StarknetMessaging { Url::parse(&config.rpc_url)?, ))); - let private_key = FieldElement::from_hex_be(&config.private_key)?; + let private_key = Felt::from_hex(&config.private_key)?; let key = SigningKey::from_secret_scalar(private_key); let wallet = LocalWallet::from_signing_key(key); let chain_id = provider.chain_id().await?; - let sender_account_address = FieldElement::from_hex_be(&config.sender_address)?; - let messaging_contract_address = FieldElement::from_hex_be(&config.contract_address)?; + let sender_account_address = Felt::from_hex(&config.sender_address)?; + let messaging_contract_address = Felt::from_hex(&config.contract_address)?; Ok(StarknetMessaging { wallet, @@ -107,7 +107,7 @@ impl StarknetMessaging { } /// Sends an invoke TX on starknet. - async fn send_invoke_tx(&self, calls: Vec) -> Result { + async fn send_invoke_tx(&self, calls: Vec) -> Result { let signer = Arc::new(&self.wallet); let mut account = SingleOwnerAccount::new( @@ -121,19 +121,19 @@ impl StarknetMessaging { account.set_block_id(BlockId::Tag(BlockTag::Pending)); // TODO: we need to have maximum fee configurable. - let execution = account.execute(calls).fee_estimate_multiplier(10f64); - let estimated_fee = (execution.estimate_fee().await?.overall_fee) * 10u64.into(); + let execution = account.execute_v1(calls).fee_estimate_multiplier(10f64); + let estimated_fee = (execution.estimate_fee().await?.overall_fee) * Felt::from(10u128); let tx = execution.max_fee(estimated_fee).send().await?; Ok(tx.transaction_hash) } /// Sends messages hashes to settlement layer by sending a transaction. - async fn send_hashes(&self, mut hashes: Vec) -> MessengerResult { + async fn send_hashes(&self, mut hashes: Vec) -> MessengerResult { hashes.retain(|&x| x != HASH_EXEC); if hashes.is_empty() { - return Ok(FieldElement::ZERO); + return Ok(Felt::ZERO); } let mut calldata = hashes; @@ -160,7 +160,7 @@ impl StarknetMessaging { #[async_trait] impl Messenger for StarknetMessaging { - type MessageHash = FieldElement; + type MessageHash = Felt; type MessageTransaction = L1HandlerTx; async fn gather_messages( @@ -250,8 +250,8 @@ impl Messenger for StarknetMessaging { /// /// Messages can also be labelled as EXE, which in this case generate a `Call` /// additionally to the hash. -fn parse_messages(messages: &[MessageToL1]) -> MessengerResult<(Vec, Vec)> { - let mut hashes: Vec = vec![]; +fn parse_messages(messages: &[MessageToL1]) -> MessengerResult<(Vec, Vec)> { + let mut hashes: Vec = vec![]; let mut calls: Vec = vec![]; for m in messages { @@ -295,7 +295,7 @@ fn parse_messages(messages: &[MessageToL1]) -> MessengerResult<(Vec = vec![]; buf.extend(m.from_address.to_bytes_be()); buf.extend(to_address.to_bytes_be()); - buf.extend(FieldElement::from(payload.len()).to_bytes_be()); + buf.extend(Felt::from(payload.len()).to_bytes_be()); for p in payload { buf.extend(p.to_bytes_be()); } @@ -347,7 +347,7 @@ fn l1_handler_tx_from_event(event: &EmittedEvent, chain_id: ChainId) -> Result for ExecutionError { fn from(error: TransactionExecutionError) -> Self { match error { TransactionExecutionError::DeclareTransactionError { class_hash } => { - Self::ClassAlreadyDeclared(class_hash.0.into()) + Self::ClassAlreadyDeclared(to_felt(class_hash.0)) } TransactionExecutionError::ValidateTransactionError(e) => { Self::TransactionValidationFailed(Box::new(Self::from(e))) @@ -50,7 +50,7 @@ impl From for ExecutionError { fn from(error: PreExecutionError) -> Self { match error { PreExecutionError::EntryPointNotFound(selector) => { - Self::EntryPointNotFound(selector.0.into()) + Self::EntryPointNotFound(to_felt(selector.0)) } PreExecutionError::UninitializedStorageAddress(address) => { Self::ContractNotDeployed(to_address(address)) @@ -69,8 +69,8 @@ impl From for ExecutionError { incoming_tx_nonce, .. } => Self::InvalidNonce { - actual: incoming_tx_nonce.0.into(), - expected: account_nonce.0.into(), + actual: to_felt(incoming_tx_nonce.0), + expected: to_felt(account_nonce.0), }, TransactionPreValidationError::TransactionFeeError(e) => Self::from(e), TransactionPreValidationError::StateError(e) => Self::from(e), @@ -96,7 +96,7 @@ impl From for ExecutionError { impl From for ExecutionError { fn from(error: StateError) -> Self { match error { - StateError::UndeclaredClassHash(hash) => Self::UndeclaredClass(hash.0.into()), + StateError::UndeclaredClassHash(hash) => Self::UndeclaredClass(to_felt(hash.0)), e => Self::Other(e.to_string()), } } diff --git a/crates/katana/executor/src/implementation/blockifier/state.rs b/crates/katana/executor/src/implementation/blockifier/state.rs index c6d7f27572..49d4b17462 100644 --- a/crates/katana/executor/src/implementation/blockifier/state.rs +++ b/crates/katana/executor/src/implementation/blockifier/state.rs @@ -11,12 +11,10 @@ use katana_provider::traits::contract::ContractClassProvider; use katana_provider::traits::state::StateProvider; use katana_provider::ProviderResult; use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; -use starknet_api::core::{ClassHash, CompiledClassHash, Nonce, PatriciaKey}; -use starknet_api::hash::StarkHash; -use starknet_api::patricia_key; +use starknet_api::core::{ClassHash, CompiledClassHash, Nonce}; use starknet_api::state::StorageKey; -use super::utils::{self}; +use super::utils::{self, to_felt, to_stark_felt}; use super::CACHE_SIZE; use crate::StateProviderDb; @@ -32,7 +30,7 @@ impl<'a> StateReader for StateProviderDb<'a> { ) -> StateResult { self.0 .class_hash_of_contract(utils::to_address(contract_address)) - .map(|v| ClassHash(v.unwrap_or_default().into())) + .map(|v| ClassHash(to_stark_felt(v.unwrap_or_default()))) .map_err(|e| StateError::StateReadError(e.to_string())) } @@ -42,10 +40,10 @@ impl<'a> StateReader for StateProviderDb<'a> { ) -> StateResult { if let Some(hash) = self .0 - .compiled_class_hash_of_class_hash(class_hash.0.into()) + .compiled_class_hash_of_class_hash(to_felt(class_hash.0)) .map_err(|e| StateError::StateReadError(e.to_string()))? { - Ok(CompiledClassHash(hash.into())) + Ok(CompiledClassHash(to_stark_felt(hash))) } else { Err(StateError::UndeclaredClassHash(class_hash)) } @@ -57,7 +55,7 @@ impl<'a> StateReader for StateProviderDb<'a> { ) -> StateResult { if let Some(class) = self .0 - .class(class_hash.0.into()) + .class(to_felt(class_hash.0)) .map_err(|e| StateError::StateReadError(e.to_string()))? { let class = @@ -75,7 +73,7 @@ impl<'a> StateReader for StateProviderDb<'a> { ) -> StateResult { self.0 .nonce(utils::to_address(contract_address)) - .map(|n| Nonce(n.unwrap_or_default().into())) + .map(|n| Nonce(to_stark_felt(n.unwrap_or_default()))) .map_err(|e| StateError::StateReadError(e.to_string())) } @@ -85,8 +83,8 @@ impl<'a> StateReader for StateProviderDb<'a> { key: starknet_api::state::StorageKey, ) -> StateResult { self.0 - .storage(utils::to_address(contract_address), (*key.0.key()).into()) - .map(|v| v.unwrap_or_default().into()) + .storage(utils::to_address(contract_address), to_felt(*key.0.key())) + .map(|v| to_stark_felt(v.unwrap_or_default())) .map_err(|e| StateError::StateReadError(e.to_string())) } } @@ -142,10 +140,11 @@ impl ContractClassProvider for CachedState { &self, hash: katana_primitives::class::ClassHash, ) -> ProviderResult> { - let Ok(hash) = self.write().inner.get_compiled_class_hash(ClassHash(hash.into())) else { + let Ok(hash) = self.write().inner.get_compiled_class_hash(ClassHash(to_stark_felt(hash))) + else { return Ok(None); }; - Ok(Some(hash.0.into())) + Ok(Some(to_felt(hash.0))) } fn sierra_class( @@ -170,7 +169,7 @@ impl StateProvider for CachedState { return Ok(None); }; - let hash = hash.0.into(); + let hash = to_felt(hash.0); if hash == FieldElement::ZERO { Ok(None) } else { Ok(Some(hash)) } } @@ -184,7 +183,7 @@ impl StateProvider for CachedState { } match self.0.write().inner.get_nonce_at(utils::to_blk_address(address)) { - Ok(nonce) => Ok(Some(nonce.0.into())), + Ok(nonce) => Ok(Some(to_felt(nonce.0))), Err(e) => Err(ProviderError::Other(e.to_string())), } } @@ -200,10 +199,14 @@ impl StateProvider for CachedState { } let address = utils::to_blk_address(address); - let key = StorageKey(patricia_key!(storage_key)); + let key = StorageKey( + to_stark_felt(storage_key) + .try_into() + .expect("storage key is not a valid field element"), + ); match self.write().inner.get_storage_at(address, key) { - Ok(value) => Ok(Some(value.into())), + Ok(value) => Ok(Some(to_felt(value))), Err(e) => Err(ProviderError::Other(e.to_string())), } } @@ -260,6 +263,9 @@ mod tests { use katana_provider::traits::contract::ContractClassWriter; use katana_provider::traits::state::{StateFactoryProvider, StateProvider, StateWriter}; use starknet::macros::felt; + use starknet_api::core::PatriciaKey; + use starknet_api::hash::StarkHash; + use starknet_api::patricia_key; use super::{CachedState, *}; use crate::StateProviderDb; @@ -308,17 +314,19 @@ mod tests { let api_address = utils::to_blk_address(address); let actual_class_hash = cached_state.get_class_hash_at(api_address)?; let actual_nonce = cached_state.get_nonce_at(api_address)?; - let actual_storage_value = - cached_state.get_storage_at(api_address, StorageKey(patricia_key!(storage_key)))?; + let actual_storage_value = cached_state.get_storage_at( + api_address, + StorageKey(patricia_key!(utils::to_stark_felt(storage_key))), + )?; let actual_compiled_hash = cached_state.get_compiled_class_hash(actual_class_hash)?; let actual_class = cached_state.get_compiled_contract_class(actual_class_hash)?; - let actual_legacy_class = - cached_state.get_compiled_contract_class(ClassHash(legacy_class_hash.into()))?; + let actual_legacy_class = cached_state + .get_compiled_contract_class(ClassHash(to_stark_felt(legacy_class_hash)))?; - assert_eq!(actual_nonce.0, felt!("0x7").into()); - assert_eq!(actual_storage_value, felt!("0x2").into()); - assert_eq!(actual_class_hash.0, felt!("0x123").into()); - assert_eq!(actual_compiled_hash.0, felt!("0x456").into()); + assert_eq!(actual_nonce.0, to_stark_felt(felt!("0x7"))); + assert_eq!(actual_storage_value, to_stark_felt(felt!("0x2"))); + assert_eq!(actual_class_hash.0, to_stark_felt(felt!("0x123"))); + assert_eq!(actual_compiled_hash.0, to_stark_felt(felt!("0x456"))); assert_eq!( actual_class, utils::to_class(DEFAULT_OZ_ACCOUNT_CONTRACT_CASM.clone()).unwrap().contract_class() @@ -378,16 +386,17 @@ mod tests { let blk_state = &mut lock.inner; let address = utils::to_blk_address(new_address); - let storage_key = StorageKey(patricia_key!(new_storage_key)); - let storage_value = new_storage_value.into(); - let class_hash = ClassHash(new_class_hash.into()); + let storage_key = StorageKey(patricia_key!(utils::to_stark_felt(new_storage_key))); + let storage_value = utils::to_stark_felt(new_storage_value); + let class_hash = ClassHash(utils::to_stark_felt(new_class_hash)); let class = utils::to_class(new_compiled_sierra_class.clone()).unwrap().contract_class(); - let compiled_hash = CompiledClassHash(new_compiled_hash.into()); - let legacy_class_hash = ClassHash(new_legacy_class_hash.into()); + let compiled_hash = CompiledClassHash(utils::to_stark_felt(new_compiled_hash)); + let legacy_class_hash = ClassHash(utils::to_stark_felt(new_legacy_class_hash)); let legacy_class = utils::to_class(DEFAULT_LEGACY_UDC_CASM.clone()).unwrap().contract_class(); - let legacy_compiled_hash = CompiledClassHash(new_legacy_compiled_hash.into()); + let legacy_compiled_hash = + CompiledClassHash(utils::to_stark_felt(new_legacy_compiled_hash)); blk_state.increment_nonce(address)?; blk_state.set_class_hash_at(address, legacy_class_hash)?; @@ -488,8 +497,8 @@ mod tests { let mut cached_state = CachedState::new(StateProviderDb(sp)); let api_address = utils::to_blk_address(address); - let api_storage_key = StorageKey(patricia_key!(storage_key)); - let api_class_hash = ClassHash(class_hash.into()); + let api_storage_key = StorageKey(patricia_key!(utils::to_stark_felt(storage_key))); + let api_class_hash = ClassHash(utils::to_stark_felt(class_hash)); let actual_nonce = cached_state.get_nonce_at(api_address).expect("should return default value"); diff --git a/crates/katana/executor/src/implementation/blockifier/utils.rs b/crates/katana/executor/src/implementation/blockifier/utils.rs index 6a22e5b9b4..9a07699b15 100644 --- a/crates/katana/executor/src/implementation/blockifier/utils.rs +++ b/crates/katana/executor/src/implementation/blockifier/utils.rs @@ -40,13 +40,10 @@ use katana_provider::traits::contract::ContractClassProvider; use starknet::core::types::PriceUnit; use starknet::core::utils::parse_cairo_short_string; use starknet_api::block::{BlockNumber, BlockTimestamp}; -use starknet_api::core::{ - self, ChainId, ClassHash, CompiledClassHash, ContractAddress, Nonce, PatriciaKey, -}; +use starknet_api::core::{self, ChainId, ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::deprecated_contract_class::EntryPointType; -use starknet_api::hash::StarkHash; -use starknet_api::patricia_key; +use starknet_api::hash::StarkFelt; use starknet_api::transaction::{ AccountDeploymentData, Calldata, ContractAddressSalt, DeclareTransaction as ApiDeclareTransaction, DeclareTransactionV0V1, DeclareTransactionV2, @@ -138,8 +135,8 @@ pub fn call( let call = CallEntryPoint { initial_gas: initial_gas as u64, storage_address: to_blk_address(request.contract_address), - entry_point_selector: core::EntryPointSelector(request.entry_point_selector.into()), - calldata: Calldata(Arc::new(request.calldata.into_iter().map(|f| f.into()).collect())), + entry_point_selector: core::EntryPointSelector(to_stark_felt(request.entry_point_selector)), + calldata: Calldata(Arc::new(request.calldata.into_iter().map(to_stark_felt).collect())), ..Default::default() }; @@ -169,7 +166,7 @@ pub fn call( )?; let retdata = res.execution.retdata.0; - let retdata = retdata.into_iter().map(|f| f.into()).collect::>(); + let retdata = retdata.into_iter().map(to_felt).collect::>(); Ok(retdata) } @@ -179,36 +176,36 @@ fn to_executor_tx(tx: ExecutableTxWithHash) -> Transaction { match tx.transaction { ExecutableTx::Invoke(tx) => match tx { InvokeTx::V1(tx) => { - let calldata = tx.calldata.into_iter().map(|f| f.into()).collect(); - let signature = tx.signature.into_iter().map(|f| f.into()).collect(); + let calldata = tx.calldata.into_iter().map(to_stark_felt).collect(); + let signature = tx.signature.into_iter().map(to_stark_felt).collect(); Transaction::AccountTransaction(AccountTransaction::Invoke(InvokeTransaction { tx: ApiInvokeTransaction::V1(starknet_api::transaction::InvokeTransactionV1 { max_fee: Fee(tx.max_fee), - nonce: Nonce(tx.nonce.into()), + nonce: Nonce(to_stark_felt(tx.nonce)), sender_address: to_blk_address(tx.sender_address), signature: TransactionSignature(signature), calldata: Calldata(Arc::new(calldata)), }), - tx_hash: TransactionHash(hash.into()), + tx_hash: TransactionHash(to_stark_felt(hash)), only_query: false, })) } InvokeTx::V3(tx) => { - let calldata = tx.calldata.into_iter().map(|f| f.into()).collect(); - let signature = tx.signature.into_iter().map(|f| f.into()).collect(); + let calldata = tx.calldata.into_iter().map(to_stark_felt).collect(); + let signature = tx.signature.into_iter().map(to_stark_felt).collect(); - let paymaster_data = tx.paymaster_data.into_iter().map(|f| f.into()).collect(); + let paymaster_data = tx.paymaster_data.into_iter().map(to_stark_felt).collect(); let account_deploy_data = - tx.account_deployment_data.into_iter().map(|f| f.into()).collect(); + tx.account_deployment_data.into_iter().map(to_stark_felt).collect(); let fee_data_availability_mode = to_api_da_mode(tx.fee_data_availability_mode); let nonce_data_availability_mode = to_api_da_mode(tx.nonce_data_availability_mode); Transaction::AccountTransaction(AccountTransaction::Invoke(InvokeTransaction { tx: ApiInvokeTransaction::V3(starknet_api::transaction::InvokeTransactionV3 { tip: Tip(tx.tip), - nonce: Nonce(tx.nonce.into()), + nonce: Nonce(to_stark_felt(tx.nonce)), sender_address: to_blk_address(tx.sender_address), signature: TransactionSignature(signature), calldata: Calldata(Arc::new(calldata)), @@ -218,7 +215,7 @@ fn to_executor_tx(tx: ExecutableTxWithHash) -> Transaction { nonce_data_availability_mode, resource_bounds: to_api_resource_bounds(tx.resource_bounds), }), - tx_hash: TransactionHash(hash.into()), + tx_hash: TransactionHash(to_stark_felt(hash)), only_query: false, })) } @@ -226,33 +223,33 @@ fn to_executor_tx(tx: ExecutableTxWithHash) -> Transaction { ExecutableTx::DeployAccount(tx) => match tx { DeployAccountTx::V1(tx) => { - let calldata = tx.constructor_calldata.into_iter().map(|f| f.into()).collect(); - let signature = tx.signature.into_iter().map(|f| f.into()).collect(); - let salt = ContractAddressSalt(tx.contract_address_salt.into()); + let calldata = tx.constructor_calldata.into_iter().map(to_stark_felt).collect(); + let signature = tx.signature.into_iter().map(to_stark_felt).collect(); + let salt = ContractAddressSalt(to_stark_felt(tx.contract_address_salt)); Transaction::AccountTransaction(AccountTransaction::DeployAccount( DeployAccountTransaction { contract_address: to_blk_address(tx.contract_address), tx: ApiDeployAccountTransaction::V1(DeployAccountTransactionV1 { max_fee: Fee(tx.max_fee), - nonce: Nonce(tx.nonce.into()), + nonce: Nonce(to_stark_felt(tx.nonce)), signature: TransactionSignature(signature), - class_hash: ClassHash(tx.class_hash.into()), + class_hash: ClassHash(to_stark_felt(tx.class_hash)), constructor_calldata: Calldata(Arc::new(calldata)), contract_address_salt: salt, }), - tx_hash: TransactionHash(hash.into()), + tx_hash: TransactionHash(to_stark_felt(hash)), only_query: false, }, )) } DeployAccountTx::V3(tx) => { - let calldata = tx.constructor_calldata.into_iter().map(|f| f.into()).collect(); - let signature = tx.signature.into_iter().map(|f| f.into()).collect(); - let salt = ContractAddressSalt(tx.contract_address_salt.into()); + let calldata = tx.constructor_calldata.into_iter().map(to_stark_felt).collect(); + let signature = tx.signature.into_iter().map(to_stark_felt).collect(); + let salt = ContractAddressSalt(to_stark_felt(tx.contract_address_salt)); - let paymaster_data = tx.paymaster_data.into_iter().map(|f| f.into()).collect(); + let paymaster_data = tx.paymaster_data.into_iter().map(to_stark_felt).collect(); let fee_data_availability_mode = to_api_da_mode(tx.fee_data_availability_mode); let nonce_data_availability_mode = to_api_da_mode(tx.nonce_data_availability_mode); @@ -261,9 +258,9 @@ fn to_executor_tx(tx: ExecutableTxWithHash) -> Transaction { contract_address: to_blk_address(tx.contract_address), tx: ApiDeployAccountTransaction::V3(DeployAccountTransactionV3 { tip: Tip(tx.tip), - nonce: Nonce(tx.nonce.into()), + nonce: Nonce(to_stark_felt(tx.nonce)), signature: TransactionSignature(signature), - class_hash: ClassHash(tx.class_hash.into()), + class_hash: ClassHash(to_stark_felt(tx.class_hash)), constructor_calldata: Calldata(Arc::new(calldata)), contract_address_salt: salt, paymaster_data: PaymasterData(paymaster_data), @@ -271,7 +268,7 @@ fn to_executor_tx(tx: ExecutableTxWithHash) -> Transaction { nonce_data_availability_mode, resource_bounds: to_api_resource_bounds(tx.resource_bounds), }), - tx_hash: TransactionHash(hash.into()), + tx_hash: TransactionHash(to_stark_felt(hash)), only_query: false, }, )) @@ -283,48 +280,52 @@ fn to_executor_tx(tx: ExecutableTxWithHash) -> Transaction { let tx = match tx.transaction { DeclareTx::V1(tx) => { - let signature = tx.signature.into_iter().map(|f| f.into()).collect(); + let signature = tx.signature.into_iter().map(to_stark_felt).collect(); ApiDeclareTransaction::V1(DeclareTransactionV0V1 { max_fee: Fee(tx.max_fee), - nonce: Nonce(tx.nonce.into()), + nonce: Nonce(to_stark_felt(tx.nonce)), sender_address: to_blk_address(tx.sender_address), signature: TransactionSignature(signature), - class_hash: ClassHash(tx.class_hash.into()), + class_hash: ClassHash(to_stark_felt(tx.class_hash)), }) } DeclareTx::V2(tx) => { - let signature = tx.signature.into_iter().map(|f| f.into()).collect(); + let signature = tx.signature.into_iter().map(to_stark_felt).collect(); ApiDeclareTransaction::V2(DeclareTransactionV2 { max_fee: Fee(tx.max_fee), - nonce: Nonce(tx.nonce.into()), + nonce: Nonce(to_stark_felt(tx.nonce)), sender_address: to_blk_address(tx.sender_address), signature: TransactionSignature(signature), - class_hash: ClassHash(tx.class_hash.into()), - compiled_class_hash: CompiledClassHash(tx.compiled_class_hash.into()), + class_hash: ClassHash(to_stark_felt(tx.class_hash)), + compiled_class_hash: CompiledClassHash(to_stark_felt( + tx.compiled_class_hash, + )), }) } DeclareTx::V3(tx) => { - let signature = tx.signature.into_iter().map(|f| f.into()).collect(); + let signature = tx.signature.into_iter().map(to_stark_felt).collect(); - let paymaster_data = tx.paymaster_data.into_iter().map(|f| f.into()).collect(); + let paymaster_data = tx.paymaster_data.into_iter().map(to_stark_felt).collect(); let fee_data_availability_mode = to_api_da_mode(tx.fee_data_availability_mode); let nonce_data_availability_mode = to_api_da_mode(tx.nonce_data_availability_mode); let account_deploy_data = - tx.account_deployment_data.into_iter().map(|f| f.into()).collect(); + tx.account_deployment_data.into_iter().map(to_stark_felt).collect(); ApiDeclareTransaction::V3(DeclareTransactionV3 { tip: Tip(tx.tip), - nonce: Nonce(tx.nonce.into()), + nonce: Nonce(to_stark_felt(tx.nonce)), sender_address: to_blk_address(tx.sender_address), signature: TransactionSignature(signature), - class_hash: ClassHash(tx.class_hash.into()), + class_hash: ClassHash(to_stark_felt(tx.class_hash)), account_deployment_data: AccountDeploymentData(account_deploy_data), - compiled_class_hash: CompiledClassHash(tx.compiled_class_hash.into()), + compiled_class_hash: CompiledClassHash(to_stark_felt( + tx.compiled_class_hash, + )), paymaster_data: PaymasterData(paymaster_data), fee_data_availability_mode, nonce_data_availability_mode, @@ -333,24 +334,26 @@ fn to_executor_tx(tx: ExecutableTxWithHash) -> Transaction { } }; - let hash = TransactionHash(hash.into()); + let hash = TransactionHash(to_stark_felt(hash)); let class = to_class(contract_class).unwrap(); let tx = DeclareTransaction::new(tx, hash, class).expect("class mismatch"); Transaction::AccountTransaction(AccountTransaction::Declare(tx)) } ExecutableTx::L1Handler(tx) => { - let calldata = tx.calldata.into_iter().map(|f| f.into()).collect(); + let calldata = tx.calldata.into_iter().map(to_stark_felt).collect(); Transaction::L1HandlerTransaction(L1HandlerTransaction { paid_fee_on_l1: Fee(tx.paid_fee_on_l1), tx: starknet_api::transaction::L1HandlerTransaction { - nonce: core::Nonce(tx.nonce.into()), + nonce: core::Nonce(to_stark_felt(tx.nonce)), calldata: Calldata(Arc::new(calldata)), version: TransactionVersion(1u128.into()), contract_address: to_blk_address(tx.contract_address), - entry_point_selector: core::EntryPointSelector(tx.entry_point_selector.into()), + entry_point_selector: core::EntryPointSelector(to_stark_felt( + tx.entry_point_selector, + )), }, - tx_hash: TransactionHash(hash.into()), + tx_hash: TransactionHash(to_stark_felt(hash)), }) } } @@ -410,7 +413,7 @@ pub(super) fn state_update_from_cached_state( > = HashMap::new(); for (class_hash, _) in &state_diff.class_hash_to_compiled_class_hash { - let hash = class_hash.0.into(); + let hash = to_felt(class_hash.0); let class = state.class(hash).unwrap().expect("must exist if declared"); if let CompiledClass::Class(_) = class { @@ -425,7 +428,7 @@ pub(super) fn state_update_from_cached_state( state_diff .address_to_nonce .into_iter() - .map(|(key, value)| (to_address(key), value.0.into())) + .map(|(key, value)| (to_address(key), to_felt(value.0))) .collect::( .map(|(addr, entries)| { let entries = entries .into_iter() - .map(|(k, v)| ((*k.0.key()).into(), v.into())) + .map(|(k, v)| (to_felt(*k.0.key()), to_felt(v))) .collect::>(); + katana_primitives::contract::StorageKey, + katana_primitives::contract::StorageValue, + >>(); (to_address(addr), entries) }) @@ -451,7 +454,7 @@ pub(super) fn state_update_from_cached_state( state_diff .address_to_class_hash .into_iter() - .map(|(key, value)| (to_address(key), value.0.into())) + .map(|(key, value)| (to_address(key), to_felt(value.0))) .collect::( state_diff .class_hash_to_compiled_class_hash .into_iter() - .map(|(key, value)| (key.0.into(), value.0.into())) + .map(|(key, value)| (to_felt(key.0), to_felt(value.0))) .collect:: FeeType { } pub fn to_blk_address(address: katana_primitives::contract::ContractAddress) -> ContractAddress { - ContractAddress(patricia_key!(address.0)) + to_stark_felt(address.0).try_into().expect("valid address") } pub fn to_address(address: ContractAddress) -> katana_primitives::contract::ContractAddress { - katana_primitives::contract::ContractAddress((*address.0.key()).into()) + katana_primitives::contract::ContractAddress(to_felt(*address.0.key())) } pub fn to_blk_chain_id(chain_id: katana_primitives::chain::ChainId) -> ChainId { @@ -558,7 +561,7 @@ fn starknet_api_ethaddr_to_felt(value: starknet_api::core::EthAddress) -> FieldE // Padding H160 with zeros to 32 bytes (big endian) bytes[12..32].copy_from_slice(value.0.as_bytes()); let stark_felt = starknet_api::hash::StarkFelt::new(bytes).expect("valid slice for stark felt"); - stark_felt.into() + to_felt(stark_felt) } pub fn to_exec_info(exec_info: TransactionExecutionInfo) -> TxExecInfo { @@ -581,10 +584,10 @@ fn to_call_info(call: CallInfo) -> trace::CallInfo { let contract_address = to_address(call.call.storage_address); let caller_address = to_address(call.call.caller_address); let code_address = call.call.code_address.map(to_address); - let class_hash = call.call.class_hash.map(|a| a.0.into()); - let entry_point_selector = call.call.entry_point_selector.0.into(); - let calldata = call.call.calldata.0.iter().map(|f| (*f).into()).collect(); - let retdata = call.execution.retdata.0.into_iter().map(|f| f.into()).collect(); + let class_hash = call.call.class_hash.map(|a| to_felt(a.0)); + let entry_point_selector = to_felt(call.call.entry_point_selector.0); + let calldata = call.call.calldata.0.iter().map(|f| to_felt(*f)).collect(); + let retdata = call.execution.retdata.0.into_iter().map(to_felt).collect(); let builtin_counter = call.resources.builtin_instance_counter; let execution_resources = trace::ExecutionResources { @@ -610,8 +613,8 @@ fn to_call_info(call: CallInfo) -> trace::CallInfo { EntryPointType::Constructor => trace::EntryPointType::Constructor, }; - let storage_read_values = call.storage_read_values.into_iter().map(|f| f.into()).collect(); - let storg_keys = call.accessed_storage_keys.into_iter().map(|k| (*k.0.key()).into()).collect(); + let storage_read_values = call.storage_read_values.into_iter().map(to_felt).collect(); + let storg_keys = call.accessed_storage_keys.into_iter().map(|k| to_felt(*k.0.key())).collect(); let inner_calls = call.inner_calls.into_iter().map(to_call_info).collect(); trace::CallInfo { @@ -638,8 +641,8 @@ fn to_call_info(call: CallInfo) -> trace::CallInfo { fn to_ordered_event(e: OrderedEvent) -> event::OrderedEvent { event::OrderedEvent { order: e.order as u64, - keys: e.event.keys.into_iter().map(|f| f.0.into()).collect(), - data: e.event.data.0.into_iter().map(FieldElement::from).collect(), + keys: e.event.keys.iter().map(|f| to_felt(f.0)).collect(), + data: e.event.data.0.into_iter().map(to_felt).collect(), } } @@ -649,10 +652,18 @@ fn to_l2_l1_messages( ) -> message::OrderedL2ToL1Message { let order = m.order as u64; let to_address = starknet_api_ethaddr_to_felt(m.message.to_address); - let payload = m.message.payload.0.into_iter().map(FieldElement::from).collect(); + let payload = m.message.payload.0.into_iter().map(to_felt).collect(); message::OrderedL2ToL1Message { order, from_address, to_address, payload } } +pub fn to_stark_felt(value: FieldElement) -> StarkFelt { + StarkFelt::new(value.to_bytes_be()).expect("can convert from field element") +} + +pub fn to_felt(value: StarkFelt) -> FieldElement { + FieldElement::from_bytes_be_slice(value.bytes()) +} + #[cfg(test)] mod tests { @@ -660,12 +671,36 @@ mod tests { use katana_cairo::cairo_vm::vm::runners::cairo_runner::ExecutionResources; use katana_primitives::chain::{ChainId, NamedChainId}; + use katana_primitives::felt::FieldElement; use starknet_api::core::EntryPointSelector; use starknet_api::hash::StarkFelt; use starknet_api::stark_felt; use starknet_api::transaction::{EventContent, EventData, EventKey}; use super::*; + use crate::implementation::blockifier::utils; + + #[test] + fn test_to_stark_felt() { + let field_element = FieldElement::from_hex("0x1234567890abcdef").unwrap(); + let stark_felt = to_stark_felt(field_element); + assert_eq!(stark_felt, StarkFelt::try_from("0x1234567890abcdef").unwrap()); + } + + #[test] + fn test_to_felt() { + let stark_felt = StarkFelt::try_from("0xabcdef1234567890").unwrap(); + let field_element = to_felt(stark_felt); + assert_eq!(field_element, FieldElement::from_hex("0xabcdef1234567890").unwrap()); + } + + #[test] + fn test_roundtrip_felt_conversion() { + let original_felt = FieldElement::from_hex("0x123456789abcdef0").unwrap(); + let stark_felt = to_stark_felt(original_felt); + let roundtrip_felt = to_felt(stark_felt); + assert_eq!(original_felt, roundtrip_felt); + } #[test] fn convert_chain_id() { @@ -748,12 +783,12 @@ mod tests { let expected_contract_address = to_address(call.call.storage_address); let expected_caller_address = to_address(call.call.caller_address); let expected_code_address = call.call.code_address.map(to_address); - let expected_class_hash = call.call.class_hash.map(|a| a.0.into()); - let expected_entry_point_selector = call.call.entry_point_selector.0.into(); + let expected_class_hash = call.call.class_hash.map(|c| to_felt(c.0)); + let expected_entry_point_selector = to_felt(call.call.entry_point_selector.0); let expected_calldata: Vec = - call.call.calldata.0.iter().map(|f| (*f).into()).collect(); + call.call.calldata.0.iter().map(|f| to_felt(*f)).collect(); let expected_retdata: Vec = - call.execution.retdata.0.iter().map(|f| (*f).into()).collect(); + call.execution.retdata.0.iter().map(|f| to_felt(*f)).collect(); let builtin_counter = call.resources.builtin_instance_counter.clone(); let expected_execution_resources = trace::ExecutionResources { @@ -784,9 +819,9 @@ mod tests { }; let expected_storage_read_values: Vec = - call.storage_read_values.iter().map(|f| (*f).into()).collect(); + call.storage_read_values.iter().map(|v| utils::to_felt(*v)).collect(); let expected_storage_keys: HashSet = - call.accessed_storage_keys.iter().map(|k| (*k.0.key()).into()).collect(); + call.accessed_storage_keys.iter().map(|k| utils::to_felt(*k.0.key())).collect(); let expected_inner_calls: Vec<_> = call.inner_calls.clone().into_iter().map(to_call_info).collect(); diff --git a/crates/katana/executor/tests/executor.rs b/crates/katana/executor/tests/executor.rs index 6e1bbf46a0..a0de300f90 100644 --- a/crates/katana/executor/tests/executor.rs +++ b/crates/katana/executor/tests/executor.rs @@ -223,7 +223,7 @@ fn test_executor_with_valid_blocks_impl( let actual_storage_value_4_1 = state_provider .storage( deployed_contract.into(), - get_storage_var_address("ERC20_total_supply", &[]).unwrap() + 1u8.into(), + get_storage_var_address("ERC20_total_supply", &[]).unwrap() + FieldElement::ONE, ) .unwrap(); let actual_storage_value_5 = state_provider diff --git a/crates/katana/executor/tests/fixtures/transaction.rs b/crates/katana/executor/tests/fixtures/transaction.rs index 450df62e16..f804cca858 100644 --- a/crates/katana/executor/tests/fixtures/transaction.rs +++ b/crates/katana/executor/tests/fixtures/transaction.rs @@ -44,7 +44,7 @@ pub fn invoke_executable_tx( calldata: vec![felt!("0x1"), felt!("0x99"), felt!("0x0")], }]; - let tx = account.execute(calls).nonce(nonce).max_fee(max_fee).prepared().unwrap(); + let tx = account.execute_v1(calls).nonce(nonce).max_fee(max_fee).prepared().unwrap(); let mut broadcasted_tx = tokio::runtime::Builder::new_current_thread() .enable_all() @@ -54,14 +54,13 @@ pub fn invoke_executable_tx( .unwrap(); if !signed { - match broadcasted_tx { - BroadcastedInvokeTransaction::V1(ref mut tx) => tx.signature = vec![], - BroadcastedInvokeTransaction::V3(ref mut tx) => tx.signature = vec![], - } + broadcasted_tx.signature = vec![] } - let tx = katana_rpc_types::transaction::BroadcastedInvokeTx(broadcasted_tx) - .into_tx_with_chain_id(chain_id); + let tx = katana_rpc_types::transaction::BroadcastedInvokeTx(BroadcastedInvokeTransaction::V1( + broadcasted_tx, + )) + .into_tx_with_chain_id(chain_id); ExecutableTxWithHash::new(tx.into()) } diff --git a/crates/katana/primitives/Cargo.toml b/crates/katana/primitives/Cargo.toml index 6a4e1ed8c3..880ea906db 100644 --- a/crates/katana/primitives/Cargo.toml +++ b/crates/katana/primitives/Cargo.toml @@ -11,11 +11,12 @@ anyhow.workspace = true base64.workspace = true derive_more.workspace = true lazy_static.workspace = true +num-traits.workspace = true rand = { workspace = true, features = [ "small_rng" ] } serde.workspace = true serde_json.workspace = true serde_with.workspace = true -starknet-crypto = "0.6.1" +starknet-crypto.workspace = true starknet.workspace = true strum.workspace = true strum_macros.workspace = true diff --git a/crates/katana/primitives/src/chain.rs b/crates/katana/primitives/src/chain.rs index ec1c2d6f77..ecce9bd794 100644 --- a/crates/katana/primitives/src/chain.rs +++ b/crates/katana/primitives/src/chain.rs @@ -1,5 +1,8 @@ -use starknet::core::types::{FieldElement, FromStrError}; use starknet::core::utils::{cairo_short_string_to_felt, CairoShortStringToFeltError}; +use starknet::macros::short_string; + +use crate::felt::FromStrError; +use crate::FieldElement; /// Known chain ids that has been assigned a name. #[derive(Debug, Clone, Copy, PartialEq, Eq, strum_macros::Display)] @@ -12,28 +15,13 @@ pub enum NamedChainId { impl NamedChainId { /// `SN_MAIN` in ASCII - pub const SN_MAIN: FieldElement = FieldElement::from_mont([ - 0xf596341657d6d657, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0x6f9757bd5443bc6, - ]); + pub const SN_MAIN: FieldElement = short_string!("SN_MAIN"); /// `SN_GOERLI` in ASCII - pub const SN_GOERLI: FieldElement = FieldElement::from_mont([ - 0x3417161755cc97b2, - 0xfffffffffffff596, - 0xffffffffffffffff, - 0x588778cb29612d1, - ]); + pub const SN_GOERLI: FieldElement = short_string!("SN_GOERLI"); /// `SN_SEPOLIA` in ASCII - pub const SN_SEPOLIA: FieldElement = FieldElement::from_mont([ - 0x159755f62c97a933, - 0xfffffffffff59634, - 0xffffffffffffffff, - 0x70cb558f6123c62, - ]); + pub const SN_SEPOLIA: FieldElement = short_string!("SN_SEPOLIA"); /// Returns the id of the chain. It is the ASCII representation of a predefined string /// constants. @@ -108,7 +96,7 @@ impl ChainId { /// Cairo short string. pub fn parse(s: &str) -> Result { let id = if s.starts_with("0x") { - FieldElement::from_hex_be(s)? + FieldElement::from_hex(s)? } else { cairo_short_string_to_felt(s)? }; diff --git a/crates/katana/primitives/src/conversion/rpc.rs b/crates/katana/primitives/src/conversion/rpc.rs index 25ec978a31..a21a47e7c2 100644 --- a/crates/katana/primitives/src/conversion/rpc.rs +++ b/crates/katana/primitives/src/conversion/rpc.rs @@ -47,7 +47,7 @@ pub fn legacy_inner_to_rpc_class( .iter() .map(|e| LegacyContractEntryPoint { offset: e.offset.0 as u64, - selector: FieldElement::from(e.selector.0), + selector: FieldElement::from_bytes_be_slice(e.selector.0.bytes()), }) .collect::>()) } @@ -149,7 +149,7 @@ pub fn flattened_sierra_to_compiled_class( let sierra = SierraProgram { program, entry_points_by_type }; let casm = CasmContractClass::from_contract_class(class, true, usize::MAX)?; - let compiled_hash = FieldElement::from_bytes_be(&casm.compiled_class_hash().to_be_bytes())?; + let compiled_hash = FieldElement::from_bytes_be(&casm.compiled_class_hash().to_be_bytes()); let class = crate::class::CompiledClass::Class(SierraCompiledClass { casm, sierra }); Ok((class_hash, compiled_hash, class)) diff --git a/crates/katana/primitives/src/genesis/allocation.rs b/crates/katana/primitives/src/genesis/allocation.rs index 5ae6f11cba..c267fee0fe 100644 --- a/crates/katana/primitives/src/genesis/allocation.rs +++ b/crates/katana/primitives/src/genesis/allocation.rs @@ -269,7 +269,7 @@ impl DevAllocationsGenerator { private_key_bytes[0] %= 0x8; seed = private_key_bytes; - let private_key = FieldElement::from_bytes_be(&private_key_bytes).unwrap(); + let private_key = FieldElement::from_bytes_be(&private_key_bytes); DevGenesisAccount::new_with_balance(private_key, self.class_hash, self.balance) }) .collect() diff --git a/crates/katana/primitives/src/genesis/constant.rs b/crates/katana/primitives/src/genesis/constant.rs index affd6890ce..273e9ec365 100644 --- a/crates/katana/primitives/src/genesis/constant.rs +++ b/crates/katana/primitives/src/genesis/constant.rs @@ -9,83 +9,51 @@ use crate::FieldElement; /// The default universal deployer contract address. /// Corresponds to 0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf -pub const DEFAULT_UDC_ADDRESS: ContractAddress = ContractAddress(FieldElement::from_mont([ - 15144800532519055890, - 15685625669053253235, - 9333317513348225193, - 121672436446604875, -])); +pub const DEFAULT_UDC_ADDRESS: ContractAddress = + ContractAddress(felt!("0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf")); /// The default fee token contract address. /// Corresponds to 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 -pub const DEFAULT_FEE_TOKEN_ADDRESS: ContractAddress = ContractAddress(FieldElement::from_mont([ - 4380532846569209554, - 17839402928228694863, - 17240401758547432026, - 418961398025637529, -])); +pub const DEFAULT_FEE_TOKEN_ADDRESS: ContractAddress = + ContractAddress(felt!("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7")); /// The standard storage address for `public key` in OpenZeppelin account contract. /// Corresponds to keccak("Account_public_key") == /// 0x1379ac0624b939ceb9dede92211d7db5ee174fe28be72245b0a1a2abd81c98f -pub const OZ_ACCOUNT_CONTRACT_PUBKEY_STORAGE_SLOT: StorageKey = FieldElement::from_mont([ - 1846274790623946671, - 4425861538928837650, - 5862944509338977095, - 333410775162302292, -]); +pub const OZ_ACCOUNT_CONTRACT_PUBKEY_STORAGE_SLOT: StorageKey = + felt!("0x1379ac0624b939ceb9dede92211d7db5ee174fe28be72245b0a1a2abd81c98f"); /// The standard storage address for `ERC20_name` in ERC20 contract. /// Corresponds to keccak("ERC20_name") == /// 0x0341c1bdfd89f69748aa00b5742b03adbffd79b8e80cab5c50d91cd8c2a79be1 -pub const ERC20_NAME_STORAGE_SLOT: StorageKey = FieldElement::from_mont([ - 14245373332046594057, - 5531369627875559154, - 7076950148258849527, - 42006782206471821, -]); +pub const ERC20_NAME_STORAGE_SLOT: StorageKey = + felt!("0x0341c1bdfd89f69748aa00b5742b03adbffd79b8e80cab5c50d91cd8c2a79be1"); /// The standard storage address for `ERC20_symbol` in ERC20 contract. /// Corresponds to keccak("ERC20_symbol") == /// 0x00b6ce5410fca59d078ee9b2a4371a9d684c530d697c64fbef0ae6d5e8f0ac72 -pub const ERC20_SYMBOL_STORAGE_SLOT: StorageKey = FieldElement::from_mont([ - 3529993699915368059, - 8508842680170426599, - 11308853324722862885, - 140787116910459578, -]); +pub const ERC20_SYMBOL_STORAGE_SLOT: StorageKey = + felt!("0x00b6ce5410fca59d078ee9b2a4371a9d684c530d697c64fbef0ae6d5e8f0ac72"); /// The standard storage address for `ERC20_decimals` in ERC20 contract. /// Corresponds to keccak("ERC20_decimals") == /// 0x01f0d4aa99431d246bac9b8e48c33e888245b15e9678f64f9bdfc8823dc8f979 -pub const ERC20_DECIMAL_STORAGE_SLOT: StorageKey = FieldElement::from_mont([ - 1858031281331058897, - 9678267618682904527, - 9433316002840757017, - 17823060228645335, -]); +pub const ERC20_DECIMAL_STORAGE_SLOT: StorageKey = + felt!("0x01f0d4aa99431d246bac9b8e48c33e888245b15e9678f64f9bdfc8823dc8f979"); /// The standard storage address for `ERC20_total_supply` in ERC20 contract. /// Corresponds to keccak("ERC20_total_supply") == /// 0x110e2f729c9c2b988559994a3daccd838cf52faf88e18101373e67dd061455a -pub const ERC20_TOTAL_SUPPLY_STORAGE_SLOT: StorageKey = FieldElement::from_mont([ - 700008926920971440, - 9682182591019764224, - 8184857487847920423, - 218835885563775175, -]); +pub const ERC20_TOTAL_SUPPLY_STORAGE_SLOT: StorageKey = + felt!("0x110e2f729c9c2b988559994a3daccd838cf52faf88e18101373e67dd061455a"); /// The default fee token balance for dev accounts at genesis. pub const DEFAULT_PREFUNDED_ACCOUNT_BALANCE: u128 = 10 * u128::pow(10, 21); /// The class hash of DEFAULT_LEGACY_ERC20_CONTRACT_CASM. /// Corresponds to 0x02a8846878b6ad1f54f6ba46f5f40e11cee755c677f130b2c4b60566c9003f1f -pub const DEFAULT_LEGACY_ERC20_CONTRACT_CLASS_HASH: ClassHash = FieldElement::from_mont([ - 5063404709606896214, - 17264546324508274858, - 2617848339092803640, - 396742056646423680, -]); +pub const DEFAULT_LEGACY_ERC20_CONTRACT_CLASS_HASH: ClassHash = + felt!("0x02a8846878b6ad1f54f6ba46f5f40e11cee755c677f130b2c4b60566c9003f1f"); /// The compiled class hash of DEFAULT_LEGACY_ERC20_CONTRACT_CASM. pub const DEFAULT_LEGACY_ERC20_CONTRACT_COMPILED_CLASS_HASH: CompiledClassHash = @@ -93,34 +61,21 @@ pub const DEFAULT_LEGACY_ERC20_CONTRACT_COMPILED_CLASS_HASH: CompiledClassHash = /// The class hash of DEFAULT_LEGACY_UDC_CASM. /// Corresponds to 0x07b3e05f48f0c69e4a65ce5e076a66271a527aff2c34ce1083ec6e1526997a69 -pub const DEFAULT_LEGACY_UDC_CLASS_HASH: ClassHash = FieldElement::from_mont([ - 13364470047046544565, - 11148922744554181574, - 8853940111481564631, - 179653587345909319, -]); +pub const DEFAULT_LEGACY_UDC_CLASS_HASH: ClassHash = + felt!("0x07b3e05f48f0c69e4a65ce5e076a66271a527aff2c34ce1083ec6e1526997a69"); /// The compiled class hash of DEFAULT_LEGACY_UDC_CASM. pub const DEFAULT_LEGACY_UDC_COMPILED_CLASS_HASH: CompiledClassHash = DEFAULT_LEGACY_UDC_CLASS_HASH; /// The class hash of DEFAULT_OZ_ACCOUNT_CONTRACT. /// Corresponds to 0x05400e90f7e0ae78bd02c77cd75527280470e2fe19c54970dd79dc37a9d3645c -pub const DEFAULT_OZ_ACCOUNT_CONTRACT_CLASS_HASH: ClassHash = FieldElement::from_mont([ - 8460675502047588988, - 17729791148444280953, - 7171298771336181387, - 292243705759714441, -]); +pub const DEFAULT_OZ_ACCOUNT_CONTRACT_CLASS_HASH: ClassHash = + felt!("0x05400e90f7e0ae78bd02c77cd75527280470e2fe19c54970dd79dc37a9d3645c"); /// The compiled class hash of DEFAULT_OZ_ACCOUNT_CONTRACT. /// Corresponds to 0x016c6081eb34ad1e0c5513234ed0c025b3c7f305902d291bad534cd6474c85bc pub const DEFAULT_OZ_ACCOUNT_CONTRACT_COMPILED_CLASS_HASH: CompiledClassHash = - FieldElement::from_mont([ - 18006730038010879891, - 12016093095874787527, - 4539661479059859683, - 190499602541245794, - ]); + felt!("0x016c6081eb34ad1e0c5513234ed0c025b3c7f305902d291bad534cd6474c85bc"); pub const CONTROLLER_ACCOUNT_CONTRACT_CLASS_HASH: ClassHash = felt!("0xCC"); diff --git a/crates/katana/primitives/src/genesis/json.rs b/crates/katana/primitives/src/genesis/json.rs index d1fa24bfd6..eef85a0d7a 100644 --- a/crates/katana/primitives/src/genesis/json.rs +++ b/crates/katana/primitives/src/genesis/json.rs @@ -20,7 +20,6 @@ use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; use starknet::core::types::contract::legacy::LegacyContractClass; use starknet::core::types::contract::{ComputeClassHashError, JsonError}; -use starknet::core::types::FromByteArrayError; use super::allocation::{ DevGenesisAccount, GenesisAccount, GenesisAccountAlloc, GenesisContractAlloc, @@ -210,9 +209,6 @@ pub enum GenesisJsonError { #[error(transparent)] ComputeClassHash(#[from] ComputeClassHashError), - #[error(transparent)] - ConversionError(#[from] FromByteArrayError), - #[error(transparent)] SierraCompilation(#[from] StarknetSierraCompilationError), @@ -363,7 +359,7 @@ impl TryFrom for Genesis { ( class_hash, - FieldElement::from_bytes_be(&compiled_hash)?, + FieldElement::from_bytes_be(&compiled_hash), Some(Arc::new(sierra.flatten()?)), Arc::new(CompiledClass::Class(class)), ) diff --git a/crates/katana/primitives/src/genesis/mod.rs b/crates/katana/primitives/src/genesis/mod.rs index 78e817801d..d65ad481d7 100644 --- a/crates/katana/primitives/src/genesis/mod.rs +++ b/crates/katana/primitives/src/genesis/mod.rs @@ -204,7 +204,7 @@ impl Genesis { // the storage address of low u128 of the balance let low_bal_storage_var = bal_base_storage_var; // the storage address of high u128 of the balance - let high_bal_storage_var = bal_base_storage_var + 1u8.into(); + let high_bal_storage_var = bal_base_storage_var + FieldElement::ONE; fee_token_storage.insert(low_bal_storage_var, low); fee_token_storage.insert(high_bal_storage_var, high); @@ -222,7 +222,8 @@ impl Genesis { fee_token_storage.insert(ERC20_SYMBOL_STORAGE_SLOT, symbol); fee_token_storage.insert(ERC20_DECIMAL_STORAGE_SLOT, decimals); fee_token_storage.insert(ERC20_TOTAL_SUPPLY_STORAGE_SLOT, total_supply_low); - fee_token_storage.insert(ERC20_TOTAL_SUPPLY_STORAGE_SLOT + 1u8.into(), total_supply_high); + fee_token_storage + .insert(ERC20_TOTAL_SUPPLY_STORAGE_SLOT + FieldElement::ONE, total_supply_high); states .state_updates @@ -449,7 +450,8 @@ mod tests { fee_token_storage.insert(ERC20_SYMBOL_STORAGE_SLOT, symbol); fee_token_storage.insert(ERC20_DECIMAL_STORAGE_SLOT, decimals); fee_token_storage.insert(ERC20_TOTAL_SUPPLY_STORAGE_SLOT, total_supply_low); - fee_token_storage.insert(ERC20_TOTAL_SUPPLY_STORAGE_SLOT + 1u8.into(), total_supply_high); + fee_token_storage + .insert(ERC20_TOTAL_SUPPLY_STORAGE_SLOT + FieldElement::ONE, total_supply_high); for (address, alloc) in &allocations { if let Some(balance) = alloc.balance() { @@ -461,7 +463,7 @@ mod tests { // the storage address of low u128 of the balance let low_bal_storage_var = bal_base_storage_var; // the storage address of high u128 of the balance - let high_bal_storage_var = bal_base_storage_var + 1u8.into(); + let high_bal_storage_var = bal_base_storage_var + FieldElement::ONE; fee_token_storage.insert(low_bal_storage_var, low); fee_token_storage.insert(high_bal_storage_var, high); @@ -698,7 +700,7 @@ mod tests { Some(&total_supply_low) ); assert_eq!( - fee_token_storage.get(&(ERC20_TOTAL_SUPPLY_STORAGE_SLOT + 1u8.into())), + fee_token_storage.get(&(ERC20_TOTAL_SUPPLY_STORAGE_SLOT + FieldElement::ONE)), Some(&total_supply_high) ); @@ -720,7 +722,7 @@ mod tests { // the storage address of low u128 of the balance let low_bal_storage_var = bal_base_storage_var; // the storage address of high u128 of the balance - let high_bal_storage_var = bal_base_storage_var + 1u8.into(); + let high_bal_storage_var = bal_base_storage_var + FieldElement::ONE; assert_eq!(fee_token_storage.get(&low_bal_storage_var), Some(&low)); assert_eq!(fee_token_storage.get(&high_bal_storage_var), Some(&high)); @@ -740,7 +742,7 @@ mod tests { "total supply must be calculated from allocations balances correctly" ); assert_eq!( - fee_token_storage.get(&(ERC20_TOTAL_SUPPLY_STORAGE_SLOT + 1u8.into())), + fee_token_storage.get(&(ERC20_TOTAL_SUPPLY_STORAGE_SLOT + FieldElement::ONE)), Some(&actual_total_supply_high), "total supply must be calculated from allocations balances correctly" ); diff --git a/crates/katana/primitives/src/lib.rs b/crates/katana/primitives/src/lib.rs index de95663047..7accc01ceb 100644 --- a/crates/katana/primitives/src/lib.rs +++ b/crates/katana/primitives/src/lib.rs @@ -17,4 +17,8 @@ pub mod conversion; pub mod state; pub mod utils; -pub type FieldElement = starknet::core::types::FieldElement; +pub use felt::FieldElement; + +pub mod felt { + pub use starknet::core::types::{Felt as FieldElement, FromStrError}; +} diff --git a/crates/katana/primitives/src/utils/transaction.rs b/crates/katana/primitives/src/utils/transaction.rs index 0157c3a15c..94cc1b3458 100644 --- a/crates/katana/primitives/src/utils/transaction.rs +++ b/crates/katana/primitives/src/utils/transaction.rs @@ -6,43 +6,39 @@ use starknet_crypto::poseidon_hash_many; use crate::FieldElement; /// 2^ 128 -const QUERY_VERSION_OFFSET: FieldElement = FieldElement::from_mont([ - 18446744073700081665, - 17407, - 18446744073709551584, - 576460752142434320, -]); +const QUERY_VERSION_OFFSET: FieldElement = + FieldElement::from_raw([576460752142434320, 18446744073709551584, 17407, 18446744073700081665]); /// Cairo string for "invoke" -const PREFIX_INVOKE: FieldElement = FieldElement::from_mont([ - 18443034532770911073, +const PREFIX_INVOKE: FieldElement = FieldElement::from_raw([ + 513398556346534256, 18446744073709551615, 18446744073709551615, - 513398556346534256, + 18443034532770911073, ]); /// Cairo string for "declare" -const PREFIX_DECLARE: FieldElement = FieldElement::from_mont([ - 17542456862011667323, +const PREFIX_DECLARE: FieldElement = FieldElement::from_raw([ + 191557713328401194, 18446744073709551615, 18446744073709551615, - 191557713328401194, + 17542456862011667323, ]); /// Cairo string for "deploy_account" -const PREFIX_DEPLOY_ACCOUNT: FieldElement = FieldElement::from_mont([ - 3350261884043292318, - 18443211694809419988, - 18446744073709551615, +const PREFIX_DEPLOY_ACCOUNT: FieldElement = FieldElement::from_raw([ 461298303000467581, + 18446744073709551615, + 18443211694809419988, + 3350261884043292318, ]); /// Cairo string for "l1_handler" -const PREFIX_L1_HANDLER: FieldElement = FieldElement::from_mont([ - 1365666230910873368, - 18446744073708665300, - 18446744073709551615, +const PREFIX_L1_HANDLER: FieldElement = FieldElement::from_raw([ 157895833347907735, + 18446744073709551615, + 18446744073708665300, + 1365666230910873368, ]); /// Compute the hash of a V1 DeployAccount transaction. @@ -306,7 +302,7 @@ fn encode_gas_bound(name: &[u8], bound: &ResourceBounds) -> FieldElement { max_amount.copy_from_slice(&bound.max_amount.to_be_bytes()); max_price.copy_from_slice(&bound.max_price_per_unit.to_be_bytes()); - FieldElement::from_bytes_be(&buffer).expect("Packed resource should fit into felt") + FieldElement::from_bytes_be(&buffer) } fn hash_fee_fields( @@ -332,11 +328,26 @@ fn encode_da_mode( #[cfg(test)] mod tests { + use num_traits::ToPrimitive; use starknet::core::chain_id; - use starknet::macros::felt; + use starknet::macros::{felt, short_string}; use super::*; + #[test] + fn test_query_version_offset() { + // 2^ 128 + assert_eq!(QUERY_VERSION_OFFSET, FieldElement::TWO.pow(128u8)); + } + + #[test] + fn test_prefix_constants() { + assert_eq!(PREFIX_INVOKE, short_string!("invoke")); + assert_eq!(PREFIX_DECLARE, short_string!("declare")); + assert_eq!(PREFIX_DEPLOY_ACCOUNT, short_string!("deploy_account")); + assert_eq!(PREFIX_L1_HANDLER, short_string!("l1_handler")); + } + #[test] fn test_compute_deploy_account_v1_tx_hash() { // Starknet mainnet tx hash: https://voyager.online/tx/0x3d013d17c20a5db05d5c2e06c948a4e0bf5ea5b851b15137316533ec4788b6b @@ -363,7 +374,7 @@ mod tests { &constructor_calldata, class_hash, salt, - max_fee.try_into().unwrap(), + max_fee.to_u128().unwrap(), chain_id, nonce, false, diff --git a/crates/katana/rpc/rpc-api/src/starknet.rs b/crates/katana/rpc/rpc-api/src/starknet.rs index 9158fa1724..2f496462ce 100644 --- a/crates/katana/rpc/rpc-api/src/starknet.rs +++ b/crates/katana/rpc/rpc-api/src/starknet.rs @@ -4,11 +4,12 @@ use katana_primitives::block::{BlockIdOrTag, BlockNumber}; use katana_primitives::transaction::TxHash; use katana_primitives::FieldElement; use katana_rpc_types::block::{ - BlockHashAndNumber, BlockTxCount, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, + BlockHashAndNumber, BlockTxCount, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes, + MaybePendingBlockWithTxs, }; use katana_rpc_types::event::{EventFilterWithPage, EventsPage}; use katana_rpc_types::message::MsgFromL1; -use katana_rpc_types::receipt::MaybePendingTxReceipt; +use katana_rpc_types::receipt::TxReceiptWithBlockInfo; use katana_rpc_types::state_update::StateUpdate; use katana_rpc_types::transaction::{ BroadcastedDeclareTx, BroadcastedDeployAccountTx, BroadcastedInvokeTx, BroadcastedTx, @@ -21,7 +22,7 @@ use katana_rpc_types::{ use starknet::core::types::{SimulatedTransaction, TransactionStatus}; /// The currently supported version of the Starknet JSON-RPC specification. -pub const RPC_SPEC_VERSION: &str = "0.6.0"; +pub const RPC_SPEC_VERSION: &str = "0.7.1"; /// Starknet JSON-RPC APIs: #[cfg_attr(not(feature = "client"), rpc(server, namespace = "starknet"))] @@ -44,6 +45,13 @@ pub trait StarknetApi { #[method(name = "getBlockWithTxs")] async fn block_with_txs(&self, block_id: BlockIdOrTag) -> RpcResult; + /// Get block information with full transactions and receipts given the block id. + #[method(name = "getBlockWithReceipts")] + async fn block_with_receipts( + &self, + block_id: BlockIdOrTag, + ) -> RpcResult; + /// Get the information about the result of executing the requested block. #[method(name = "getStateUpdate")] async fn state_update(&self, block_id: BlockIdOrTag) -> RpcResult; @@ -79,7 +87,7 @@ pub trait StarknetApi { async fn transaction_receipt( &self, transaction_hash: TxHash, - ) -> RpcResult; + ) -> RpcResult; /// Get the contract class definition in the given block associated with the given hash. #[method(name = "getClass")] diff --git a/crates/katana/rpc/rpc-types-builder/Cargo.toml b/crates/katana/rpc/rpc-types-builder/Cargo.toml index d53783e828..8caf945948 100644 --- a/crates/katana/rpc/rpc-types-builder/Cargo.toml +++ b/crates/katana/rpc/rpc-types-builder/Cargo.toml @@ -11,6 +11,6 @@ katana-executor.workspace = true katana-primitives.workspace = true katana-provider.workspace = true katana-rpc-types.workspace = true +starknet.workspace = true anyhow.workspace = true -starknet.workspace = true diff --git a/crates/katana/rpc/rpc-types-builder/src/block.rs b/crates/katana/rpc/rpc-types-builder/src/block.rs index cd16a71f94..537da569d0 100644 --- a/crates/katana/rpc/rpc-types-builder/src/block.rs +++ b/crates/katana/rpc/rpc-types-builder/src/block.rs @@ -1,7 +1,8 @@ use katana_primitives::block::BlockHashOrNumber; use katana_provider::traits::block::{BlockHashProvider, BlockProvider, BlockStatusProvider}; +use katana_provider::traits::transaction::ReceiptProvider; use katana_provider::ProviderResult; -use katana_rpc_types::block::{BlockWithTxHashes, BlockWithTxs}; +use katana_rpc_types::block::{BlockWithReceipts, BlockWithTxHashes, BlockWithTxs}; /// A builder for building RPC block types. pub struct BlockBuilder

{ @@ -17,7 +18,7 @@ impl

BlockBuilder

{ impl

BlockBuilder

where - P: BlockProvider + BlockHashProvider, + P: BlockProvider + BlockHashProvider + ReceiptProvider, { pub fn build(self) -> ProviderResult> { let Some(hash) = BlockHashProvider::block_hash_by_id(&self.provider, self.block_id)? else { @@ -44,4 +45,19 @@ where Ok(Some(BlockWithTxHashes::new(hash, block, finality_status))) } + + pub fn build_with_receipts(self) -> ProviderResult> { + let Some(block) = BlockProvider::block(&self.provider, self.block_id)? else { + return Ok(None); + }; + + let finality_status = BlockStatusProvider::block_status(&self.provider, self.block_id)? + .expect("should exist if block exists"); + let receipts = ReceiptProvider::receipts_by_block(&self.provider, self.block_id)? + .expect("should exist if block exists"); + + let receipts_with_txs = block.body.into_iter().zip(receipts); + + Ok(Some(BlockWithReceipts::new(block.header, finality_status, receipts_with_txs))) + } } diff --git a/crates/katana/rpc/rpc-types-builder/src/receipt.rs b/crates/katana/rpc/rpc-types-builder/src/receipt.rs index 36dac22825..d46e85c389 100644 --- a/crates/katana/rpc/rpc-types-builder/src/receipt.rs +++ b/crates/katana/rpc/rpc-types-builder/src/receipt.rs @@ -2,7 +2,7 @@ use katana_primitives::transaction::TxHash; use katana_provider::traits::transaction::{ ReceiptProvider, TransactionProvider, TransactionStatusProvider, }; -use katana_rpc_types::receipt::TxReceipt; +use katana_rpc_types::receipt::{ReceiptBlock, TxReceiptWithBlockInfo}; /// A builder for building RPC transaction receipt types. pub struct ReceiptBuilder

{ @@ -20,11 +20,10 @@ impl

ReceiptBuilder

where P: TransactionProvider + TransactionStatusProvider + ReceiptProvider, { - pub fn build(&self) -> anyhow::Result> { + pub fn build(&self) -> anyhow::Result> { let receipt = ReceiptProvider::receipt_by_hash(&self.provider, self.transaction_hash)?; let Some(receipt) = receipt else { return Ok(None) }; - let transaction_hash = self.transaction_hash; let (block_number, block_hash) = TransactionProvider::transaction_block_num_and_hash( &self.provider, self.transaction_hash, @@ -35,10 +34,11 @@ where TransactionStatusProvider::transaction_status(&self.provider, self.transaction_hash)? .expect("must exist"); - Ok(Some(TxReceipt::new( - transaction_hash, - block_number, - block_hash, + let block = ReceiptBlock::Block { block_hash, block_number }; + + Ok(Some(TxReceiptWithBlockInfo::new( + block, + self.transaction_hash, finality_status, receipt, ))) diff --git a/crates/katana/rpc/rpc-types/Cargo.toml b/crates/katana/rpc/rpc-types/Cargo.toml index bc351aa0fc..d792d682ef 100644 --- a/crates/katana/rpc/rpc-types/Cargo.toml +++ b/crates/katana/rpc/rpc-types/Cargo.toml @@ -16,6 +16,7 @@ anyhow.workspace = true derive_more.workspace = true futures.workspace = true jsonrpsee = { workspace = true, features = [ "server" ] } +num-traits.workspace = true serde.workspace = true serde_json.workspace = true serde_with.workspace = true diff --git a/crates/katana/rpc/rpc-types/src/block.rs b/crates/katana/rpc/rpc-types/src/block.rs index 0e274906aa..a9c24e642b 100644 --- a/crates/katana/rpc/rpc-types/src/block.rs +++ b/crates/katana/rpc/rpc-types/src/block.rs @@ -1,7 +1,15 @@ -use katana_primitives::block::{Block, BlockHash, BlockNumber, FinalityStatus, PartialHeader}; +use katana_primitives::block::{ + Block, BlockHash, BlockNumber, FinalityStatus, Header, PartialHeader, +}; +use katana_primitives::receipt::Receipt; use katana_primitives::transaction::{TxHash, TxWithHash}; use serde::{Deserialize, Serialize}; -use starknet::core::types::{BlockStatus, ResourcePrice}; +use starknet::core::types::{ + BlockStatus, L1DataAvailabilityMode, ResourcePrice, TransactionWithReceipt, +}; + +use crate::receipt::TxReceipt; +use crate::transaction::Tx; pub type BlockTxCount = u64; @@ -33,6 +41,12 @@ impl BlockWithTxs { FinalityStatus::AcceptedOnL1 => BlockStatus::AcceptedOnL1, FinalityStatus::AcceptedOnL2 => BlockStatus::AcceptedOnL2, }, + + l1_da_mode: L1DataAvailabilityMode::Calldata, + l1_data_gas_price: ResourcePrice { + price_in_fri: Default::default(), + price_in_wei: Default::default(), + }, }) } } @@ -58,6 +72,12 @@ impl PendingBlockWithTxs { parent_hash: header.parent_hash, starknet_version: header.version.to_string(), sequencer_address: header.sequencer_address.into(), + + l1_da_mode: L1DataAvailabilityMode::Calldata, + l1_data_gas_price: ResourcePrice { + price_in_fri: Default::default(), + price_in_wei: Default::default(), + }, }) } } @@ -98,6 +118,12 @@ impl BlockWithTxHashes { FinalityStatus::AcceptedOnL1 => BlockStatus::AcceptedOnL1, FinalityStatus::AcceptedOnL2 => BlockStatus::AcceptedOnL2, }, + + l1_da_mode: L1DataAvailabilityMode::Calldata, + l1_data_gas_price: ResourcePrice { + price_in_fri: Default::default(), + price_in_wei: Default::default(), + }, }) } } @@ -120,6 +146,12 @@ impl PendingBlockWithTxHashes { parent_hash: header.parent_hash, starknet_version: header.version.to_string(), sequencer_address: header.sequencer_address.into(), + + l1_da_mode: L1DataAvailabilityMode::Calldata, + l1_data_gas_price: ResourcePrice { + price_in_fri: Default::default(), + price_in_wei: Default::default(), + }, }) } } @@ -146,3 +178,95 @@ impl From<(BlockHash, BlockNumber)> for BlockHashAndNumber { Self::new(hash, number) } } + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(transparent)] +pub struct BlockWithReceipts(starknet::core::types::BlockWithReceipts); + +impl BlockWithReceipts { + pub fn new( + header: Header, + finality_status: FinalityStatus, + receipts: impl Iterator, + ) -> Self { + let l1_gas_price = ResourcePrice { + price_in_wei: header.gas_prices.eth.into(), + price_in_fri: header.gas_prices.strk.into(), + }; + + let transactions = receipts + .map(|(tx_with_hash, receipt)| { + let receipt = TxReceipt::new(tx_with_hash.hash, finality_status, receipt).0; + let transaction = Tx::from(tx_with_hash).0; + TransactionWithReceipt { transaction, receipt } + }) + .collect(); + + Self(starknet::core::types::BlockWithReceipts { + status: match finality_status { + FinalityStatus::AcceptedOnL1 => BlockStatus::AcceptedOnL1, + FinalityStatus::AcceptedOnL2 => BlockStatus::AcceptedOnL2, + }, + block_hash: header.parent_hash, + parent_hash: header.parent_hash, + block_number: header.number, + new_root: header.state_root, + timestamp: header.timestamp, + sequencer_address: header.sequencer_address.into(), + l1_gas_price, + l1_data_gas_price: ResourcePrice { + price_in_fri: Default::default(), + price_in_wei: Default::default(), + }, + l1_da_mode: L1DataAvailabilityMode::Calldata, + starknet_version: header.version.to_string(), + transactions, + }) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(transparent)] +pub struct PendingBlockWithReceipts(starknet::core::types::PendingBlockWithReceipts); + +impl PendingBlockWithReceipts { + pub fn new( + header: PartialHeader, + receipts: impl Iterator, + ) -> Self { + let l1_gas_price = ResourcePrice { + price_in_wei: header.gas_prices.eth.into(), + price_in_fri: header.gas_prices.strk.into(), + }; + + let transactions = receipts + .map(|(tx_with_hash, receipt)| { + let receipt = + TxReceipt::new(tx_with_hash.hash, FinalityStatus::AcceptedOnL2, receipt).0; + let transaction = Tx::from(tx_with_hash).0; + TransactionWithReceipt { transaction, receipt } + }) + .collect(); + + Self(starknet::core::types::PendingBlockWithReceipts { + transactions, + l1_gas_price, + timestamp: header.timestamp, + sequencer_address: header.sequencer_address.into(), + parent_hash: header.parent_hash, + l1_da_mode: L1DataAvailabilityMode::Calldata, + l1_data_gas_price: ResourcePrice { + price_in_fri: Default::default(), + price_in_wei: Default::default(), + }, + starknet_version: header.version.to_string(), + }) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum MaybePendingBlockWithReceipts { + Pending(PendingBlockWithReceipts), + Block(BlockWithReceipts), +} diff --git a/crates/katana/rpc/rpc-types/src/message.rs b/crates/katana/rpc/rpc-types/src/message.rs index 3ffa26566b..5014796104 100644 --- a/crates/katana/rpc/rpc-types/src/message.rs +++ b/crates/katana/rpc/rpc-types/src/message.rs @@ -16,7 +16,7 @@ impl MsgFromL1 { let message_hash = compute_l2_to_l1_message_hash( // This conversion will never fail bcs `from_address` is 20 bytes and the it will only // fail if the slice is > 32 bytes - FieldElement::from_byte_slice_be(self.0.from_address.as_bytes()).unwrap(), + FieldElement::from_bytes_be_slice(self.0.from_address.as_bytes()), self.0.to_address, &self.0.payload, ); diff --git a/crates/katana/rpc/rpc-types/src/receipt.rs b/crates/katana/rpc/rpc-types/src/receipt.rs index 6dd4ad5ecd..970f7f40fb 100644 --- a/crates/katana/rpc/rpc-types/src/receipt.rs +++ b/crates/katana/rpc/rpc-types/src/receipt.rs @@ -1,25 +1,23 @@ -use katana_primitives::block::{BlockHash, BlockNumber, FinalityStatus}; +use katana_primitives::block::FinalityStatus; use katana_primitives::fee::TxFeeInfo; use katana_primitives::receipt::{MessageToL1, Receipt, TxExecutionResources}; use katana_primitives::transaction::TxHash; use serde::{Deserialize, Serialize}; +pub use starknet::core::types::ReceiptBlock; use starknet::core::types::{ - DeclareTransactionReceipt, DeployAccountTransactionReceipt, ExecutionResult, FeePayment, - Hash256, InvokeTransactionReceipt, L1HandlerTransactionReceipt, - PendingDeclareTransactionReceipt, PendingDeployAccountTransactionReceipt, - PendingInvokeTransactionReceipt, PendingL1HandlerTransactionReceipt, PendingTransactionReceipt, - TransactionFinalityStatus, TransactionReceipt, + ComputationResources, DataAvailabilityResources, DataResources, DeclareTransactionReceipt, + DeployAccountTransactionReceipt, ExecutionResult, FeePayment, Hash256, + InvokeTransactionReceipt, L1HandlerTransactionReceipt, TransactionFinalityStatus, + TransactionReceipt, TransactionReceiptWithBlockInfo, }; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(transparent)] -pub struct TxReceipt(starknet::core::types::TransactionReceipt); +pub struct TxReceipt(pub(crate) starknet::core::types::TransactionReceipt); impl TxReceipt { pub fn new( transaction_hash: TxHash, - block_number: BlockNumber, - block_hash: BlockHash, finality_status: FinalityStatus, receipt: Receipt, ) -> Self { @@ -36,8 +34,6 @@ impl TxReceipt { TransactionReceipt::Invoke(InvokeTransactionReceipt { events, - block_hash, - block_number, messages_sent, finality_status, transaction_hash, @@ -58,8 +54,6 @@ impl TxReceipt { TransactionReceipt::Declare(DeclareTransactionReceipt { events, - block_hash, - block_number, messages_sent, finality_status, transaction_hash, @@ -80,8 +74,6 @@ impl TxReceipt { TransactionReceipt::L1Handler(L1HandlerTransactionReceipt { events, - block_hash, - block_number, messages_sent, finality_status, transaction_hash, @@ -103,8 +95,6 @@ impl TxReceipt { TransactionReceipt::DeployAccount(DeployAccountTransactionReceipt { events, - block_hash, - block_number, messages_sent, finality_status, transaction_hash, @@ -126,104 +116,17 @@ impl TxReceipt { #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(transparent)] -pub struct PendingTxReceipt(starknet::core::types::PendingTransactionReceipt); +pub struct TxReceiptWithBlockInfo(starknet::core::types::TransactionReceiptWithBlockInfo); -impl PendingTxReceipt { - pub fn new(transaction_hash: TxHash, receipt: Receipt) -> Self { - let receipt = match receipt { - Receipt::Invoke(rct) => { - let messages_sent = - rct.messages_sent.into_iter().map(|e| MsgToL1::from(e).0).collect(); - let events = rct.events.into_iter().map(|e| Event::from(e).0).collect(); - - PendingTransactionReceipt::Invoke(PendingInvokeTransactionReceipt { - transaction_hash, - events, - messages_sent, - actual_fee: to_rpc_fee(rct.fee), - execution_resources: ExecutionResources::from(rct.execution_resources).0, - execution_result: if let Some(reason) = rct.revert_error { - ExecutionResult::Reverted { reason } - } else { - ExecutionResult::Succeeded - }, - }) - } - - Receipt::Declare(rct) => { - let messages_sent = - rct.messages_sent.into_iter().map(|e| MsgToL1::from(e).0).collect(); - let events = rct.events.into_iter().map(|e| Event::from(e).0).collect(); - - PendingTransactionReceipt::Declare(PendingDeclareTransactionReceipt { - events, - transaction_hash, - messages_sent, - actual_fee: to_rpc_fee(rct.fee), - execution_resources: ExecutionResources::from(rct.execution_resources).0, - execution_result: if let Some(reason) = rct.revert_error { - ExecutionResult::Reverted { reason } - } else { - ExecutionResult::Succeeded - }, - }) - } - - Receipt::L1Handler(rct) => { - let messages_sent = - rct.messages_sent.into_iter().map(|e| MsgToL1::from(e).0).collect(); - let events = rct.events.into_iter().map(|e| Event::from(e).0).collect(); - - PendingTransactionReceipt::L1Handler(PendingL1HandlerTransactionReceipt { - transaction_hash, - events, - messages_sent, - actual_fee: to_rpc_fee(rct.fee), - execution_resources: ExecutionResources::from(rct.execution_resources).0, - message_hash: Hash256::from_bytes(rct.message_hash.0), - execution_result: if let Some(reason) = rct.revert_error { - ExecutionResult::Reverted { reason } - } else { - ExecutionResult::Succeeded - }, - }) - } - - Receipt::DeployAccount(rct) => { - let messages_sent = - rct.messages_sent.into_iter().map(|e| MsgToL1::from(e).0).collect(); - let events = rct.events.into_iter().map(|e| Event::from(e).0).collect(); - - PendingTransactionReceipt::DeployAccount(PendingDeployAccountTransactionReceipt { - transaction_hash, - events, - messages_sent, - actual_fee: to_rpc_fee(rct.fee), - contract_address: rct.contract_address.into(), - execution_resources: ExecutionResources::from(rct.execution_resources).0, - execution_result: if let Some(reason) = rct.revert_error { - ExecutionResult::Reverted { reason } - } else { - ExecutionResult::Succeeded - }, - }) - } - }; - - Self(receipt) - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(untagged)] -pub enum MaybePendingTxReceipt { - Receipt(TxReceipt), - Pending(PendingTxReceipt), -} - -impl From for TxReceipt { - fn from(receipt: starknet::core::types::TransactionReceipt) -> Self { - Self(receipt) +impl TxReceiptWithBlockInfo { + pub fn new( + block: ReceiptBlock, + transaction_hash: TxHash, + finality_status: FinalityStatus, + receipt: Receipt, + ) -> Self { + let receipt = TxReceipt::new(transaction_hash, finality_status, receipt).0; + Self(TransactionReceiptWithBlockInfo { receipt, block }) } } @@ -256,16 +159,21 @@ struct ExecutionResources(starknet::core::types::ExecutionResources); impl From for ExecutionResources { fn from(value: TxExecutionResources) -> Self { ExecutionResources(starknet::core::types::ExecutionResources { - steps: value.steps, - memory_holes: value.memory_holes, - ec_op_builtin_applications: value.ec_op_builtin, - ecdsa_builtin_applications: value.ecdsa_builtin, - keccak_builtin_applications: value.keccak_builtin, - bitwise_builtin_applications: value.bitwise_builtin, - pedersen_builtin_applications: value.pedersen_builtin, - poseidon_builtin_applications: value.poseidon_builtin, - range_check_builtin_applications: value.range_check_builtin, - segment_arena_builtin: value.segment_arena_builtin, + computation_resources: ComputationResources { + steps: value.steps, + memory_holes: value.memory_holes, + ec_op_builtin_applications: value.ec_op_builtin, + ecdsa_builtin_applications: value.ecdsa_builtin, + keccak_builtin_applications: value.keccak_builtin, + bitwise_builtin_applications: value.bitwise_builtin, + pedersen_builtin_applications: value.pedersen_builtin, + poseidon_builtin_applications: value.poseidon_builtin, + range_check_builtin_applications: value.range_check_builtin, + segment_arena_builtin: value.segment_arena_builtin, + }, + data_resources: DataResources { + data_availability: DataAvailabilityResources { l1_data_gas: 0, l1_gas: 0 }, + }, }) } } diff --git a/crates/katana/rpc/rpc-types/src/trace.rs b/crates/katana/rpc/rpc-types/src/trace.rs index 971d1b46a0..938ca9485a 100644 --- a/crates/katana/rpc/rpc-types/src/trace.rs +++ b/crates/katana/rpc/rpc-types/src/trace.rs @@ -2,7 +2,7 @@ use katana_primitives::trace::{CallInfo, TxExecInfo}; use katana_primitives::transaction::TxHash; use serde::{Deserialize, Serialize}; use starknet::core::types::{ - CallType, EntryPointType, ExecutionResources, OrderedEvent, OrderedMessage, + CallType, ComputationResources, EntryPointType, OrderedEvent, OrderedMessage, }; pub struct FunctionInvocation(pub starknet::core::types::FunctionInvocation); @@ -41,10 +41,9 @@ impl From for FunctionInvocation { let vm_resources = info.execution_resources; let get_vm_resource = |name: &str| vm_resources.builtin_instance_counter.get(name).copied(); - // TODO: replace execution resources type in primitive CallInfo with an already defined // `TxExecutionResources` - let execution_resources = ExecutionResources { + let execution_resources = ComputationResources { steps: vm_resources.n_steps, memory_holes: Some(vm_resources.n_memory_holes), range_check_builtin_applications: get_vm_resource("range_check_builtin"), diff --git a/crates/katana/rpc/rpc-types/src/transaction.rs b/crates/katana/rpc/rpc-types/src/transaction.rs index 231326474d..83116798f7 100644 --- a/crates/katana/rpc/rpc-types/src/transaction.rs +++ b/crates/katana/rpc/rpc-types/src/transaction.rs @@ -14,6 +14,7 @@ use katana_primitives::transaction::{ DeployAccountTxV1, DeployAccountTxV3, InvokeTx, InvokeTxV1, InvokeTxV3, TxHash, TxWithHash, }; use katana_primitives::FieldElement; +use num_traits::ToPrimitive; use serde::{Deserialize, Serialize}; use starknet::core::types::{ BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction, @@ -22,7 +23,7 @@ use starknet::core::types::{ }; use starknet::core::utils::get_contract_address; -use crate::receipt::MaybePendingTxReceipt; +use crate::receipt::TxReceiptWithBlockInfo; pub const CHUNK_SIZE_DEFAULT: u64 = 100; @@ -46,7 +47,7 @@ impl BroadcastedInvokeTx { calldata: tx.calldata, signature: tx.signature, sender_address: tx.sender_address.into(), - max_fee: tx.max_fee.try_into().expect("max_fee is too big"), + max_fee: tx.max_fee.to_u128().expect("max_fee is too big"), }), BroadcastedInvokeTransaction::V3(tx) => InvokeTx::V3(InvokeTxV3 { @@ -107,7 +108,7 @@ impl BroadcastedDeclareTx { nonce: tx.nonce, signature: tx.signature, sender_address: tx.sender_address.into(), - max_fee: tx.max_fee.try_into().expect("max fee is too large"), + max_fee: tx.max_fee.to_u128().expect("max fee is too large"), }), }) } @@ -127,7 +128,7 @@ impl BroadcastedDeclareTx { signature: tx.signature, sender_address: tx.sender_address.into(), compiled_class_hash: tx.compiled_class_hash, - max_fee: tx.max_fee.try_into().expect("max fee is too large"), + max_fee: tx.max_fee.to_u128().expect("max fee is too large"), }), }) } @@ -198,7 +199,7 @@ impl BroadcastedDeployAccountTx { contract_address: contract_address.into(), constructor_calldata: tx.constructor_calldata, contract_address_salt: tx.contract_address_salt, - max_fee: tx.max_fee.try_into().expect("max_fee is too big"), + max_fee: tx.max_fee.to_u128().expect("max_fee is too big"), }) } @@ -340,7 +341,7 @@ impl From for Tx { calldata: tx.calldata, contract_address: tx.contract_address.into(), entry_point_selector: tx.entry_point_selector, - nonce: tx.nonce.try_into().expect("nonce should fit in u64"), + nonce: tx.nonce.to_u64().expect("nonce should fit in u64"), version: tx.version, }, ), @@ -430,7 +431,7 @@ impl From for InvokeTx { signature: tx.signature, chain_id: ChainId::default(), sender_address: tx.sender_address.into(), - max_fee: tx.max_fee.try_into().expect("max_fee is too big"), + max_fee: tx.max_fee.to_u128().expect("max_fee is too big"), }), BroadcastedInvokeTransaction::V3(tx) => InvokeTx::V3(InvokeTxV3 { @@ -469,7 +470,7 @@ impl From for DeployAccountTx { contract_address: contract_address.into(), constructor_calldata: tx.constructor_calldata, contract_address_salt: tx.contract_address_salt, - max_fee: tx.max_fee.try_into().expect("max_fee is too big"), + max_fee: tx.max_fee.to_u128().expect("max_fee is too big"), }) } @@ -515,6 +516,6 @@ impl Default for TransactionsPageCursor { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TransactionsPage { - pub transactions: Vec<(TxWithHash, MaybePendingTxReceipt)>, + pub transactions: Vec<(TxWithHash, TxReceiptWithBlockInfo)>, pub cursor: TransactionsPageCursor, } diff --git a/crates/katana/rpc/rpc/Cargo.toml b/crates/katana/rpc/rpc/Cargo.toml index 21bd70a416..a5d5cbaf42 100644 --- a/crates/katana/rpc/rpc/Cargo.toml +++ b/crates/katana/rpc/rpc/Cargo.toml @@ -47,6 +47,7 @@ dojo-world.workspace = true jsonrpsee = { workspace = true, features = [ "client" ] } katana-rpc-api = { workspace = true, features = [ "client" ] } katana-runner.workspace = true +num-traits.workspace = true url.workspace = true alloy = { git = "https://github.com/alloy-rs/alloy", features = [ "contract", diff --git a/crates/katana/rpc/rpc/src/starknet.rs b/crates/katana/rpc/rpc/src/starknet.rs index 603dcff366..f1e616ee58 100644 --- a/crates/katana/rpc/rpc/src/starknet.rs +++ b/crates/katana/rpc/rpc/src/starknet.rs @@ -16,13 +16,14 @@ use katana_provider::traits::transaction::{ }; use katana_rpc_api::starknet::StarknetApiServer; use katana_rpc_types::block::{ - BlockHashAndNumber, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, - PendingBlockWithTxHashes, PendingBlockWithTxs, + BlockHashAndNumber, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes, + MaybePendingBlockWithTxs, PendingBlockWithReceipts, PendingBlockWithTxHashes, + PendingBlockWithTxs, }; use katana_rpc_types::error::starknet::StarknetApiError; use katana_rpc_types::event::{EventFilterWithPage, EventsPage}; use katana_rpc_types::message::MsgFromL1; -use katana_rpc_types::receipt::{MaybePendingTxReceipt, PendingTxReceipt}; +use katana_rpc_types::receipt::{ReceiptBlock, TxReceiptWithBlockInfo}; use katana_rpc_types::state_update::StateUpdate; use katana_rpc_types::trace::FunctionInvocation; use katana_rpc_types::transaction::{ @@ -36,7 +37,8 @@ use katana_rpc_types::{ use katana_rpc_types_builder::ReceiptBuilder; use katana_tasks::{BlockingTaskPool, TokioTaskSpawner}; use starknet::core::types::{ - BlockTag, DeclareTransactionTrace, DeployAccountTransactionTrace, ExecuteInvocation, + BlockTag, ComputationResources, DataAvailabilityResources, DataResources, + DeclareTransactionTrace, DeployAccountTransactionTrace, ExecuteInvocation, ExecutionResources, InvokeTransactionTrace, L1HandlerTransactionTrace, RevertedInvocation, SimulatedTransaction, TransactionExecutionStatus, TransactionStatus, TransactionTrace, }; @@ -107,6 +109,8 @@ impl StarknetApi { gas_consumed: fee.gas_consumed.into(), overall_fee: fee.overall_fee.into(), unit: fee.unit, + data_gas_price: Default::default(), + data_gas_consumed: Default::default(), }), Err(err) => { @@ -347,6 +351,62 @@ impl StarknetApiServer for StarknetApi { .await } + async fn block_with_receipts( + &self, + block_id: BlockIdOrTag, + ) -> RpcResult { + self.on_io_blocking_task(move |this| { + let provider = this.inner.sequencer.backend.blockchain.provider(); + + if BlockIdOrTag::Tag(BlockTag::Pending) == block_id { + if let Some(executor) = this.inner.sequencer.pending_executor() { + let block_env = executor.read().block_env(); + let latest_hash = provider.latest_hash().map_err(StarknetApiError::from)?; + + let gas_prices = block_env.l1_gas_prices.clone(); + + let header = PartialHeader { + number: block_env.number, + gas_prices, + parent_hash: latest_hash, + version: CURRENT_STARKNET_VERSION, + timestamp: block_env.timestamp, + sequencer_address: block_env.sequencer_address, + }; + + let receipts = executor + .read() + .transactions() + .iter() + .filter_map(|(tx, result)| match result { + ExecutionResult::Success { receipt, .. } => { + Some((tx.clone(), receipt.clone())) + } + ExecutionResult::Failed { .. } => None, + }) + .collect::>(); + + return Ok(MaybePendingBlockWithReceipts::Pending( + PendingBlockWithReceipts::new(header, receipts.into_iter()), + )); + } + } + + let block_num = BlockIdReader::convert_block_id(provider, block_id) + .map_err(|e| StarknetApiError::UnexpectedError { reason: e.to_string() })? + .map(BlockHashOrNumber::Num) + .ok_or(StarknetApiError::BlockNotFound)?; + + let block = katana_rpc_types_builder::BlockBuilder::new(block_num, provider) + .build_with_receipts() + .map_err(|e| StarknetApiError::UnexpectedError { reason: e.to_string() })? + .ok_or(Error::from(StarknetApiError::BlockNotFound))?; + + Ok(MaybePendingBlockWithReceipts::Block(block)) + }) + .await + } + async fn state_update(&self, block_id: BlockIdOrTag) -> RpcResult { self.on_io_blocking_task(move |this| { let provider = this.inner.sequencer.backend.blockchain.provider(); @@ -375,7 +435,7 @@ impl StarknetApiServer for StarknetApi { async fn transaction_receipt( &self, transaction_hash: FieldElement, - ) -> RpcResult { + ) -> RpcResult { self.on_io_blocking_task(move |this| { let provider = this.inner.sequencer.backend.blockchain.provider(); let receipt = ReceiptBuilder::new(transaction_hash, provider) @@ -383,7 +443,7 @@ impl StarknetApiServer for StarknetApi { .map_err(|e| StarknetApiError::UnexpectedError { reason: e.to_string() })?; match receipt { - Some(receipt) => Ok(MaybePendingTxReceipt::Receipt(receipt)), + Some(receipt) => Ok(receipt), None => { let executor = this.inner.sequencer.pending_executor(); @@ -404,10 +464,12 @@ impl StarknetApiServer for StarknetApi { }) .ok_or(Error::from(StarknetApiError::TxnHashNotFound))?; - Ok(MaybePendingTxReceipt::Pending(PendingTxReceipt::new( + Ok(TxReceiptWithBlockInfo::new( + ReceiptBlock::Pending, transaction_hash, + FinalityStatus::AcceptedOnL2, pending_receipt, - ))) + )) } } }) @@ -841,6 +903,27 @@ impl StarknetApiServer for StarknetApi { // TODO: compute the state diff let state_diff = None; + let execution_resources = ExecutionResources { + computation_resources: ComputationResources { + steps: 0, + memory_holes: None, + segment_arena_builtin: None, + ecdsa_builtin_applications: None, + ec_op_builtin_applications: None, + keccak_builtin_applications: None, + bitwise_builtin_applications: None, + pedersen_builtin_applications: None, + poseidon_builtin_applications: None, + range_check_builtin_applications: None, + }, + data_resources: DataResources { + data_availability: DataAvailabilityResources { + l1_gas: 0, + l1_data_gas: 0, + }, + }, + }; + let transaction_trace = match receipt { Receipt::Invoke(_) => { TransactionTrace::Invoke(InvokeTransactionTrace { @@ -857,6 +940,7 @@ impl StarknetApiServer for StarknetApi { .expect("should exist if not reverted"), ) }, + execution_resources: execution_resources.clone(), }) } @@ -865,6 +949,7 @@ impl StarknetApiServer for StarknetApi { fee_transfer_invocation, validate_invocation, state_diff, + execution_resources: execution_resources.clone(), }) } @@ -875,6 +960,7 @@ impl StarknetApiServer for StarknetApi { state_diff, constructor_invocation: execute_invocation .expect("should exist bcs tx succeed"), + execution_resources: execution_resources.clone(), }) } @@ -883,6 +969,7 @@ impl StarknetApiServer for StarknetApi { state_diff, function_invocation: execute_invocation .expect("should exist bcs tx succeed"), + execution_resources, }) } }; @@ -895,6 +982,8 @@ impl StarknetApiServer for StarknetApi { gas_price: fee.gas_price.into(), overall_fee: fee.overall_fee.into(), gas_consumed: fee.gas_consumed.into(), + data_gas_price: Default::default(), + data_gas_consumed: Default::default(), }, }) } diff --git a/crates/katana/rpc/rpc/src/torii.rs b/crates/katana/rpc/rpc/src/torii.rs index d80baf35b6..ec2b8ff821 100644 --- a/crates/katana/rpc/rpc/src/torii.rs +++ b/crates/katana/rpc/rpc/src/torii.rs @@ -5,11 +5,11 @@ use jsonrpsee::core::{async_trait, RpcResult}; use katana_core::sequencer::KatanaSequencer; use katana_core::service::block_producer::BlockProducerMode; use katana_executor::ExecutorFactory; -use katana_primitives::block::BlockHashOrNumber; +use katana_primitives::block::{BlockHashOrNumber, FinalityStatus}; use katana_provider::traits::transaction::TransactionProvider; use katana_rpc_api::torii::ToriiApiServer; use katana_rpc_types::error::torii::ToriiApiError; -use katana_rpc_types::receipt::{MaybePendingTxReceipt, PendingTxReceipt}; +use katana_rpc_types::receipt::{ReceiptBlock, TxReceiptWithBlockInfo}; use katana_rpc_types::transaction::{TransactionsPage, TransactionsPageCursor}; use katana_rpc_types_builder::ReceiptBuilder; use katana_tasks::TokioTaskSpawner; @@ -83,7 +83,7 @@ impl ToriiApiServer for ToriiApi { .build() .expect("Receipt should exist for tx") .expect("Receipt should exist for tx"); - (tx, MaybePendingTxReceipt::Receipt(receipt)) + (tx, receipt) }) .collect::>(); @@ -114,10 +114,12 @@ impl ToriiApiServer for ToriiApi { res.receipt().map(|rct| { ( tx.clone(), - MaybePendingTxReceipt::Pending(PendingTxReceipt::new( + TxReceiptWithBlockInfo::new( + ReceiptBlock::Pending, tx.hash, + FinalityStatus::AcceptedOnL2, rct.clone(), - )), + ), ) }) }) @@ -152,10 +154,12 @@ impl ToriiApiServer for ToriiApi { res.receipt().map(|rct| { ( tx.clone(), - MaybePendingTxReceipt::Pending(PendingTxReceipt::new( + TxReceiptWithBlockInfo::new( + ReceiptBlock::Pending, tx.hash, + FinalityStatus::AcceptedOnL2, rct.clone(), - )), + ), ) }) }) @@ -201,10 +205,12 @@ impl ToriiApiServer for ToriiApi { .map(|tx_outcome| { ( tx_outcome.tx.clone(), - MaybePendingTxReceipt::Pending(PendingTxReceipt::new( + TxReceiptWithBlockInfo::new( + ReceiptBlock::Pending, tx_outcome.tx.hash, + FinalityStatus::AcceptedOnL2, tx_outcome.receipt, - )), + ), ) }) .collect::>(); diff --git a/crates/katana/rpc/rpc/tests/common/mod.rs b/crates/katana/rpc/rpc/tests/common/mod.rs index 853e4091cf..e0aa36bdb2 100644 --- a/crates/katana/rpc/rpc/tests/common/mod.rs +++ b/crates/katana/rpc/rpc/tests/common/mod.rs @@ -7,12 +7,12 @@ use cairo_lang_starknet_classes::contract_class::ContractClass; use katana_primitives::conversion::rpc::CompiledClass; use starknet::accounts::Call; use starknet::core::types::contract::SierraClass; -use starknet::core::types::{FieldElement, FlattenedSierraClass}; +use starknet::core::types::{Felt, FlattenedSierraClass}; use starknet::core::utils::get_selector_from_name; pub fn prepare_contract_declaration_params( artifact_path: &PathBuf, -) -> Result<(FlattenedSierraClass, FieldElement)> { +) -> Result<(FlattenedSierraClass, Felt)> { let flattened_class = get_flattened_class(artifact_path) .map_err(|e| anyhow!("error flattening the contract class: {e}"))?; let compiled_class_hash = get_compiled_class_hash(artifact_path) @@ -26,7 +26,7 @@ fn get_flattened_class(artifact_path: &PathBuf) -> Result Ok(contract_artifact.flatten()?) } -fn get_compiled_class_hash(artifact_path: &PathBuf) -> Result { +fn get_compiled_class_hash(artifact_path: &PathBuf) -> Result { let file = File::open(artifact_path)?; let casm_contract_class: ContractClass = serde_json::from_reader(file)?; let casm_contract = @@ -40,15 +40,15 @@ fn get_compiled_class_hash(artifact_path: &PathBuf) -> Result { // TODO: not sure why this function is not seen as used // as prepare_contract_declaration_params is. #[allow(dead_code)] -pub fn build_deploy_cairo1_contract_call(class_hash: FieldElement, salt: FieldElement) -> Call { - let constructor_calldata = vec![FieldElement::from(1_u32), FieldElement::from(2_u32)]; +pub fn build_deploy_cairo1_contract_call(class_hash: Felt, salt: Felt) -> Call { + let constructor_calldata = vec![Felt::from(1_u32), Felt::from(2_u32)]; let calldata = [ vec![ - class_hash, // class hash - salt, // salt - FieldElement::ZERO, // unique - FieldElement::from(constructor_calldata.len()), // constructor calldata len + class_hash, // class hash + salt, // salt + Felt::ZERO, // unique + Felt::from(constructor_calldata.len()), // constructor calldata len ], constructor_calldata.clone(), ] @@ -57,10 +57,8 @@ pub fn build_deploy_cairo1_contract_call(class_hash: FieldElement, salt: FieldEl Call { calldata, // devnet UDC address - to: FieldElement::from_hex_be( - "0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", - ) - .unwrap(), + to: Felt::from_hex("0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf") + .unwrap(), selector: get_selector_from_name("deployContract").unwrap(), } } diff --git a/crates/katana/rpc/rpc/tests/messaging.rs b/crates/katana/rpc/rpc/tests/messaging.rs index a2dffb8538..7156d56fc2 100644 --- a/crates/katana/rpc/rpc/tests/messaging.rs +++ b/crates/katana/rpc/rpc/tests/messaging.rs @@ -11,14 +11,15 @@ use dojo_world::utils::TransactionWaiter; use katana_primitives::utils::transaction::{ compute_l1_handler_tx_hash, compute_l1_to_l2_message_hash, compute_l2_to_l1_message_hash, }; +use katana_rpc_types::receipt::ReceiptBlock; use katana_runner::{KatanaRunner, KatanaRunnerConfig}; use rand::Rng; use serde_json::json; use starknet::accounts::{Account, ConnectedAccount}; use starknet::contract::ContractFactory; use starknet::core::types::{ - BlockId, BlockTag, ContractClass, FieldElement, Hash256, MaybePendingTransactionReceipt, - Transaction, TransactionFinalityStatus, TransactionReceipt, + BlockId, BlockTag, ContractClass, Felt, Hash256, Transaction, TransactionFinalityStatus, + TransactionReceipt, }; use starknet::core::utils::get_contract_address; use starknet::macros::selector; @@ -94,7 +95,7 @@ async fn test_messaging() { // Declare the contract let class_hash = contract.class_hash(); - let res = katana_account.declare(contract.into(), compiled_hash).send().await.unwrap(); + let res = katana_account.declare_v2(contract.into(), compiled_hash).send().await.unwrap(); // The waiter already checks that the transaction is accepted and succeeded on L2. TransactionWaiter::new(res.transaction_hash, katana_account.provider()) @@ -109,11 +110,11 @@ async fn test_messaging() { assert_eq!(class.class_hash(), class_hash, "invalid declared class"); // just to make sure the rpc returns the correct class // Compute the contract address - let address = get_contract_address(FieldElement::ZERO, class_hash, &[], FieldElement::ZERO); + let address = get_contract_address(Felt::ZERO, class_hash, &[], Felt::ZERO); // Deploy the contract using UDC let res = ContractFactory::new(class_hash, &katana_account) - .deploy(Vec::new(), FieldElement::ZERO, false) + .deploy_v1(Vec::new(), Felt::ZERO, false) .send() .await .expect("Unable to deploy contract"); @@ -173,12 +174,12 @@ async fn test_messaging() { // In an l1_handler transaction, the first element of the calldata is always the Ethereum // address of the sender (msg.sender). - let mut l1_tx_calldata = vec![FieldElement::from_byte_slice_be(sender.as_slice()).unwrap()]; - l1_tx_calldata.extend(calldata.iter().map(|x| FieldElement::from(*x))); + let mut l1_tx_calldata = vec![Felt::from_bytes_be_slice(sender.as_slice())]; + l1_tx_calldata.extend(calldata.iter().map(|x| Felt::from(*x))); // Compute transaction hash let tx_hash = compute_l1_handler_tx_hash( - FieldElement::ZERO, + Felt::ZERO, recipient, selector, &l1_tx_calldata, @@ -203,15 +204,15 @@ async fn test_messaging() { assert_eq!(tx.calldata, l1_tx_calldata); // fetch the receipt - let receipt = katana_account + let receipt_res = katana_account .provider() .get_transaction_receipt(tx.transaction_hash) .await .expect("failed to get receipt"); - match receipt { - MaybePendingTransactionReceipt::Receipt(receipt) => { - let TransactionReceipt::L1Handler(receipt) = receipt else { + match receipt_res.block { + ReceiptBlock::Block { .. } => { + let TransactionReceipt::L1Handler(receipt) = receipt_res.receipt else { panic!("invalid receipt type"); }; @@ -219,7 +220,7 @@ async fn test_messaging() { sender.as_slice().try_into().unwrap(), recipient, selector, - &calldata.iter().map(|x| FieldElement::from(*x)).collect::>(), + &calldata.iter().map(|x| Felt::from(*x)).collect::>(), nonce.to::(), ); @@ -243,13 +244,13 @@ async fn test_messaging() { { // The L1 contract address to send the message to let l1_contract_address = l1_test_contract.address(); - let l1_contract_address = FieldElement::from_str(&l1_contract_address.to_string()).unwrap(); + let l1_contract_address = Felt::from_str(&l1_contract_address.to_string()).unwrap(); let l2_contract = CairoMessagingContract::new(l2_test_contract, &katana_account); // Send message to L1 let res = l2_contract - .send_message_value(&EthAddress::from(l1_contract_address), &FieldElement::TWO) + .send_message_value(&EthAddress::from(l1_contract_address), &Felt::TWO) .send() .await .expect("Call to send_message_value failed"); @@ -266,11 +267,8 @@ async fn test_messaging() { // registered. If the message is registered, calling `l2ToL1Messages` of the L1 core // contract with the message hash should return a non-zero value. - let l2_l1_msg_hash = compute_l2_to_l1_message_hash( - l2_test_contract, - l1_contract_address, - &[FieldElement::TWO], - ); + let l2_l1_msg_hash = + compute_l2_to_l1_message_hash(l2_test_contract, l1_contract_address, &[Felt::TWO]); let msg_fee = core_contract .l2ToL1Messages(l2_l1_msg_hash) diff --git a/crates/katana/rpc/rpc/tests/saya.rs b/crates/katana/rpc/rpc/tests/saya.rs index ad821d524b..7b8b260d6b 100644 --- a/crates/katana/rpc/rpc/tests/saya.rs +++ b/crates/katana/rpc/rpc/tests/saya.rs @@ -9,10 +9,10 @@ use katana_primitives::block::{BlockIdOrTag, BlockTag}; use katana_rpc_api::dev::DevApiClient; use katana_rpc_api::saya::SayaApiClient; use starknet::accounts::{Account, ConnectedAccount}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::macros::felt; -const ENOUGH_GAS: FieldElement = felt!("0x100000000000000000"); +const ENOUGH_GAS: Felt = felt!("0x100000000000000000"); mod common; @@ -33,7 +33,7 @@ async fn fetch_traces_from_block() { common::prepare_contract_declaration_params(&path).unwrap(); let contract = Arc::new(contract); - let res = account.declare(contract.clone(), compiled_class_hash).send().await.unwrap(); + let res = account.declare_v2(contract.clone(), compiled_class_hash).send().await.unwrap(); // wait for the tx to be mined TransactionWaiter::new(res.transaction_hash, account.provider()) .with_interval(200) @@ -47,7 +47,7 @@ async fn fetch_traces_from_block() { let call = common::build_deploy_cairo1_contract_call(res.class_hash, (i + 2_u32).into()); let res = account - .execute(vec![call]) + .execute_v1(vec![call]) .max_fee(ENOUGH_GAS) .send() .await @@ -102,7 +102,7 @@ async fn fetch_traces_from_pending_block() { common::prepare_contract_declaration_params(&path).unwrap(); let contract = Arc::new(contract); - let res = account.declare(contract.clone(), compiled_class_hash).send().await.unwrap(); + let res = account.declare_v2(contract.clone(), compiled_class_hash).send().await.unwrap(); // wait for the tx to be mined TransactionWaiter::new(res.transaction_hash, account.provider()) .with_interval(200) @@ -118,7 +118,7 @@ async fn fetch_traces_from_pending_block() { // we set the nonce manually so that we can send the tx rapidly without waiting for the // previous tx to be mined first. let res = account - .execute(vec![call]) + .execute_v1(vec![call]) .max_fee(ENOUGH_GAS) .send() .await diff --git a/crates/katana/rpc/rpc/tests/starknet.rs b/crates/katana/rpc/rpc/tests/starknet.rs index ec0bf3a57f..d9aae51aaa 100644 --- a/crates/katana/rpc/rpc/tests/starknet.rs +++ b/crates/katana/rpc/rpc/tests/starknet.rs @@ -5,11 +5,12 @@ use std::time::Duration; use dojo_test_utils::sequencer::{get_default_test_starknet_config, TestSequencer}; use katana_core::sequencer::SequencerConfig; +use katana_rpc_types::receipt::ReceiptBlock; use starknet::accounts::{Account, Call, ConnectedAccount}; use starknet::core::types::contract::legacy::LegacyContractClass; use starknet::core::types::{ - BlockId, BlockTag, DeclareTransactionReceipt, FieldElement, MaybePendingTransactionReceipt, - TransactionFinalityStatus, TransactionReceipt, + BlockId, BlockTag, DeclareTransactionReceipt, Felt, TransactionFinalityStatus, + TransactionReceipt, }; use starknet::core::utils::{get_contract_address, get_selector_from_name}; use starknet::providers::Provider; @@ -29,52 +30,51 @@ async fn test_send_declare_and_deploy_contract() { common::prepare_contract_declaration_params(&path).unwrap(); let class_hash = contract.class_hash(); - let res = account.declare(Arc::new(contract), compiled_class_hash).send().await.unwrap(); + let res = account.declare_v2(Arc::new(contract), compiled_class_hash).send().await.unwrap(); // wait for the tx to be mined tokio::time::sleep(Duration::from_millis(WAIT_TX_DELAY_MILLIS)).await; let receipt = account.provider().get_transaction_receipt(res.transaction_hash).await.unwrap(); - match receipt { - MaybePendingTransactionReceipt::Receipt(TransactionReceipt::Declare( - DeclareTransactionReceipt { finality_status, .. }, - )) => { + match receipt.block { + ReceiptBlock::Block { .. } => { + let TransactionReceipt::Declare(DeclareTransactionReceipt { finality_status, .. }) = + receipt.receipt + else { + panic!("invalid tx receipt") + }; + assert_eq!(finality_status, TransactionFinalityStatus::AcceptedOnL2); } + _ => panic!("invalid tx receipt"), } assert!(account.provider().get_class(BlockId::Tag(BlockTag::Latest), class_hash).await.is_ok()); - let constructor_calldata = vec![FieldElement::from(1_u32), FieldElement::from(2_u32)]; + let constructor_calldata = vec![Felt::from(1_u32), Felt::from(2_u32)]; let calldata = [ vec![ - res.class_hash, // class hash - FieldElement::ZERO, // salt - FieldElement::ZERO, // unique - FieldElement::from(constructor_calldata.len()), // constructor calldata len + res.class_hash, // class hash + Felt::ZERO, // salt + Felt::ZERO, // unique + Felt::from(constructor_calldata.len()), // constructor calldata len ], constructor_calldata.clone(), ] .concat(); - let contract_address = get_contract_address( - FieldElement::ZERO, - res.class_hash, - &constructor_calldata, - FieldElement::ZERO, - ); + let contract_address = + get_contract_address(Felt::ZERO, res.class_hash, &constructor_calldata, Felt::ZERO); account - .execute(vec![Call { + .execute_v1(vec![Call { calldata, // devnet UDC address - to: FieldElement::from_hex_be( - "0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", - ) - .unwrap(), + to: Felt::from_hex("0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf") + .unwrap(), selector: get_selector_from_name("deployContract").unwrap(), }]) .send() @@ -115,45 +115,44 @@ async fn test_send_declare_and_deploy_legacy_contract() { let receipt = account.provider().get_transaction_receipt(res.transaction_hash).await.unwrap(); - match receipt { - MaybePendingTransactionReceipt::Receipt(TransactionReceipt::Declare( - DeclareTransactionReceipt { finality_status, .. }, - )) => { + match receipt.block { + ReceiptBlock::Block { .. } => { + let TransactionReceipt::Declare(DeclareTransactionReceipt { finality_status, .. }) = + receipt.receipt + else { + panic!("invalid tx receipt") + }; + assert_eq!(finality_status, TransactionFinalityStatus::AcceptedOnL2); } + _ => panic!("invalid tx receipt"), } assert!(account.provider().get_class(BlockId::Tag(BlockTag::Latest), class_hash).await.is_ok()); - let constructor_calldata = vec![FieldElement::ONE]; + let constructor_calldata = vec![Felt::ONE]; let calldata = [ vec![ - res.class_hash, // class hash - FieldElement::ZERO, // salt - FieldElement::ZERO, // unique - FieldElement::from(constructor_calldata.len()), // constructor calldata len + res.class_hash, // class hash + Felt::ZERO, // salt + Felt::ZERO, // unique + Felt::from(constructor_calldata.len()), // constructor calldata len ], constructor_calldata.clone(), ] .concat(); - let contract_address = get_contract_address( - FieldElement::ZERO, - res.class_hash, - &constructor_calldata.clone(), - FieldElement::ZERO, - ); + let contract_address = + get_contract_address(Felt::ZERO, res.class_hash, &constructor_calldata.clone(), Felt::ZERO); account - .execute(vec![Call { + .execute_v1(vec![Call { calldata, // devnet UDC address - to: FieldElement::from_hex_be( - "0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", - ) - .unwrap(), + to: Felt::from_hex("0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf") + .unwrap(), selector: get_selector_from_name("deployContract").unwrap(), }]) .send() diff --git a/crates/katana/rpc/rpc/tests/torii.rs b/crates/katana/rpc/rpc/tests/torii.rs index 64f57da019..abd552e347 100644 --- a/crates/katana/rpc/rpc/tests/torii.rs +++ b/crates/katana/rpc/rpc/tests/torii.rs @@ -11,7 +11,7 @@ use katana_rpc_api::starknet::StarknetApiClient; use katana_rpc_api::torii::ToriiApiClient; use katana_rpc_types::transaction::{TransactionsPage, TransactionsPageCursor}; use starknet::accounts::{Account, Call, ConnectedAccount}; -use starknet::core::types::{FieldElement, TransactionStatus}; +use starknet::core::types::{Felt, TransactionStatus}; use starknet::core::utils::get_selector_from_name; use tokio::time::sleep; @@ -46,7 +46,8 @@ async fn test_get_transactions() { assert_eq!(response.cursor.block_number, 1); assert_eq!(response.cursor.transaction_index, 0); - let declare_res = account.declare(contract.clone(), compiled_class_hash).send().await.unwrap(); + let declare_res = + account.declare_v2(contract.clone(), compiled_class_hash).send().await.unwrap(); // Should return successfully with single pending txn. let response: TransactionsPage = client.get_transactions(response.cursor).await.unwrap(); @@ -67,8 +68,8 @@ async fn test_get_transactions() { // Should block on cursor at end of page and return on new txn let long_poll_future = client.get_transactions(response.cursor); - let deploy_call = build_deploy_contract_call(declare_res.class_hash, FieldElement::ZERO); - let deploy_txn = account.execute(vec![deploy_call]); + let deploy_call = build_deploy_contract_call(declare_res.class_hash, Felt::ZERO); + let deploy_txn = account.execute_v1(vec![deploy_call]); let deploy_txn_future = deploy_txn.send(); tokio::select! { @@ -87,8 +88,8 @@ async fn test_get_transactions() { // Create block 2. let _: () = client.generate_block().await.unwrap(); - let deploy_call = build_deploy_contract_call(declare_res.class_hash, FieldElement::ONE); - let deploy_txn = account.execute(vec![deploy_call]); + let deploy_call = build_deploy_contract_call(declare_res.class_hash, Felt::ONE); + let deploy_txn = account.execute_v1(vec![deploy_call]); let deploy_txn_future = deploy_txn.send().await.unwrap(); TransactionWaiter::new(deploy_txn_future.transaction_hash, &account.provider()).await.unwrap(); @@ -111,23 +112,23 @@ async fn test_get_transactions() { // Create block 3. let _: () = client.generate_block().await.unwrap(); - let max_fee = FieldElement::from_hex_be(ENOUGH_GAS).unwrap(); - let mut nonce = FieldElement::THREE; - let mut last_tx_hash = FieldElement::ZERO; + let max_fee = Felt::from_hex(ENOUGH_GAS).unwrap(); + let mut nonce = Felt::THREE; + let mut last_tx_hash = Felt::ZERO; // Test only returns first 100 txns from pending block for i in 0..101 { let deploy_call = build_deploy_contract_call(declare_res.class_hash, (i + 2_u32).into()); - let deploy_txn = account.execute(vec![deploy_call]).nonce(nonce).max_fee(max_fee); + let deploy_txn = account.execute_v1(vec![deploy_call]).nonce(nonce).max_fee(max_fee); let res = deploy_txn.send().await.unwrap(); - nonce += FieldElement::ONE; + nonce += Felt::ONE; if i == 100 { last_tx_hash = res.transaction_hash; } } - assert!(last_tx_hash != FieldElement::ZERO); + assert!(last_tx_hash != Felt::ZERO); // Poll the statux of the last tx sent. let max_retry = 10; @@ -195,7 +196,8 @@ async fn test_get_transactions_with_instant_mining() { // Should return successfully when no transactions have been mined. let cursor = TransactionsPageCursor { block_number: 0, transaction_index: 0, chunk_size: 100 }; - let declare_res = account.declare(contract.clone(), compiled_class_hash).send().await.unwrap(); + let declare_res = + account.declare_v2(contract.clone(), compiled_class_hash).send().await.unwrap(); sleep(Duration::from_millis(1000)).await; @@ -208,8 +210,8 @@ async fn test_get_transactions_with_instant_mining() { // Should block on cursor at end of page and return on new txn let long_poll_future = client.get_transactions(response.cursor); - let deploy_call = build_deploy_contract_call(declare_res.class_hash, FieldElement::ZERO); - let deploy_txn = account.execute(vec![deploy_call]); + let deploy_call = build_deploy_contract_call(declare_res.class_hash, Felt::ZERO); + let deploy_txn = account.execute_v1(vec![deploy_call]); let deploy_txn_future = deploy_txn.send(); tokio::select! { @@ -225,8 +227,8 @@ async fn test_get_transactions_with_instant_mining() { } } - let deploy_call = build_deploy_contract_call(declare_res.class_hash, FieldElement::ONE); - let deploy_txn = account.execute(vec![deploy_call]); + let deploy_call = build_deploy_contract_call(declare_res.class_hash, Felt::ONE); + let deploy_txn = account.execute_v1(vec![deploy_call]); let deploy_txn_future = deploy_txn.send().await.unwrap(); // Should properly increment to new pending block @@ -247,15 +249,15 @@ async fn test_get_transactions_with_instant_mining() { sequencer.stop().expect("failed to stop sequencer"); } -fn build_deploy_contract_call(class_hash: FieldElement, salt: FieldElement) -> Call { - let constructor_calldata = vec![FieldElement::from(1_u32), FieldElement::from(2_u32)]; +fn build_deploy_contract_call(class_hash: Felt, salt: Felt) -> Call { + let constructor_calldata = vec![Felt::from(1_u32), Felt::from(2_u32)]; let calldata = [ vec![ - class_hash, // class hash - salt, // salt - FieldElement::ZERO, // unique - FieldElement::from(constructor_calldata.len()), // constructor calldata len + class_hash, // class hash + salt, // salt + Felt::ZERO, // unique + Felt::from(constructor_calldata.len()), // constructor calldata len ], constructor_calldata.clone(), ] @@ -264,10 +266,8 @@ fn build_deploy_contract_call(class_hash: FieldElement, salt: FieldElement) -> C Call { calldata, // devnet UDC address - to: FieldElement::from_hex_be( - "0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", - ) - .unwrap(), + to: Felt::from_hex("0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf") + .unwrap(), selector: get_selector_from_name("deployContract").unwrap(), } } diff --git a/crates/katana/storage/codecs/src/lib.rs b/crates/katana/storage/codecs/src/lib.rs index 9e0c2e2043..ff18972ec0 100644 --- a/crates/katana/storage/codecs/src/lib.rs +++ b/crates/katana/storage/codecs/src/lib.rs @@ -63,7 +63,7 @@ macro_rules! impl_compact_felt { if len > 0 { let mut arr = [0u8; 32]; arr[32 - len..].copy_from_slice(&buf[..len]); - (FieldElement::from_bytes_be(&arr).unwrap().into(), &buf[len..]) + (FieldElement::from_bytes_be(&arr).into(), &buf[len..]) } else { (FieldElement::ZERO.into(), buf) } diff --git a/crates/katana/storage/db/src/codecs/mod.rs b/crates/katana/storage/db/src/codecs/mod.rs index c45a2a93f5..9c57ec7034 100644 --- a/crates/katana/storage/db/src/codecs/mod.rs +++ b/crates/katana/storage/db/src/codecs/mod.rs @@ -62,8 +62,7 @@ macro_rules! impl_encode_and_decode_for_felts { impl Decode for $ty { fn decode>(bytes: B) -> Result { - let felt = FieldElement::from_byte_slice_be(bytes.as_ref()); - Ok(felt.map_err(|e| CodecError::Decode(e.to_string()))?.into()) + Ok(FieldElement::from_bytes_be_slice(bytes.as_ref()).into()) } } )* diff --git a/crates/katana/storage/db/src/models/storage.rs b/crates/katana/storage/db/src/models/storage.rs index 5412b22b1f..b6264a481f 100644 --- a/crates/katana/storage/db/src/models/storage.rs +++ b/crates/katana/storage/db/src/models/storage.rs @@ -27,8 +27,7 @@ impl Compress for StorageEntry { impl Decompress for StorageEntry { fn decompress>(bytes: B) -> Result { let bytes = bytes.as_ref(); - let key = StorageKey::from_byte_slice_be(&bytes[0..32]) - .map_err(|e| CodecError::Decompress(e.to_string()))?; + let key = StorageKey::from_bytes_be_slice(&bytes[0..32]); let value = StorageValue::decompress(&bytes[32..])?; Ok(Self { key, value }) } diff --git a/crates/katana/storage/provider/tests/block.rs b/crates/katana/storage/provider/tests/block.rs index 2378ee3968..a5ea696017 100644 --- a/crates/katana/storage/provider/tests/block.rs +++ b/crates/katana/storage/provider/tests/block.rs @@ -27,7 +27,7 @@ use fixtures::{ db_provider, fork_provider, fork_provider_with_spawned_fork_network, in_memory_provider, mock_state_updates, provider_with_states, }; -use starknet::core::types::FieldElement; +use katana_primitives::FieldElement; #[apply(insert_block_cases)] fn insert_block_with_in_memory_provider( diff --git a/crates/saya/core/Cargo.toml b/crates/saya/core/Cargo.toml index bb319cbc3a..051b8f3c9d 100644 --- a/crates/saya/core/Cargo.toml +++ b/crates/saya/core/Cargo.toml @@ -16,6 +16,7 @@ saya-provider.workspace = true anyhow.workspace = true async-trait.workspace = true +bigdecimal.workspace = true cairo-proof-parser.workspace = true cairo-vm.workspace = true convert_case.workspace = true @@ -31,7 +32,7 @@ serde.workspace = true serde_json.workspace = true serde_with.workspace = true starknet-crypto.workspace = true -starknet-types-core = { version = "0.0.9", default-features = false, features = [ "curve", "num-traits", "serde" ] } +starknet-types-core = { version = "0.1.4", default-features = false, features = [ "curve", "num-traits", "serde" ] } starknet.workspace = true starknet_api.workspace = true thiserror.workspace = true diff --git a/crates/saya/core/src/data_availability/celestia/mod.rs b/crates/saya/core/src/data_availability/celestia/mod.rs index 7e85dd1567..51372e7910 100644 --- a/crates/saya/core/src/data_availability/celestia/mod.rs +++ b/crates/saya/core/src/data_availability/celestia/mod.rs @@ -7,7 +7,7 @@ use celestia_types::blob::GasPrice; use celestia_types::nmt::Namespace; use celestia_types::Blob; use serde::{Deserialize, Serialize}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use url::Url; use crate::data_availability::error::{DataAvailabilityResult, Error}; @@ -54,10 +54,7 @@ impl DataAvailabilityClient for CelestiaClient { self.mode } - async fn publish_state_diff_felts( - &self, - state_diff: &[FieldElement], - ) -> DataAvailabilityResult { + async fn publish_state_diff_felts(&self, state_diff: &[Felt]) -> DataAvailabilityResult { let bytes: Vec = state_diff.iter().flat_map(|fe| fe.to_bytes_be().to_vec()).collect(); let blob = Blob::new(self.namespace, bytes)?; @@ -72,8 +69,8 @@ impl DataAvailabilityClient for CelestiaClient { async fn publish_state_diff_and_proof_felts( &self, - state_diff: &[FieldElement], - state_diff_proof: &[FieldElement], + state_diff: &[Felt], + state_diff_proof: &[Felt], ) -> DataAvailabilityResult { let bytes: Vec = state_diff.iter().flat_map(|fe| fe.to_bytes_be().to_vec()).collect(); let blob = Blob::new(self.namespace, bytes)?; diff --git a/crates/saya/core/src/data_availability/mod.rs b/crates/saya/core/src/data_availability/mod.rs index d5ae1d410b..fbf8deba8c 100644 --- a/crates/saya/core/src/data_availability/mod.rs +++ b/crates/saya/core/src/data_availability/mod.rs @@ -7,7 +7,7 @@ use std::fmt::Display; use async_trait::async_trait; use serde::{Deserialize, Serialize}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; pub mod celestia; @@ -57,10 +57,7 @@ pub trait DataAvailabilityClient { /// * `state_diff` - An array of felt representing the data to be published on the DA layer. We /// use felt as all fields inside the state diff can be expressed as a felt. Nonce and updates /// count are limited to 64 bits anyway. - async fn publish_state_diff_felts( - &self, - state_diff: &[FieldElement], - ) -> DataAvailabilityResult; + async fn publish_state_diff_felts(&self, state_diff: &[Felt]) -> DataAvailabilityResult; /// Publishes both data and transition proof on the DA layer atomically. /// Returns the block height in which the state diff was included. @@ -73,8 +70,8 @@ pub trait DataAvailabilityClient { /// * `state_diff_proof` - The serialized transition proof corresponding to the `state_diff`. async fn publish_state_diff_and_proof_felts( &self, - state_diff: &[FieldElement], - state_diff_proof: &[FieldElement], + state_diff: &[Felt], + state_diff_proof: &[Felt], ) -> DataAvailabilityResult; } diff --git a/crates/saya/core/src/dojo_os/mod.rs b/crates/saya/core/src/dojo_os/mod.rs index 74d387539c..2318fc9656 100644 --- a/crates/saya/core/src/dojo_os/mod.rs +++ b/crates/saya/core/src/dojo_os/mod.rs @@ -17,7 +17,7 @@ use itertools::chain; use once_cell::sync::OnceCell; use starknet::accounts::{Account, Call, ConnectedAccount, ExecutionEncoding, SingleOwnerAccount}; use starknet::core::types::{ - BlockId, BlockTag, FieldElement, TransactionExecutionStatus, TransactionStatus, + BlockId, BlockTag, Felt, TransactionExecutionStatus, TransactionStatus, }; use starknet::core::utils::get_selector_from_name; use starknet::providers::jsonrpc::HttpTransport; @@ -55,15 +55,15 @@ pub fn get_starknet_account( } pub async fn starknet_apply_diffs( - world: FieldElement, - new_state: Vec, - program_output: Vec, - program_hash: FieldElement, - nonce: FieldElement, + world: Felt, + new_state: Vec, + program_output: Vec, + program_hash: Felt, + nonce: Felt, starknet_account: StarknetAccountData, ) -> anyhow::Result { let calldata = chain![ - vec![FieldElement::from(new_state.len() as u64 / 2)].into_iter(), + vec![Felt::from(new_state.len() as u64 / 2)].into_iter(), new_state.clone().into_iter(), program_output.into_iter(), vec![program_hash], @@ -74,7 +74,7 @@ pub async fn starknet_apply_diffs( let account = account.lock().await; let txn_config = TxnConfig { wait: true, receipt: true, ..Default::default() }; let tx = account - .execute(vec![Call { + .execute_v1(vec![Call { to: world, selector: get_selector_from_name("upgrade_state").expect("invalid selector"), calldata, diff --git a/crates/saya/core/src/lib.rs b/crates/saya/core/src/lib.rs index fa982c5eb4..030b2bd6ca 100644 --- a/crates/saya/core/src/lib.rs +++ b/crates/saya/core/src/lib.rs @@ -20,6 +20,7 @@ use saya_provider::Provider as SayaProvider; use serde::{Deserialize, Serialize}; use starknet::core::utils::cairo_short_string_to_felt; use starknet_crypto::poseidon_hash_many; +use starknet_types_core::felt::Felt; use tokio::fs::File; use tokio::io::AsyncWriteExt; use tracing::{error, info, trace}; @@ -388,7 +389,7 @@ impl Saya { world_da, program_output, program_hash, - nonce_after + 1u64.into(), + nonce_after + Felt::ONE, self.config.starknet_account.clone(), ) .await?; diff --git a/crates/saya/core/src/prover/extract.rs b/crates/saya/core/src/prover/extract.rs index 7ae3cf7bdd..7a760183f5 100644 --- a/crates/saya/core/src/prover/extract.rs +++ b/crates/saya/core/src/prover/extract.rs @@ -1,4 +1,5 @@ use anyhow::anyhow; +use bigdecimal::BigDecimal; use katana_primitives::contract::ContractAddress; use katana_primitives::state::StateUpdates; use katana_primitives::FieldElement; @@ -15,7 +16,7 @@ pub fn program_input_from_program_output( let block_number = serde_json::from_str(&output[2].to_string()).unwrap(); let block_hash = output[3]; let config_hash = output[4]; - let mut decimal = output[6].clone().to_big_decimal(0); // Convert with no decimal places + let mut decimal: BigDecimal = output[6].clone().to_bigint().into(); // Convert with no decimal places let num = decimal.to_u64().ok_or_else(|| anyhow!("Conversion to u64 failed"))?; let message_to_starknet_segment = match num { @@ -24,7 +25,7 @@ pub fn program_input_from_program_output( }; let index = 7 + num as usize; - decimal = output[index].clone().to_big_decimal(0); + decimal = output[index].clone().to_bigint().into(); let num = decimal.to_u64().ok_or_else(|| anyhow!("Conversion to u64 failed"))?; let message_to_appchain_segment = match num { 0..=4 => Default::default(), @@ -59,7 +60,7 @@ fn get_message_to_starknet_segment( } let from_address = ContractAddress::from(output[index]); let to_address = ContractAddress::from(output[index + 1]); - let decimal = output[index + 2].to_big_decimal(0); + let decimal: BigDecimal = output[index + 2].to_bigint().into(); let num = decimal.to_u64().ok_or_else(|| anyhow!("Conversion to u64 failed"))?; let payload = output[index + 3..index + 3 + num as usize].to_vec(); message_to_starknet_segment.push(MessageToStarknet { from_address, to_address, payload }); @@ -81,7 +82,7 @@ fn get_message_to_appchain_segment( let to_address = ContractAddress::from(output[index + 1]); let nonce = output[index + 2]; let selector = output[index + 3]; - let decimal = output[index + 4].to_big_decimal(0); + let decimal: BigDecimal = output[index + 4].to_bigint().into(); let num = decimal.to_u64().ok_or_else(|| anyhow!("Conversion to u64 failed"))?; let payload = output[index + 5..index + 5 + num as usize].to_vec(); diff --git a/crates/saya/core/src/prover/program_input.rs b/crates/saya/core/src/prover/program_input.rs index 146f9ce111..74fdb233ab 100644 --- a/crates/saya/core/src/prover/program_input.rs +++ b/crates/saya/core/src/prover/program_input.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use anyhow::bail; +use bigdecimal::BigDecimal; use katana_primitives::contract::ContractAddress; use katana_primitives::state::StateUpdates; use katana_primitives::trace::{CallInfo, EntryPointType}; @@ -8,16 +9,16 @@ use katana_primitives::transaction::{L1HandlerTx, TxHash}; use katana_rpc_types::trace::TxExecutionInfo; use serde::ser::{SerializeSeq, Serializer}; use serde::{Deserialize, Deserializer, Serialize}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; /// Based on https://github.com/cartridge-gg/piltover/blob/2be9d46f00c9c71e2217ab74341f77b09f034c81/src/snos_output.cairo#L19-L20 /// With the new state root computed by the prover. #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Default)] pub struct ProgramInput { - pub prev_state_root: FieldElement, + pub prev_state_root: Felt, pub block_number: u64, - pub block_hash: FieldElement, - pub config_hash: FieldElement, + pub block_hash: Felt, + pub config_hash: Felt, #[serde(serialize_with = "MessageToStarknet::serialize_message_to_starknet")] #[serde(deserialize_with = "MessageToStarknet::deserialize_message_to_starknet")] pub message_to_starknet_segment: Vec, @@ -27,13 +28,10 @@ pub struct ProgramInput { #[serde(flatten)] pub state_updates: StateUpdates, #[serde(serialize_with = "serialize_world_da")] - pub world_da: Option>, + pub world_da: Option>, } -fn serialize_world_da( - element: &Option>, - serializer: S, -) -> Result +fn serialize_world_da(element: &Option>, serializer: S) -> Result where S: Serializer, { @@ -41,9 +39,10 @@ where let mut seq = serializer.serialize_seq(Some(da.len()))?; for d in da { - let decimal = d.to_big_decimal(0); // Convert with no decimal places - let num = decimal.to_string(); - seq.serialize_element(&num)?; + // let decimal: BigDecimal = d.to_bigint().into(); // Convert with no decimal places + // let num = decimal.to_string(); + // seq.serialize_element(&num)?; + seq.serialize_element(&d)?; } seq.end() @@ -117,7 +116,7 @@ impl ProgramInput { /// that represent the serialized DA. The length is not included as the array contains /// serialiazed struct with two members: key and value. /// TODO: migrate to cainome + simple rust vec for better devX in the future. - pub fn fill_da(&mut self, world: FieldElement) { + pub fn fill_da(&mut self, world: Felt) { let updates = self .state_updates .storage_updates @@ -183,7 +182,7 @@ impl ProgramInput { }) } - pub fn da_as_calldata(&self, world: FieldElement) -> Vec { + pub fn da_as_calldata(&self, world: Felt) -> Vec { let updates = self .state_updates .storage_updates @@ -196,37 +195,37 @@ impl ProgramInput { updates } - fn serialize_to_prover_args(&self) -> Vec { + fn serialize_to_prover_args(&self) -> Vec { let mut out = vec![ self.prev_state_root, - FieldElement::from(self.block_number), + Felt::from(self.block_number), self.block_hash, self.config_hash, ]; - out.push(FieldElement::from(self.state_updates.nonce_updates.len())); + out.push(Felt::from(self.state_updates.nonce_updates.len())); for (k, v) in &self.state_updates.nonce_updates { out.push(**k); out.push(*v); } - out.push(FieldElement::from(self.state_updates.storage_updates.len())); + out.push(Felt::from(self.state_updates.storage_updates.len())); for (c, h) in &self.state_updates.storage_updates { out.push(**c); - out.push(FieldElement::from(h.len())); + out.push(Felt::from(h.len())); for (k, v) in h { out.push(*k); out.push(*v); } } - out.push(FieldElement::from(self.state_updates.contract_updates.len())); + out.push(Felt::from(self.state_updates.contract_updates.len())); for (k, v) in &self.state_updates.contract_updates { out.push(**k); out.push(*v); } - out.push(FieldElement::from(self.state_updates.declared_classes.len())); + out.push(Felt::from(self.state_updates.declared_classes.len())); for (k, v) in &self.state_updates.declared_classes { out.push(*k); out.push(*v); @@ -237,7 +236,7 @@ impl ProgramInput { .iter() .flat_map(|m| m.serialize().unwrap()) .collect::>(); - out.push(FieldElement::from(starknet_messages.len())); + out.push(Felt::from(starknet_messages.len())); out.extend(starknet_messages); let appchain_messages = self @@ -246,13 +245,13 @@ impl ProgramInput { .flat_map(|m| m.serialize().unwrap()) .collect::>(); - out.push(FieldElement::from(appchain_messages.len())); + out.push(Felt::from(appchain_messages.len())); out.extend(appchain_messages); - out.push(FieldElement::from(self.world_da.as_ref().unwrap().len() / 2)); + out.push(Felt::from(self.world_da.as_ref().unwrap().len() / 2)); out.extend(self.world_da.as_ref().unwrap().iter().cloned()); - out.push(FieldElement::from(0u64)); // Proofs + out.push(Felt::from(0u64)); // Proofs out } @@ -261,7 +260,10 @@ impl ProgramInput { let serialized = inputs.iter().flat_map(|input| input.serialize_to_prover_args()).collect::>(); - let joined = serialized.iter().map(|f| f.to_big_decimal(0).to_string()).collect::>(); + let joined = serialized + .iter() + .map(|f| BigDecimal::from(f.to_bigint()).to_string()) + .collect::>(); format!("[{} {}]", inputs.len(), joined.join(" ")) } @@ -272,7 +274,7 @@ impl ProgramInput { pub struct MessageToStarknet { pub from_address: ContractAddress, pub to_address: ContractAddress, - pub payload: Vec, + pub payload: Vec, } impl MessageToStarknet { @@ -288,17 +290,18 @@ impl MessageToStarknet { let serialized = message.serialize().unwrap(); // Instead of adding serialized as an array, add each element individually for field_element in serialized { - let decimal = field_element.to_big_decimal(0); // Assuming no decimal places for simplicity - let num = decimal.to_string(); - seq.serialize_element(&num)?; + // let decimal: BigDecimal = field_element.to_bigint().into(); // Assuming no + // decimal places for simplicity let num = decimal.to_string(); + // seq.serialize_element(&num)?; + seq.serialize_element(&field_element)?; } } seq.end() } - pub fn serialize(&self) -> anyhow::Result> { + pub fn serialize(&self) -> anyhow::Result> { let mut result = vec![*self.from_address, *self.to_address]; - result.push(FieldElement::from(self.payload.len())); + result.push(Felt::from(self.payload.len())); result.extend(self.payload.iter().cloned()); Ok(result) } @@ -325,19 +328,33 @@ impl MessageToStarknet { let mut messages = Vec::new(); while let Some(from_address) = seq .next_element::()? - .map(|num| FieldElement::from_str(&num.to_string()).unwrap()) + .map(|num| Felt::from_str(&num.to_string()).unwrap()) { let to_address = seq .next_element::()? - .map(|num| FieldElement::from_str(&num.to_string()).unwrap()) + .map(|num| Felt::from_str(&num.to_string()).unwrap()) .unwrap_or_default(); + let payload_length_str = seq.next_element::()?.unwrap_or_default(); - let payload_length: usize = payload_length_str.parse().unwrap_or_default(); + // TODO: for compatibility reason, the length can be in either decimal or hex + // format. maybe should just expect all values to be in hex format. + let payload_length = payload_length_str + .parse::() + .or_else(|_| { + usize::from_str_radix( + payload_length_str + .strip_prefix("0x") + .unwrap_or(&payload_length_str), + 16, + ) + }) + .expect("invalid length value"); + let mut payload = Vec::new(); for _ in 0..payload_length { if let Some(element) = seq .next_element::()? - .map(|num| FieldElement::from_str(&num.to_string()).unwrap()) + .map(|num| Felt::from_str(&num.to_string()).unwrap()) { payload.push(element); } @@ -361,9 +378,9 @@ impl MessageToStarknet { pub struct MessageToAppchain { pub from_address: ContractAddress, pub to_address: ContractAddress, - pub nonce: FieldElement, - pub selector: FieldElement, - pub payload: Vec, + pub nonce: Felt, + pub selector: Felt, + pub payload: Vec, } impl MessageToAppchain { @@ -378,17 +395,18 @@ impl MessageToAppchain { for message in messages { let serialized = message.serialize().unwrap(); for field_element in serialized { - let decimal = field_element.to_big_decimal(0); // Assuming no decimal places for simplicity - let num = decimal.to_string(); - seq.serialize_element(&num)?; + // let decimal: BigDecimal = field_element.to_bigint().into(); // Assuming no + // decimal places for simplicity let num = decimal.to_string(); + // seq.serialize_element(&num)?; + seq.serialize_element(&field_element)?; } } seq.end() } - pub fn serialize(&self) -> anyhow::Result> { + pub fn serialize(&self) -> anyhow::Result> { let mut result = vec![*self.from_address, *self.to_address, self.nonce, self.selector]; - result.push(FieldElement::from(self.payload.len())); + result.push(Felt::from(self.payload.len())); result.extend(self.payload.iter().cloned()); Ok(result) } @@ -415,27 +433,41 @@ impl MessageToAppchain { let mut messages = Vec::new(); while let Some(from_address) = seq .next_element::()? - .map(|num| FieldElement::from_str(&num.to_string()).unwrap()) + .map(|num| Felt::from_str(&num.to_string()).unwrap()) { let to_address = seq .next_element::()? - .map(|num| FieldElement::from_str(&num.to_string()).unwrap()) + .map(|num| Felt::from_str(&num.to_string()).unwrap()) .unwrap_or_default(); let nonce = seq .next_element::()? - .map(|num| FieldElement::from_str(&num.to_string()).unwrap()) + .map(|num| Felt::from_str(&num.to_string()).unwrap()) .unwrap_or_default(); let selector = seq .next_element::()? - .map(|num| FieldElement::from_str(&num.to_string()).unwrap()) + .map(|num| Felt::from_str(&num.to_string()).unwrap()) .unwrap_or_default(); + let payload_length_str = seq.next_element::()?.unwrap_or_default(); - let payload_length: usize = payload_length_str.parse().unwrap_or_default(); + // TODO: for compatibility reason, the length can be in either decimal or hex + // format. maybe should just expect all values to be in hex format. + let payload_length = payload_length_str + .parse::() + .or_else(|_| { + usize::from_str_radix( + payload_length_str + .strip_prefix("0x") + .unwrap_or(&payload_length_str), + 16, + ) + }) + .expect("invalid length value"); + let mut payload = Vec::new(); for _ in 0..payload_length { if let Some(element) = seq .next_element::()? - .map(|num| FieldElement::from_str(&num.to_string()).unwrap()) + .map(|num| Felt::from_str(&num.to_string()).unwrap()) { payload.push(element); } @@ -461,53 +493,52 @@ fn test_deserialize_input() -> anyhow::Result<()> { use std::str::FromStr; let input = r#"{ - "prev_state_root":"101", - "block_number":102, - "block_hash":"103", - "config_hash":"104", - "message_to_starknet_segment":["105","106","1","1"], - "message_to_appchain_segment":["108","109","110","111","1","112"], + "prev_state_root":"0x65", + "block_number": 102, + "block_hash":"0x67", + "config_hash":"0x68", + "message_to_starknet_segment":["0x69","0x6a","0x1","0x1"], + "message_to_appchain_segment":["0x6c","0x6d","0x6e","0x6f","0x1","0x70"], "storage_updates":{ - "42": { - "2010": "1200", - "2012": "1300" + "0x2a": { + "0x7dc": "0x514", + "0x7da": "0x4b0" } }, "nonce_updates":{ - "1111": "22222", - "1116": "22223" + "0x457": "0x56ce", + "0x45c": "0x56cf" }, "contract_updates":{ - "3": "437267489" + "0x3": "0x1a102c21" }, "declared_classes":{ - "1234": "12345" + "0x4d2": "0x3039" } }"#; - let mut expected = ProgramInput { - prev_state_root: FieldElement::from_str("101")?, + prev_state_root: Felt::from_str("101")?, block_number: 102, - block_hash: FieldElement::from_str("103")?, - config_hash: FieldElement::from_str("104")?, + block_hash: Felt::from_str("103")?, + config_hash: Felt::from_str("104")?, message_to_starknet_segment: vec![MessageToStarknet { - from_address: ContractAddress::from(FieldElement::from_str("105")?), - to_address: ContractAddress::from(FieldElement::from_str("106")?), - payload: vec![FieldElement::from_str("1")?], + from_address: ContractAddress::from(Felt::from_str("105")?), + to_address: ContractAddress::from(Felt::from_str("106")?), + payload: vec![Felt::from_str("1")?], }], message_to_appchain_segment: vec![MessageToAppchain { - from_address: ContractAddress::from(FieldElement::from_str("108")?), - to_address: ContractAddress::from(FieldElement::from_str("109")?), - nonce: FieldElement::from_str("110")?, - selector: FieldElement::from_str("111")?, - payload: vec![FieldElement::from_str("112")?], + from_address: ContractAddress::from(Felt::from_str("108")?), + to_address: ContractAddress::from(Felt::from_str("109")?), + nonce: Felt::from_str("110")?, + selector: Felt::from_str("111")?, + payload: vec![Felt::from_str("112")?], }], state_updates: StateUpdates { storage_updates: vec![( - ContractAddress::from(FieldElement::from_str("42")?), + ContractAddress::from(Felt::from_str("42")?), vec![ - (FieldElement::from_str("2010")?, FieldElement::from_str("1200")?), - (FieldElement::from_str("2012")?, FieldElement::from_str("1300")?), + (Felt::from_str("2010")?, Felt::from_str("1200")?), + (Felt::from_str("2012")?, Felt::from_str("1300")?), ] .into_iter() .collect(), @@ -516,43 +547,34 @@ fn test_deserialize_input() -> anyhow::Result<()> { .collect(), nonce_updates: vec![ - ( - ContractAddress::from(FieldElement::from_str("1111")?), - FieldElement::from_str("22222")?, - ), - ( - ContractAddress::from(FieldElement::from_str("1116")?), - FieldElement::from_str("22223")?, - ), + (ContractAddress::from(Felt::from_str("1111")?), Felt::from_str("22222")?), + (ContractAddress::from(Felt::from_str("1116")?), Felt::from_str("22223")?), ] .into_iter() .collect(), contract_updates: vec![( - ContractAddress::from(FieldElement::from_str("3")?), - FieldElement::from_str("437267489")?, + ContractAddress::from(Felt::from_str("3")?), + Felt::from_str("437267489")?, )] .into_iter() .collect(), - declared_classes: vec![( - FieldElement::from_str("1234")?, - FieldElement::from_str("12345")?, - )] - .into_iter() - .collect(), + declared_classes: vec![(Felt::from_str("1234")?, Felt::from_str("12345")?)] + .into_iter() + .collect(), }, world_da: None, }; let mut deserialized = serde_json::from_str::(input)?; assert_eq!(expected, deserialized); - deserialized.fill_da(FieldElement::from_str("42")?); + deserialized.fill_da(Felt::from_str("42")?); expected.world_da = Some(vec![ - FieldElement::from_str("2010")?, - FieldElement::from_str("1200")?, - FieldElement::from_str("2012")?, - FieldElement::from_str("1300")?, + Felt::from_str("2010")?, + Felt::from_str("1200")?, + Felt::from_str("2012")?, + Felt::from_str("1300")?, ]); Ok(()) @@ -563,28 +585,28 @@ fn test_serialize_input() -> anyhow::Result<()> { use std::str::FromStr; let input = ProgramInput { - prev_state_root: FieldElement::from_str("101")?, + prev_state_root: Felt::from_str("101")?, block_number: 102, - block_hash: FieldElement::from_str("103")?, - config_hash: FieldElement::from_str("104")?, + block_hash: Felt::from_str("103")?, + config_hash: Felt::from_str("104")?, message_to_starknet_segment: vec![MessageToStarknet { - from_address: ContractAddress::from(FieldElement::from_str("105")?), - to_address: ContractAddress::from(FieldElement::from_str("106")?), - payload: vec![FieldElement::from_str("1")?], + from_address: ContractAddress::from(Felt::from_str("105")?), + to_address: ContractAddress::from(Felt::from_str("106")?), + payload: vec![Felt::from_str("1")?], }], message_to_appchain_segment: vec![MessageToAppchain { - from_address: ContractAddress::from(FieldElement::from_str("108")?), - to_address: ContractAddress::from(FieldElement::from_str("109")?), - nonce: FieldElement::from_str("110")?, - selector: FieldElement::from_str("111")?, - payload: vec![FieldElement::from_str("112")?], + from_address: ContractAddress::from(Felt::from_str("108")?), + to_address: ContractAddress::from(Felt::from_str("109")?), + nonce: Felt::from_str("110")?, + selector: Felt::from_str("111")?, + payload: vec![Felt::from_str("112")?], }], state_updates: StateUpdates { storage_updates: vec![( - ContractAddress::from(FieldElement::from_str("42")?), + ContractAddress::from(Felt::from_str("42")?), vec![ - (FieldElement::from_str("2010")?, FieldElement::from_str("1200")?), - (FieldElement::from_str("2012")?, FieldElement::from_str("1300")?), + (Felt::from_str("2010")?, Felt::from_str("1200")?), + (Felt::from_str("2012")?, Felt::from_str("1300")?), ] .into_iter() .collect(), @@ -593,37 +615,28 @@ fn test_serialize_input() -> anyhow::Result<()> { .collect(), nonce_updates: vec![ - ( - ContractAddress::from(FieldElement::from_str("1111")?), - FieldElement::from_str("22222")?, - ), - ( - ContractAddress::from(FieldElement::from_str("1116")?), - FieldElement::from_str("22223")?, - ), + (ContractAddress::from(Felt::from_str("1111")?), Felt::from_str("22222")?), + (ContractAddress::from(Felt::from_str("1116")?), Felt::from_str("22223")?), ] .into_iter() .collect(), contract_updates: vec![( - ContractAddress::from(FieldElement::from_str("3")?), - FieldElement::from_str("437267489")?, + ContractAddress::from(Felt::from_str("3")?), + Felt::from_str("437267489")?, )] .into_iter() .collect(), - declared_classes: vec![( - FieldElement::from_str("1234")?, - FieldElement::from_str("12345")?, - )] - .into_iter() - .collect(), + declared_classes: vec![(Felt::from_str("1234")?, Felt::from_str("12345")?)] + .into_iter() + .collect(), }, world_da: Some(vec![ - FieldElement::from_str("2010")?, - FieldElement::from_str("1200")?, - FieldElement::from_str("2012")?, - FieldElement::from_str("1300")?, + Felt::from_str("2010")?, + Felt::from_str("1200")?, + Felt::from_str("2012")?, + Felt::from_str("1300")?, ]), }; @@ -637,31 +650,31 @@ fn test_serialize_input() -> anyhow::Result<()> { #[test] fn test_serialize_to_prover_args() -> anyhow::Result<()> { let input = r#"{ - "prev_state_root":"101", + "prev_state_root":"0x65", "block_number":102, - "block_hash":"103", - "config_hash":"104", + "block_hash":"0x67", + "config_hash":"0x68", "nonce_updates":{ - "1111": "22222" + "0x457": "0x56ce" }, "storage_updates":{ - "333": { - "4444": "555" + "0x14d": { + "0x115c": "0x22b" } }, "contract_updates":{ - "66666": "7777" + "0x1046a": "0x1e61" }, "declared_classes":{ - "88888": "99999" + "0x15b38": "0x1869f" }, - "message_to_starknet_segment":["123","456","123","128"], - "message_to_appchain_segment":["108","109","110","111","1","112"] + "message_to_starknet_segment":["0x7b","0x1c8","0x7b","0x80"], + "message_to_appchain_segment":["0x6c","0x6d","0x6e","0x6f","0x1","0x70"] }"#; let mut input = serde_json::from_str::(input)?; - input.fill_da(FieldElement::from_str("333")?); + input.fill_da(Felt::from_str("333")?); - println!("{:?}", input); + // println!("{:?}", input); let serialized = input.serialize_to_prover_args(); @@ -670,7 +683,7 @@ fn test_serialize_to_prover_args() -> anyhow::Result<()> { 4, 123, 456, 1, 128, 6, 108, 109, 110, 111, 1, 112, 1, 4444, 555, 0u64, ] .into_iter() - .map(FieldElement::from) + .map(Felt::from) .collect::>(); assert_eq!(serialized, expected); diff --git a/crates/saya/core/src/prover/state_diff.rs b/crates/saya/core/src/prover/state_diff.rs index 2155688533..3e68cd41f9 100644 --- a/crates/saya/core/src/prover/state_diff.rs +++ b/crates/saya/core/src/prover/state_diff.rs @@ -1,9 +1,9 @@ use katana_primitives::state::StateUpdates; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; pub struct ProvedStateDiff { - pub genesis_state_hash: FieldElement, - pub prev_state_hash: FieldElement, + pub genesis_state_hash: Felt, + pub prev_state_hash: Felt, pub state_updates: StateUpdates, } diff --git a/crates/saya/core/src/verifier/mod.rs b/crates/saya/core/src/verifier/mod.rs index 5cad2bb643..c9334456c8 100644 --- a/crates/saya/core/src/verifier/mod.rs +++ b/crates/saya/core/src/verifier/mod.rs @@ -7,7 +7,7 @@ //! an interface to query the on-chain verifier, but also //! submitting facts and proofs. -use ::starknet::core::types::FieldElement; +use ::starknet::core::types::Felt; use serde::{Deserialize, Serialize}; use crate::StarknetAccountData; @@ -17,16 +17,16 @@ mod starknet; /// Supported verifiers. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum VerifierIdentifier { - HerodotusStarknetSepolia(FieldElement), + HerodotusStarknetSepolia(Felt), StoneLocal, StarkwareEthereum, } pub async fn verify( verifier: VerifierIdentifier, - serialized_proof: Vec, + serialized_proof: Vec, account: StarknetAccountData, -) -> anyhow::Result<(String, FieldElement)> { +) -> anyhow::Result<(String, Felt)> { match verifier { VerifierIdentifier::HerodotusStarknetSepolia(fact_registry_address) => { starknet::starknet_verify(fact_registry_address, serialized_proof, account).await diff --git a/crates/saya/core/src/verifier/starknet.rs b/crates/saya/core/src/verifier/starknet.rs index 3c8f78f38e..5f5cbd8f95 100644 --- a/crates/saya/core/src/verifier/starknet.rs +++ b/crates/saya/core/src/verifier/starknet.rs @@ -4,7 +4,7 @@ use anyhow::Context; use dojo_world::migration::TxnConfig; use dojo_world::utils::TransactionExt; use starknet::accounts::{Account, Call, ConnectedAccount}; -use starknet::core::types::{FieldElement, TransactionExecutionStatus, TransactionStatus}; +use starknet::core::types::{Felt, TransactionExecutionStatus, TransactionStatus}; use starknet::core::utils::get_selector_from_name; use starknet::providers::Provider; use tokio::time::sleep; @@ -13,17 +13,17 @@ use crate::dojo_os::get_starknet_account; use crate::StarknetAccountData; pub async fn starknet_verify( - fact_registry_address: FieldElement, - serialized_proof: Vec, + fact_registry_address: Felt, + serialized_proof: Vec, starknet_config: StarknetAccountData, -) -> anyhow::Result<(String, FieldElement)> { +) -> anyhow::Result<(String, Felt)> { let txn_config = TxnConfig { wait: true, receipt: true, ..Default::default() }; let account = get_starknet_account(starknet_config)?; let account = account.lock().await; let nonce = account.get_nonce().await?; let tx = account - .execute(vec![Call { + .execute_v1(vec![Call { to: fact_registry_address, selector: get_selector_from_name("verify_and_register_fact").expect("invalid selector"), calldata: serialized_proof, diff --git a/crates/saya/provider/Cargo.toml b/crates/saya/provider/Cargo.toml index 4730c123e7..2c1d7f15df 100644 --- a/crates/saya/provider/Cargo.toml +++ b/crates/saya/provider/Cargo.toml @@ -23,6 +23,7 @@ flate2.workspace = true futures.workspace = true jsonrpsee = { workspace = true, features = [ "client" ] } lazy_static.workspace = true +num-traits.workspace = true serde.workspace = true serde_json.workspace = true serde_with.workspace = true diff --git a/crates/saya/provider/src/error.rs b/crates/saya/provider/src/error.rs index df3074c664..6a32acd45d 100644 --- a/crates/saya/provider/src/error.rs +++ b/crates/saya/provider/src/error.rs @@ -11,6 +11,6 @@ pub enum ProviderError { BlockNotFound(katana_primitives::block::BlockIdOrTag), #[error(transparent)] StarknetProvider(#[from] starknet::providers::ProviderError), - #[error(transparent)] - ValueOutOfRange(#[from] starknet::core::types::ValueOutOfRangeError), + #[error("Value out of range")] + ValueOutOfRange, } diff --git a/crates/saya/provider/src/provider.rs b/crates/saya/provider/src/provider.rs index 72e445c4d7..c0dafece58 100644 --- a/crates/saya/provider/src/provider.rs +++ b/crates/saya/provider/src/provider.rs @@ -1,7 +1,7 @@ use katana_primitives::block::{BlockNumber, SealedBlock}; use katana_primitives::state::StateUpdatesWithDeclaredClasses; use katana_rpc_types::trace::TxExecutionInfo; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use crate::ProviderResult; @@ -28,7 +28,7 @@ pub trait Provider { async fn fetch_state_updates( &self, block_number: BlockNumber, - ) -> ProviderResult<(StateUpdatesWithDeclaredClasses, Vec)>; + ) -> ProviderResult<(StateUpdatesWithDeclaredClasses, Vec)>; /// Fetches the transactions executions info for a given block. /// This method returns the all the executions info for each diff --git a/crates/saya/provider/src/rpc/mod.rs b/crates/saya/provider/src/rpc/mod.rs index e6a8ab8a3c..45e9993b05 100644 --- a/crates/saya/provider/src/rpc/mod.rs +++ b/crates/saya/provider/src/rpc/mod.rs @@ -15,8 +15,9 @@ use katana_primitives::transaction::TxWithHash; use katana_primitives::version::Version; use katana_rpc_api::saya::SayaApiClient; use katana_rpc_types::trace::TxExecutionInfo; +use num_traits::ToPrimitive; use starknet::core::types::{ - ContractClass, FieldElement, MaybePendingBlockWithTxs, MaybePendingStateUpdate, + ContractClass, Felt, MaybePendingBlockWithTxs, MaybePendingStateUpdate, }; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::{JsonRpcClient, Provider as StarknetProvider}; @@ -92,8 +93,8 @@ impl Provider for JsonRpcProvider { parent_hash: block.parent_hash, number: block.block_number, gas_prices: GasPrices::new( - block.l1_gas_price.price_in_wei.try_into().unwrap(), - block.l1_gas_price.price_in_fri.try_into().unwrap(), + block.l1_gas_price.price_in_wei.to_u128().unwrap(), + block.l1_gas_price.price_in_fri.to_u128().unwrap(), ), timestamp: block.timestamp, state_root: block.new_root, @@ -108,7 +109,7 @@ impl Provider for JsonRpcProvider { async fn fetch_state_updates( &self, block_number: BlockNumber, - ) -> ProviderResult<(StateUpdatesWithDeclaredClasses, Vec)> { + ) -> ProviderResult<(StateUpdatesWithDeclaredClasses, Vec)> { let rpc_state_update = match self .starknet_provider .get_state_update(BlockIdOrTag::Number(block_number)) diff --git a/crates/saya/provider/src/rpc/state.rs b/crates/saya/provider/src/rpc/state.rs index 072b30c939..fa359b3789 100644 --- a/crates/saya/provider/src/rpc/state.rs +++ b/crates/saya/provider/src/rpc/state.rs @@ -15,9 +15,10 @@ use std::collections::{HashMap, HashSet}; use alloy_primitives::U256; use katana_primitives::contract::ContractAddress; use katana_primitives::state::StateUpdates; +use num_traits::ToPrimitive; use starknet::core::types::{ - ContractStorageDiffItem, DeclaredClassItem, DeployedContractItem, FieldElement, NonceUpdate, - StateDiff, StateUpdate, + ContractStorageDiffItem, DeclaredClassItem, DeployedContractItem, Felt, NonceUpdate, StateDiff, + StateUpdate, }; use crate::ProviderResult; @@ -26,7 +27,6 @@ use crate::ProviderResult; const CLASS_INFO_FLAG_TRUE: &str = "100000000000000000000000000000000"; /// Converts the [`StateUpdate`] RPC type into [`StateUpdate`] Katana primitive. -/// /// # Arguments /// /// * `state_update` - The RPC state update to convert. @@ -65,7 +65,7 @@ pub fn state_updates_from_rpc(state_update: &StateUpdate) -> ProviderResult`]. +/// Converts the [`StateDiff`] from RPC types into a [`Vec`]. /// /// Currently, Katana does not support `replaced_classes` and `deprecated_declared_classes`: /// . @@ -76,7 +76,7 @@ pub fn state_updates_from_rpc(state_update: &StateUpdate) -> ProviderResult Vec { +pub fn state_diff_to_felts(state_diff: &StateDiff) -> Vec { let mut data = vec![]; // Order matters here, storage then nonce then deployed. @@ -100,17 +100,14 @@ pub fn state_diff_to_felts(state_diff: &StateDiff) -> Vec { /// Serializes for the DA all the contracts that have at least one storage update. /// This may include nonce and/or deployed-declared updates. -/// Returns a [`HashSet`] of all the contract addresses that +/// Returns a [`HashSet`] of all the contract addresses that /// were uniquely processed. /// /// # Arguments /// /// * `state_diff` - The state diff to process. /// * `out` - The output buffer to serialize into. -fn serialize_storage_updates( - state_diff: &StateDiff, - out: &mut Vec, -) -> HashSet { +fn serialize_storage_updates(state_diff: &StateDiff, out: &mut Vec) -> HashSet { let mut processed_addresses = HashSet::new(); for contract_diff in &state_diff.storage_diffs { @@ -154,8 +151,8 @@ fn serialize_storage_updates( /// * `out` - The output buffer to serialize into. fn serialize_nonce_updates( state_diff: &StateDiff, - processed_addresses: &mut HashSet, - out: &mut Vec, + processed_addresses: &mut HashSet, + out: &mut Vec, ) { for nonce_update in &state_diff.nonces { let NonceUpdate { contract_address, nonce: new_nonce } = *nonce_update; @@ -189,8 +186,8 @@ fn serialize_nonce_updates( /// * `out` - The output buffer to serialize into. fn serialize_deployed_updates( state_diff: &StateDiff, - processed_addresses: &mut HashSet, - out: &mut Vec, + processed_addresses: &mut HashSet, + out: &mut Vec, ) { for deployed in &state_diff.deployed_contracts { let DeployedContractItem { address, class_hash } = *deployed; @@ -217,10 +214,10 @@ fn serialize_deployed_updates( /// * `is_storage_only` - True if the contract address was only modified with storage updates. False /// if the contract was deployed or it's class hash replaced during this state update. fn compute_update_meta_info( - new_nonce: Option, + new_nonce: Option, n_storage_updates: u64, is_storage_only: bool, -) -> FieldElement { +) -> Felt { let mut meta = if is_storage_only { U256::from(0) } else { @@ -229,13 +226,13 @@ fn compute_update_meta_info( if let Some(nonce) = new_nonce { // At the moment, v0.11 and forward are packing the nonce into 64 bits. - let nonce_u64: u64 = nonce.try_into().expect("Nonce too large for DA serialization"); + let nonce_u64: u64 = nonce.to_u64().expect("Nonce too large for DA serialization"); meta += U256::from((nonce_u64 as u128) << 64) } meta += U256::from(n_storage_updates); - FieldElement::from_hex_be(format!("0x{:064x}", meta).as_str()).unwrap() + Felt::from_hex(format!("0x{:064x}", meta).as_str()).unwrap() } #[cfg(test)] @@ -247,13 +244,13 @@ mod tests { #[test] fn compute_update_meta_info_no_flag() { - let info = compute_update_meta_info(Some(FieldElement::ONE), 1, true); + let info = compute_update_meta_info(Some(Felt::ONE), 1, true); assert_eq!(info, felt!("0x00000000000000010000000000000001")); } #[test] fn compute_update_meta_info_with_flag() { - let info = compute_update_meta_info(Some(FieldElement::ONE), 1, false); + let info = compute_update_meta_info(Some(Felt::ONE), 1, false); assert_eq!(info, felt!("0x100000000000000010000000000000001")); } diff --git a/crates/saya/provider/src/rpc/transaction.rs b/crates/saya/provider/src/rpc/transaction.rs index bbc39b316b..4632975ed8 100644 --- a/crates/saya/provider/src/rpc/transaction.rs +++ b/crates/saya/provider/src/rpc/transaction.rs @@ -4,8 +4,9 @@ use katana_primitives::transaction::{ DeclareTx, DeclareTxV1, DeclareTxV2, DeclareTxV3, DeployAccountTx, DeployAccountTxV1, DeployAccountTxV3, InvokeTx, InvokeTxV1, InvokeTxV3, L1HandlerTx, Tx, TxWithHash, }; +use num_traits::ToPrimitive; use starknet::core::types::{ - DeclareTransaction, DeployAccountTransaction, FieldElement, InvokeTransaction, Transaction, + DeclareTransaction, DeployAccountTransaction, InvokeTransaction, Transaction, }; use crate::ProviderResult; @@ -17,7 +18,7 @@ pub fn tx_from_rpc(tx_rpc: &Transaction, chain_id: ChainId) -> ProviderResult ProviderResult Ok(TxWithHash { hash: tx.transaction_hash, transaction: Tx::Invoke(InvokeTx::V1(InvokeTxV1 { - max_fee: tx.max_fee.try_into()?, + max_fee: tx.max_fee.to_u128().expect("valid u128"), chain_id, calldata: tx.calldata.clone(), signature: tx.signature.clone(), @@ -62,7 +63,7 @@ pub fn tx_from_rpc(tx_rpc: &Transaction, chain_id: ChainId) -> ProviderResult ProviderResult Ok(TxWithHash { hash: tx.transaction_hash, transaction: Tx::Declare(DeclareTx::V1(DeclareTxV1 { - max_fee: tx.max_fee.try_into()?, + max_fee: tx.max_fee.to_u128().expect("valid u128"), chain_id, class_hash: tx.class_hash, signature: tx.signature.clone(), @@ -86,7 +87,7 @@ pub fn tx_from_rpc(tx_rpc: &Transaction, chain_id: ChainId) -> ProviderResult ProviderResult ProviderResult Result { + pub fn deploy_account_address(&self) -> Result { let undeployed_status = match &self.deployment { DeploymentStatus::Undeployed(value) => value, DeploymentStatus::Deployed(_) => { @@ -54,7 +52,7 @@ impl AccountConfig { undeployed_status.salt, undeployed_status.class_hash, &[oz.public_key], - FieldElement::ZERO, + Felt::ZERO, )), } } @@ -71,7 +69,7 @@ pub enum AccountVariant { pub struct OzAccountConfig { pub version: u64, #[serde_as(as = "UfeHex")] - pub public_key: FieldElement, + pub public_key: Felt, #[serde(default = "true_as_default")] pub legacy: bool, } @@ -84,7 +82,7 @@ pub enum DeploymentStatus { } impl DeploymentStatus { - pub fn to_deployed(&mut self, address: FieldElement) { + pub fn to_deployed(&mut self, address: Felt) { match self { DeploymentStatus::Undeployed(status) => { *self = DeploymentStatus::Deployed(DeployedStatus { @@ -103,27 +101,27 @@ impl DeploymentStatus { #[derive(Serialize, Deserialize)] pub struct UndeployedStatus { #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "UfeHex")] - pub salt: FieldElement, + pub salt: Felt, } #[serde_as] #[derive(Serialize, Deserialize)] pub struct DeployedStatus { #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, + pub class_hash: Felt, #[serde_as(as = "UfeHex")] - pub address: FieldElement, + pub address: Felt, } enum MaxFeeType { - Manual { max_fee: FieldElement }, - Estimated { estimate: FieldElement, estimate_with_buffer: FieldElement }, + Manual { max_fee: Felt }, + Estimated { estimate: Felt, estimate_with_buffer: Felt }, } impl MaxFeeType { - pub fn max_fee(&self) -> FieldElement { + pub fn max_fee(&self) -> Felt { match self { Self::Manual { max_fee } => *max_fee, Self::Estimated { estimate_with_buffer, .. } => *estimate_with_buffer, @@ -133,7 +131,7 @@ impl MaxFeeType { #[derive(Debug)] pub enum FeeSetting { - Manual(FieldElement), + Manual(Felt), EstimateOnly, None, } @@ -191,7 +189,7 @@ pub async fn deploy( provider: JsonRpcClient, signer: LocalWallet, txn_action: TxnAction, - nonce: Option, + nonce: Option, poll_interval: u64, file: PathBuf, no_confirmation: bool, @@ -236,7 +234,7 @@ pub async fn deploy( } }; - let account_deployment = factory.deploy(undeployed_status.salt); + let account_deployment = factory.deploy_v1(undeployed_status.salt); let target_deployment_address = account.deploy_account_address()?; @@ -268,10 +266,10 @@ pub async fn deploy( let fee_estimate_multiplier = fee_estimate_multiplier.unwrap_or(1.1); - let estimated_fee_with_buffer = (((TryInto::::try_into(estimated_fee)? as f64) - * fee_estimate_multiplier) - as u64) - .into(); + let estimated_fee_with_buffer = + (((estimated_fee.to_u64().context("Invalid u64")? as f64) + * fee_estimate_multiplier) as u64) + .into(); MaxFeeType::Estimated { estimate: estimated_fee, @@ -308,7 +306,9 @@ pub async fn deploy( })? .overall_fee; - println!("{} ETH", format!("{}", estimated_fee.to_big_decimal(18)).bright_yellow()); + let decimal = utils::felt_to_bigdecimal(estimated_fee, 18); + println!("{} ETH", format!("{decimal}").bright_yellow()); + Ok(()) } TxnAction::Simulate => { @@ -322,9 +322,9 @@ pub async fn deploy( async fn do_account_deploy( max_fee: MaxFeeType, txn_config: TxnConfig, - target_deployment_address: FieldElement, + target_deployment_address: Felt, no_confirmation: bool, - account_deployment: starknet::accounts::AccountDeployment< + account_deployment: starknet::accounts::AccountDeploymentV1< '_, OpenZeppelinAccountFactory>, >, @@ -337,16 +337,17 @@ async fn do_account_deploy( eprintln!( "You've manually specified the account deployment fee to be {}. Therefore, fund \ at least:\n {}", - format!("{} ETH", max_fee.to_big_decimal(18)).bright_yellow(), - format!("{} ETH", max_fee.to_big_decimal(18)).bright_yellow(), + format!("{} ETH", utils::felt_to_bigdecimal(max_fee, 18)).bright_yellow(), + format!("{} ETH", utils::felt_to_bigdecimal(max_fee, 18)).bright_yellow(), ); } MaxFeeType::Estimated { estimate, estimate_with_buffer } => { eprintln!( "The estimated account deployment fee is {}. However, to avoid failure, fund at \ least:\n {}", - format!("{} ETH", estimate.to_big_decimal(18)).bright_yellow(), - format!("{} ETH", estimate_with_buffer.to_big_decimal(18)).bright_yellow() + format!("{} ETH", utils::felt_to_bigdecimal(estimate, 18)).bright_yellow(), + format!("{} ETH", utils::felt_to_bigdecimal(estimate_with_buffer, 18)) + .bright_yellow() ); } } @@ -412,7 +413,7 @@ fn write_account_to_file(file: PathBuf, account: AccountConfig) -> Result<(), an } async fn simulate_account_deploy( - account_deployment: &starknet::accounts::AccountDeployment< + account_deployment: &starknet::accounts::AccountDeploymentV1< '_, OpenZeppelinAccountFactory>, >, @@ -430,7 +431,7 @@ pub async fn fetch( provider: JsonRpcClient, force: bool, output: PathBuf, - address: FieldElement, + address: Felt, ) -> Result<()> { if output.exists() && !force { anyhow::bail!("account config file already exists"); diff --git a/crates/sozo/ops/src/auth.rs b/crates/sozo/ops/src/auth.rs index 9edb851b48..5abdaec4a2 100644 --- a/crates/sozo/ops/src/auth.rs +++ b/crates/sozo/ops/src/auth.rs @@ -8,21 +8,20 @@ use dojo_world::migration::TxnConfig; use dojo_world::utils::TransactionExt; use scarb_ui::Ui; use starknet::accounts::{Account, ConnectedAccount}; -use starknet::core::types::{BlockId, BlockTag}; +use starknet::core::types::{BlockId, BlockTag, Felt}; use starknet::core::utils::{get_selector_from_name, parse_cairo_short_string}; -use starknet_crypto::FieldElement; use crate::utils; #[derive(Debug, Clone, PartialEq)] pub enum ResourceType { Contract(String), - Model(FieldElement), + Model(Felt), } #[derive(Debug, Clone, PartialEq)] pub struct ModelContract { - pub model: FieldElement, + pub model: Felt, pub contract: String, } @@ -50,7 +49,7 @@ impl FromStr for ModelContract { #[derive(Debug, Clone, PartialEq)] pub struct OwnerResource { pub resource: ResourceType, - pub owner: FieldElement, + pub owner: Felt, } impl FromStr for OwnerResource { @@ -67,7 +66,7 @@ impl FromStr for OwnerResource { ), }; - let owner = FieldElement::from_hex_be(owner_part) + let owner = Felt::from_hex(owner_part) .map_err(|_| anyhow::anyhow!("Invalid owner address: {}", owner_part))?; let resource_parts = resource_part.split_once(':'); @@ -129,7 +128,7 @@ where if !calls.is_empty() { let res = world .account - .execute(calls) + .execute_v1(calls) .send_with_cfg(&txn_config) .await .with_context(|| "Failed to send transaction")?; @@ -178,7 +177,7 @@ where let res = world .account - .execute(calls) + .execute_v1(calls) .send_with_cfg(&txn_config) .await .with_context(|| "Failed to send transaction")?; @@ -235,7 +234,7 @@ where if !calls.is_empty() { let res = world .account - .execute(calls) + .execute_v1(calls) .send_with_cfg(&txn_config) .await .with_context(|| "Failed to send transaction")?; @@ -284,7 +283,7 @@ where let res = world .account - .execute(calls) + .execute_v1(calls) .send_with_cfg(&txn_config) .await .with_context(|| "Failed to send transaction")?; diff --git a/crates/sozo/ops/src/call.rs b/crates/sozo/ops/src/call.rs index 14bb487b5b..3f3a125f40 100644 --- a/crates/sozo/ops/src/call.rs +++ b/crates/sozo/ops/src/call.rs @@ -1,6 +1,6 @@ use anyhow::{Context, Result}; use dojo_world::contracts::WorldContractReader; -use starknet::core::types::{BlockId, BlockTag, FieldElement, FunctionCall}; +use starknet::core::types::{BlockId, BlockTag, Felt, FunctionCall}; use starknet::core::utils::get_selector_from_name; use starknet::providers::Provider; @@ -10,7 +10,7 @@ pub async fn call( world_reader: WorldContractReader

, contract: String, entrypoint: String, - calldata: Vec, + calldata: Vec, block_id: Option, ) -> Result<()> { let contract_address = get_contract_address_from_reader(&world_reader, contract).await?; diff --git a/crates/sozo/ops/src/events.rs b/crates/sozo/ops/src/events.rs index b567157201..4c7073929a 100644 --- a/crates/sozo/ops/src/events.rs +++ b/crates/sozo/ops/src/events.rs @@ -6,7 +6,7 @@ use cainome::parser::tokens::{CompositeInner, CompositeInnerKind, CoreBasic, Tok use cainome::parser::AbiParser; use camino::Utf8PathBuf; use dojo_world::manifest::{AbiFormat, DeploymentManifest, ManifestMethods, MANIFESTS_DIR}; -use starknet::core::types::{BlockId, EventFilter, FieldElement}; +use starknet::core::types::{BlockId, EventFilter, Felt}; use starknet::core::utils::{parse_cairo_short_string, starknet_keccak}; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::{JsonRpcClient, Provider}; @@ -15,7 +15,7 @@ pub fn get_event_filter( from_block: Option, to_block: Option, events: Option>, - world_address: Option, + world_address: Option, ) -> EventFilter { let from_block = from_block.map(BlockId::Number); let to_block = to_block.map(BlockId::Number); @@ -143,11 +143,7 @@ fn parse_and_print_events( Ok(()) } -fn parse_core_basic( - cb: &CoreBasic, - value: &FieldElement, - include_felt_string: bool, -) -> Result { +fn parse_core_basic(cb: &CoreBasic, value: &Felt, include_felt_string: bool) -> Result { match cb.type_name().as_str() { "felt252" => { let hex = format!("{:#x}", value); @@ -159,7 +155,7 @@ fn parse_core_basic( } } "bool" => { - if *value == FieldElement::ZERO { + if *value == Felt::ZERO { Ok("false".to_string()) } else { Ok("true".to_string()) @@ -198,8 +194,8 @@ fn parse_event( fn process_inners( inners: &[CompositeInner], - data: &mut VecDeque, - keys: &mut VecDeque, + data: &mut VecDeque, + keys: &mut VecDeque, ) -> Result { let mut ret = String::new(); @@ -362,21 +358,21 @@ mod tests { let event = EmittedEvent { keys: vec![starknet_keccak("TestEvent".as_bytes())], data: vec![ - FieldElement::from_hex_be("0x5465737431").unwrap(), - FieldElement::from(1u8), // bool true - FieldElement::from(1u8), - FieldElement::from(2u16), - FieldElement::from(3u32), - FieldElement::from(4u64), - FieldElement::from(5u128), - FieldElement::from(6usize), - FieldElement::from_hex_be("0x54657374").unwrap(), - FieldElement::from_hex_be("0x54657374").unwrap(), + Felt::from_hex("0x5465737431").unwrap(), + Felt::from(1u8), // bool true + Felt::from(1u8), + Felt::from(2u16), + Felt::from(3u32), + Felt::from(4u64), + Felt::from(5u128), + Felt::from(6usize), + Felt::from_hex("0x54657374").unwrap(), + Felt::from_hex("0x54657374").unwrap(), ], - from_address: FieldElement::from_hex_be("0x123").unwrap(), - block_hash: FieldElement::from_hex_be("0x456").ok(), + from_address: Felt::from_hex("0x123").unwrap(), + block_hash: Felt::from_hex("0x456").ok(), block_number: Some(1), - transaction_hash: FieldElement::from_hex_be("0x789").unwrap(), + transaction_hash: Felt::from_hex("0x789").unwrap(), }; let expected_output = "Event name: dojo::world::world::TestEvent\nfelt252: 0x5465737431 \ @@ -432,16 +428,16 @@ mod tests { let event = EmittedEvent { keys: vec![starknet_keccak("StoreDelRecord".as_bytes())], data: vec![ - FieldElement::from_hex_be("0x54657374").unwrap(), - FieldElement::from(3u128), - FieldElement::from_hex_be("0x5465737431").unwrap(), - FieldElement::from_hex_be("0x5465737432").unwrap(), - FieldElement::from_hex_be("0x5465737433").unwrap(), + Felt::from_hex("0x54657374").unwrap(), + Felt::from(3u128), + Felt::from_hex("0x5465737431").unwrap(), + Felt::from_hex("0x5465737432").unwrap(), + Felt::from_hex("0x5465737433").unwrap(), ], - from_address: FieldElement::from_hex_be("0x123").unwrap(), - block_hash: FieldElement::from_hex_be("0x456").ok(), + from_address: Felt::from_hex("0x123").unwrap(), + block_hash: Felt::from_hex("0x456").ok(), block_number: Some(1), - transaction_hash: FieldElement::from_hex_be("0x789").unwrap(), + transaction_hash: Felt::from_hex("0x789").unwrap(), }; let expected_output = "Event name: dojo::world::world::StoreDelRecord\ntable: 0x54657374 \ @@ -508,14 +504,14 @@ mod tests { let event = EmittedEvent { keys: vec![ starknet_keccak("CustomEvent".as_bytes()), - FieldElement::from(3u128), - FieldElement::from_hex_be("0x5465737431").unwrap(), + Felt::from(3u128), + Felt::from_hex("0x5465737431").unwrap(), ], - data: vec![FieldElement::from(1u128), FieldElement::from(2u128)], - from_address: FieldElement::from_hex_be("0x123").unwrap(), - block_hash: FieldElement::from_hex_be("0x456").ok(), + data: vec![Felt::from(1u128), Felt::from(2u128)], + from_address: Felt::from_hex("0x123").unwrap(), + block_hash: Felt::from_hex("0x456").ok(), block_number: Some(1), - transaction_hash: FieldElement::from_hex_be("0x789").unwrap(), + transaction_hash: Felt::from_hex("0x789").unwrap(), }; let expected_output = "Event name: dojo::world::world::CustomEvent\nkey_1: 3\nkey_2: \ @@ -570,16 +566,16 @@ mod tests { let event = EmittedEvent { keys: vec![starknet_keccak("StoreDelRecord".as_bytes())], data: vec![ - FieldElement::from_hex_be("0x0").unwrap(), - FieldElement::from(3u128), - FieldElement::from_hex_be("0x0").unwrap(), - FieldElement::from_hex_be("0x1").unwrap(), - FieldElement::from_hex_be("0x2").unwrap(), + Felt::from_hex("0x0").unwrap(), + Felt::from(3u128), + Felt::from_hex("0x0").unwrap(), + Felt::from_hex("0x1").unwrap(), + Felt::from_hex("0x2").unwrap(), ], - from_address: FieldElement::from_hex_be("0x123").unwrap(), - block_hash: FieldElement::from_hex_be("0x456").ok(), + from_address: Felt::from_hex("0x123").unwrap(), + block_hash: Felt::from_hex("0x456").ok(), block_number: Some(1), - transaction_hash: FieldElement::from_hex_be("0x789").unwrap(), + transaction_hash: Felt::from_hex("0x789").unwrap(), }; let expected_output = "Event name: dojo::world::world::StoreDelRecord\ntable: 0x0\nkeys: \ diff --git a/crates/sozo/ops/src/execute.rs b/crates/sozo/ops/src/execute.rs index ad5054b14a..5fc69a9727 100644 --- a/crates/sozo/ops/src/execute.rs +++ b/crates/sozo/ops/src/execute.rs @@ -4,7 +4,7 @@ use dojo_world::migration::TxnConfig; use dojo_world::utils::TransactionExt; use scarb_ui::Ui; use starknet::accounts::{Call, ConnectedAccount}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::core::utils::get_selector_from_name; use crate::utils; @@ -13,7 +13,7 @@ pub async fn execute( ui: &Ui, contract: String, entrypoint: String, - calldata: Vec, + calldata: Vec, world: &WorldContract, txn_config: &TxnConfig, ) -> Result<()> @@ -23,7 +23,7 @@ where let contract_address = utils::get_contract_address(world, contract).await?; let res = world .account - .execute(vec![Call { + .execute_v1(vec![Call { calldata, to: contract_address, selector: get_selector_from_name(&entrypoint)?, diff --git a/crates/sozo/ops/src/keystore.rs b/crates/sozo/ops/src/keystore.rs index fcfa19d902..0f3adb15a2 100644 --- a/crates/sozo/ops/src/keystore.rs +++ b/crates/sozo/ops/src/keystore.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use anyhow::{bail, Result}; use colored::Colorize; use starknet::signers::SigningKey; -use starknet_crypto::FieldElement; +use starknet_crypto::Felt; pub fn new(password: Option, force: bool, file: PathBuf) -> Result<()> { if file.exists() && !force { @@ -36,7 +36,7 @@ pub fn from_key( } else { rpassword::prompt_password("Enter private key: ")? }; - let private_key = FieldElement::from_hex_be(private_key.trim())?; + let private_key = Felt::from_hex(private_key.trim())?; let password = get_password(password, false)?; diff --git a/crates/sozo/ops/src/migration/migrate.rs b/crates/sozo/ops/src/migration/migrate.rs index 1ab610e24e..d948f9305c 100644 --- a/crates/sozo/ops/src/migration/migrate.rs +++ b/crates/sozo/ops/src/migration/migrate.rs @@ -23,13 +23,12 @@ use scarb::core::Workspace; use scarb_ui::Ui; use starknet::accounts::ConnectedAccount; use starknet::core::types::{ - BlockId, BlockTag, FunctionCall, InvokeTransactionResult, StarknetError, + BlockId, BlockTag, Felt, FunctionCall, InvokeTransactionResult, StarknetError, }; use starknet::core::utils::{ cairo_short_string_to_felt, get_contract_address, get_selector_from_name, }; use starknet::providers::{Provider, ProviderError}; -use starknet_crypto::FieldElement; use tokio::fs; use super::ui::{bold_message, italic_message, MigrationUi}; @@ -41,7 +40,7 @@ pub fn prepare_migration( target_dir: &Utf8PathBuf, diff: WorldDiff, name: &str, - world_address: Option, + world_address: Option, ui: &Ui, ) -> Result { ui.print_step(3, "📦", "Preparing for migration..."); @@ -128,7 +127,7 @@ where A::SignError: 'static, { let ui = ws.config().ui(); - let mut world_tx_hash: Option = None; + let mut world_tx_hash: Option = None; let mut world_block_number: Option = None; match &strategy.base { @@ -256,7 +255,7 @@ where /// on success. async fn upload_on_ipfs_and_create_resource( ui: &Ui, - resource_id: FieldElement, + resource_id: Felt, metadata: ResourceMetadata, ) -> Result { match metadata.upload().await { @@ -277,10 +276,7 @@ async fn upload_on_ipfs_and_create_resource( /// # Returns /// A [`ResourceData`] object to register in the Dojo resource register /// on success. -fn create_resource_metadata( - resource_id: FieldElement, - hash: String, -) -> Result { +fn create_resource_metadata(resource_id: Felt, hash: String) -> Result { let metadata_uri = cairo_utils::encode_uri(&format!("ipfs://{hash}"))?; Ok(world::ResourceMetadata { resource_id, metadata_uri }) } @@ -321,7 +317,7 @@ where if migration_output.world_tx_hash.is_some() { match dojo_metadata.world.upload().await { Ok(hash) => { - let resource = create_resource_metadata(FieldElement::ZERO, hash.clone())?; + let resource = create_resource_metadata(Felt::ZERO, hash.clone())?; ui.print_sub(format!("world: ipfs://{}", hash)); resources.push(resource); } @@ -374,7 +370,7 @@ where let calls = resources.iter().map(|r| world.set_metadata_getcall(r)).collect::>(); let InvokeTransactionResult { transaction_hash } = - migrator.execute(calls).send_with_cfg(&txn_config).await.map_err(|e| { + migrator.execute_v1(calls).send_with_cfg(&txn_config).await.map_err(|e| { ui.verbose(format!("{e:?}")); anyhow!("Failed to register metadata into the resource registry: {e}") })?; @@ -394,7 +390,7 @@ where async fn register_dojo_models( models: &[ClassMigration], - world_address: FieldElement, + world_address: Felt, migrator: A, ui: &Ui, txn_config: &TxnConfig, @@ -405,7 +401,7 @@ where { if models.is_empty() { return Ok(RegisterOutput { - transaction_hash: FieldElement::ZERO, + transaction_hash: Felt::ZERO, declare_output: vec![], registered_model_names: vec![], }); @@ -455,7 +451,7 @@ where .collect::>(); let InvokeTransactionResult { transaction_hash } = - world.account.execute(calls).send_with_cfg(txn_config).await.map_err(|e| { + world.account.execute_v1(calls).send_with_cfg(txn_config).await.map_err(|e| { ui.verbose(format!("{e:?}")); anyhow!("Failed to register models to World: {e}") })?; @@ -469,7 +465,7 @@ where async fn register_dojo_contracts( contracts: &Vec, - world_address: FieldElement, + world_address: Felt, migrator: A, ui: &Ui, txn_config: &TxnConfig, @@ -558,7 +554,7 @@ where async fn deploy_contract( contract: &ContractMigration, contract_id: &str, - constructor_calldata: Vec, + constructor_calldata: Vec, migrator: A, ui: &Ui, txn_config: &TxnConfig, @@ -600,8 +596,8 @@ where async fn upgrade_contract( contract: &ContractMigration, contract_id: &str, - original_class_hash: FieldElement, - original_base_class_hash: FieldElement, + original_class_hash: Felt, + original_base_class_hash: Felt, migrator: A, ui: &Ui, txn_config: &TxnConfig, @@ -656,7 +652,7 @@ pub fn handle_artifact_error(ui: &Ui, artifact_path: &Path, error: anyhow::Error pub async fn get_contract_operation_name

( provider: P, contract: &ContractMigration, - world_address: Option, + world_address: Option, ) -> String where P: Provider + Sync + Send, @@ -698,7 +694,7 @@ pub async fn print_strategy

( ui: &Ui, provider: P, strategy: &MigrationStrategy, - world_address: FieldElement, + world_address: Felt, ) where P: Provider + Sync + Send, { @@ -756,7 +752,7 @@ pub async fn update_manifests_and_abis( manifest_dir: &Utf8PathBuf, profile_name: &str, rpc_url: &str, - world_address: FieldElement, + world_address: Felt, migration_output: Option, salt: &str, ) -> Result<()> { @@ -809,7 +805,7 @@ pub async fn update_manifests_and_abis( } local_manifest.contracts.iter_mut().for_each(|contract| { - if contract.inner.base_class_hash != FieldElement::ZERO { + if contract.inner.base_class_hash != Felt::ZERO { let salt = generate_salt(&contract.name); contract.inner.address = Some(get_contract_address( salt, diff --git a/crates/sozo/ops/src/migration/mod.rs b/crates/sozo/ops/src/migration/mod.rs index 915fb5fa5e..e234759dff 100644 --- a/crates/sozo/ops/src/migration/mod.rs +++ b/crates/sozo/ops/src/migration/mod.rs @@ -13,7 +13,7 @@ use dojo_world::migration::world::WorldDiff; use dojo_world::migration::{DeployOutput, TxnConfig, UpgradeOutput}; use scarb::core::Workspace; use starknet::accounts::ConnectedAccount; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; mod auto_auth; mod migrate; @@ -29,8 +29,8 @@ use self::ui::MigrationUi; #[derive(Debug, Default, Clone)] pub struct MigrationOutput { - pub world_address: FieldElement, - pub world_tx_hash: Option, + pub world_address: Felt, + pub world_tx_hash: Option, pub world_block_number: Option, // Represents if full migration got completeled. // If false that means migration got partially completed. @@ -43,14 +43,14 @@ pub struct MigrationOutput { #[derive(Debug, Default, Clone)] pub struct ContractMigrationOutput { pub name: String, - pub contract_address: FieldElement, - pub base_class_hash: FieldElement, + pub contract_address: Felt, + pub base_class_hash: Felt, } #[allow(clippy::too_many_arguments)] pub async fn migrate( ws: &Workspace<'_>, - world_address: Option, + world_address: Option, rpc_url: String, account: A, name: &str, @@ -174,7 +174,7 @@ where #[allow(dead_code)] enum ContractDeploymentOutput { - AlreadyDeployed(FieldElement), + AlreadyDeployed(Felt), Output(DeployOutput), } diff --git a/crates/sozo/ops/src/migration/utils.rs b/crates/sozo/ops/src/migration/utils.rs index 1afe38f305..88a52a8e13 100644 --- a/crates/sozo/ops/src/migration/utils.rs +++ b/crates/sozo/ops/src/migration/utils.rs @@ -6,7 +6,7 @@ use dojo_world::manifest::{ }; use scarb_ui::Ui; use starknet::accounts::ConnectedAccount; -use starknet_crypto::FieldElement; +use starknet::core::types::Felt; use super::ui::MigrationUi; @@ -16,7 +16,7 @@ use super::ui::MigrationUi; pub(super) async fn load_world_manifests( profile_dir: &Utf8PathBuf, account: A, - world_address: Option, + world_address: Option, ui: &Ui, skip_migration: Option>, ) -> Result<(BaseManifest, Option)> diff --git a/crates/sozo/ops/src/model.rs b/crates/sozo/ops/src/model.rs index 1bfe108e96..8bf245c3ea 100644 --- a/crates/sozo/ops/src/model.rs +++ b/crates/sozo/ops/src/model.rs @@ -3,7 +3,8 @@ use cainome::cairo_serde::{ByteArray, CairoSerde}; use dojo_types::schema::Ty; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::world::WorldContractReader; -use starknet::core::types::{BlockId, BlockTag, FieldElement}; +use num_traits::ToPrimitive; +use starknet::core::types::{BlockId, BlockTag, Felt}; use starknet::core::utils::get_selector_from_name; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; @@ -12,7 +13,7 @@ const INDENT: &str = " "; pub async fn model_class_hash( name: String, - world_address: FieldElement, + world_address: Felt, provider: JsonRpcClient, ) -> Result<()> { let mut world_reader = WorldContractReader::new(world_address, &provider); @@ -27,7 +28,7 @@ pub async fn model_class_hash( pub async fn model_contract_address( name: String, - world_address: FieldElement, + world_address: Felt, provider: JsonRpcClient, ) -> Result<()> { let mut world_reader = WorldContractReader::new(world_address, &provider); @@ -42,7 +43,7 @@ pub async fn model_contract_address( pub async fn model_layout( name: String, - world_address: FieldElement, + world_address: Felt, provider: JsonRpcClient, ) -> Result<()> { let mut world_reader = WorldContractReader::new(world_address, &provider); @@ -65,7 +66,7 @@ pub async fn model_layout( pub async fn model_schema( name: String, - world_address: FieldElement, + world_address: Felt, provider: JsonRpcClient, to_json: bool, ) -> Result<()> { @@ -86,8 +87,8 @@ pub async fn model_schema( pub async fn model_get( name: String, - keys: Vec, - world_address: FieldElement, + keys: Vec, + world_address: Felt, provider: JsonRpcClient, ) -> Result<()> { if keys.is_empty() { @@ -399,7 +400,7 @@ fn _start_indent(level: usize, start_indent: bool) -> String { fn format_primitive( p: &dojo_types::primitive::Primitive, - values: &mut Vec, + values: &mut Vec, level: usize, start_indent: bool, ) -> String { @@ -409,7 +410,7 @@ fn format_primitive( format!("{}{}", _start_indent(level, start_indent), _p.to_sql_value().unwrap()) } -fn format_byte_array(values: &mut Vec, level: usize, start_indent: bool) -> String { +fn format_byte_array(values: &mut Vec, level: usize, start_indent: bool) -> String { let bytearray = ByteArray::cairo_deserialize(values, 0).unwrap(); values.drain(0..ByteArray::cairo_serialized_size(&bytearray)); @@ -418,7 +419,7 @@ fn format_byte_array(values: &mut Vec, level: usize, start_indent: fn format_field_value( member: &dojo_types::schema::Member, - values: &mut Vec, + values: &mut Vec, level: usize, ) -> String { let field_repr = format_record_value(&member.ty, values, level, false); @@ -427,11 +428,11 @@ fn format_field_value( fn format_array( item: &dojo_types::schema::Ty, - values: &mut Vec, + values: &mut Vec, level: usize, start_indent: bool, ) -> String { - let length: u32 = values.remove(0).try_into().unwrap(); + let length: u32 = values.remove(0).to_u32().unwrap(); let mut items = vec![]; for _ in 0..length { @@ -448,7 +449,7 @@ fn format_array( fn format_tuple( items: &[dojo_types::schema::Ty], - values: &mut Vec, + values: &mut Vec, level: usize, start_indent: bool, ) -> String { @@ -467,7 +468,7 @@ fn format_tuple( fn format_struct( schema: &dojo_types::schema::Struct, - values: &mut Vec, + values: &mut Vec, level: usize, start_indent: bool, ) -> String { @@ -487,11 +488,11 @@ fn format_struct( fn format_enum( schema: &dojo_types::schema::Enum, - values: &mut Vec, + values: &mut Vec, level: usize, start_indent: bool, ) -> String { - let variant_index: u8 = values.remove(0).try_into().unwrap(); + let variant_index: u8 = values.remove(0).to_u8().unwrap(); let variant_index: usize = variant_index.into(); let variant_name = format!("{}::{}", schema.name, schema.options[variant_index].name); let variant_data = @@ -511,7 +512,7 @@ fn format_enum( fn format_record_value( schema: &dojo_types::schema::Ty, - values: &mut Vec, + values: &mut Vec, level: usize, start_indent: bool, ) -> String { @@ -526,11 +527,7 @@ fn format_record_value( } // print the structured record values -fn deep_print_record( - schema: &dojo_types::schema::Ty, - keys: &[FieldElement], - values: &[FieldElement], -) { +fn deep_print_record(schema: &dojo_types::schema::Ty, keys: &[Felt], values: &[Felt]) { let mut model_values = vec![]; model_values.extend(keys); model_values.extend(values); diff --git a/crates/sozo/ops/src/register.rs b/crates/sozo/ops/src/register.rs index c1edf97264..8a094d47e8 100644 --- a/crates/sozo/ops/src/register.rs +++ b/crates/sozo/ops/src/register.rs @@ -8,17 +8,17 @@ use dojo_world::migration::TxnConfig; use dojo_world::utils::TransactionExt; use scarb::core::Config; use starknet::accounts::ConnectedAccount; +use starknet::core::types::Felt; use starknet::providers::Provider; -use starknet_crypto::FieldElement; use crate::utils::handle_transaction_result; pub async fn model_register( - models: Vec, + models: Vec, world: &WorldContract, txn_config: TxnConfig, world_reader: WorldContractReader

, - world_address: FieldElement, + world_address: Felt, config: &Config, ) -> Result<()> where @@ -66,7 +66,7 @@ where let res = world .account - .execute(calls) + .execute_v1(calls) .send_with_cfg(&txn_config) .await .with_context(|| "Failed to send transaction")?; diff --git a/crates/sozo/ops/src/tests/call.rs b/crates/sozo/ops/src/tests/call.rs index 84d6c4f5bc..26c0f3802e 100644 --- a/crates/sozo/ops/src/tests/call.rs +++ b/crates/sozo/ops/src/tests/call.rs @@ -1,10 +1,10 @@ use dojo_world::contracts::WorldContractReader; use katana_runner::KatanaRunner; use starknet::accounts::SingleOwnerAccount; +use starknet::core::types::Felt; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; use starknet::signers::LocalWallet; -use starknet_crypto::FieldElement; use super::setup; use crate::{call, utils}; @@ -25,7 +25,7 @@ async fn call_with_bad_address() { world_reader, "0xBadCoffeeBadCode".to_string(), ENTRYPOINT.to_string(), - vec![FieldElement::ZERO, FieldElement::ZERO], + vec![Felt::ZERO, Felt::ZERO], None ) .await @@ -46,7 +46,7 @@ async fn call_with_bad_name() { world_reader, "BadName".to_string(), ENTRYPOINT.to_string(), - vec![FieldElement::ZERO, FieldElement::ZERO], + vec![Felt::ZERO, Felt::ZERO], None ) .await @@ -67,7 +67,7 @@ async fn call_with_bad_entrypoint() { world_reader, CONTRACT_NAME.to_string(), "BadEntryPoint".to_string(), - vec![FieldElement::ZERO, FieldElement::ZERO], + vec![Felt::ZERO, Felt::ZERO], None ) .await @@ -103,7 +103,7 @@ async fn call_with_contract_name() { world_reader, CONTRACT_NAME.to_string(), ENTRYPOINT.to_string(), - vec![FieldElement::ZERO, FieldElement::ZERO], + vec![Felt::ZERO, Felt::ZERO], None, ) .await @@ -130,7 +130,7 @@ async fn call_with_contract_address() { world_reader, format!("{:#x}", contract_address), ENTRYPOINT.to_string(), - vec![FieldElement::ZERO, FieldElement::ZERO], + vec![Felt::ZERO, Felt::ZERO], None, ) .await diff --git a/crates/sozo/ops/src/tests/migration.rs b/crates/sozo/ops/src/tests/migration.rs index 1cc6b0b3a8..16fd117229 100644 --- a/crates/sozo/ops/src/tests/migration.rs +++ b/crates/sozo/ops/src/tests/migration.rs @@ -18,12 +18,11 @@ use dojo_world::migration::TxnConfig; use futures::TryStreamExt; use ipfs_api_backend_hyper::{HyperBackend, IpfsApi, IpfsClient, TryFromUri}; use katana_runner::{KatanaRunner, KatanaRunnerConfig}; -use starknet::core::types::{BlockId, BlockTag}; +use starknet::core::types::{BlockId, BlockTag, Felt}; use starknet::core::utils::get_selector_from_name; use starknet::macros::felt; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; -use starknet_crypto::FieldElement; use super::setup; use crate::migration::{auto_authorize, execute_strategy, upload_metadata}; @@ -275,7 +274,7 @@ async fn migrate_with_metadata() { dojo_metadata_from_workspace(&ws).expect("No current package with dojo metadata found."); // check world metadata - let resource = world_reader.metadata(&FieldElement::ZERO).call().await.unwrap(); + let resource = world_reader.metadata(&Felt::ZERO).call().await.unwrap(); let element_name = WORLD_CONTRACT_NAME.to_string(); let full_uri = resource.metadata_uri.to_string().unwrap(); @@ -586,7 +585,7 @@ async fn check_ipfs_metadata( async fn check_artifact_metadata( client: &HyperBackend, world_reader: &WorldContractReader

, - resource_id: FieldElement, + resource_id: Felt, element_name: &String, dojo_metadata: &DojoMetadata, ) { diff --git a/crates/sozo/ops/src/tests/utils.rs b/crates/sozo/ops/src/tests/utils.rs index 6fe0351fd4..70cb3e03c4 100644 --- a/crates/sozo/ops/src/tests/utils.rs +++ b/crates/sozo/ops/src/tests/utils.rs @@ -2,7 +2,7 @@ use dojo_world::contracts::world::WorldContract; use dojo_world::contracts::WorldContractReader; use katana_runner::KatanaRunner; use starknet::accounts::ConnectedAccount; -use starknet::core::types::{BlockId, BlockTag, FieldElement}; +use starknet::core::types::{BlockId, BlockTag, Felt}; use super::setup; use crate::utils; @@ -18,7 +18,7 @@ async fn get_contract_address_from_world() { let contract_address = utils::get_contract_address(&world, ACTION_CONTRACT_NAME.to_string()).await.unwrap(); - assert!(contract_address != FieldElement::ZERO); + assert!(contract_address != Felt::ZERO); } #[tokio::test(flavor = "multi_thread")] @@ -26,11 +26,11 @@ async fn get_contract_address_from_string() { let sequencer = KatanaRunner::new().expect("Failed to start runner."); let account = sequencer.account(0); - let world = WorldContract::new(FieldElement::ZERO, account); + let world = WorldContract::new(Felt::ZERO, account); let contract_address = utils::get_contract_address(&world, "0x1234".to_string()).await.unwrap(); - assert_eq!(contract_address, FieldElement::from_hex_be("0x1234").unwrap()); + assert_eq!(contract_address, Felt::from_hex("0x1234").unwrap()); } #[tokio::test(flavor = "multi_thread")] @@ -47,7 +47,7 @@ async fn get_contract_address_from_world_with_world_reader() { .await .unwrap(); - assert!(contract_address != FieldElement::ZERO); + assert!(contract_address != Felt::ZERO); } #[tokio::test(flavor = "multi_thread")] @@ -56,12 +56,12 @@ async fn get_contract_address_from_string_with_world_reader() { let account = sequencer.account(0); let provider = account.provider(); - let world_reader = WorldContractReader::new(FieldElement::ZERO, provider); + let world_reader = WorldContractReader::new(Felt::ZERO, provider); let contract_address = utils::get_contract_address_from_reader(&world_reader, "0x1234".to_string()).await.unwrap(); - assert_eq!(contract_address, FieldElement::from_hex_be("0x1234").unwrap()); + assert_eq!(contract_address, Felt::from_hex("0x1234").unwrap()); } #[test] @@ -78,7 +78,7 @@ fn parse_block_id_bad_string() { fn parse_block_id_hash() { assert!( utils::parse_block_id("0x1234".to_string()).unwrap() - == BlockId::Hash(FieldElement::from_hex_be("0x1234").unwrap()) + == BlockId::Hash(Felt::from_hex("0x1234").unwrap()) ); } diff --git a/crates/sozo/ops/src/utils.rs b/crates/sozo/ops/src/utils.rs index 5fd777fc11..aeb5407959 100644 --- a/crates/sozo/ops/src/utils.rs +++ b/crates/sozo/ops/src/utils.rs @@ -1,17 +1,16 @@ use anyhow::{anyhow, Result}; -use dojo_world::contracts::world::{WorldContract, WorldContractReader}; +use bigdecimal::BigDecimal; +use dojo_world::contracts::{WorldContract, WorldContractReader}; use dojo_world::migration::strategy::generate_salt; -use dojo_world::utils::{execution_status_from_maybe_pending_receipt, TransactionWaiter}; +use dojo_world::utils::{execution_status_from_receipt, TransactionWaiter}; use scarb_ui::Ui; use starknet::accounts::ConnectedAccount; -use starknet::core::types::{ - BlockId, BlockTag, ExecutionResult, FieldElement, InvokeTransactionResult, -}; +use starknet::core::types::{BlockId, BlockTag, ExecutionResult, Felt, InvokeTransactionResult}; use starknet::providers::Provider; /// Retrieves a contract address from it's name /// using the world's data, or parses a hex string into -/// a [`FieldElement`]. +/// a [`Felt`]. /// /// # Arguments /// @@ -20,13 +19,13 @@ use starknet::providers::Provider; /// /// # Returns /// -/// A [`FieldElement`] with the address of the contract on success. +/// A [`Felt`] with the address of the contract on success. pub async fn get_contract_address( world: &WorldContract, name_or_address: String, -) -> Result { +) -> Result { if name_or_address.starts_with("0x") { - FieldElement::from_hex_be(&name_or_address).map_err(anyhow::Error::from) + Felt::from_hex(&name_or_address).map_err(anyhow::Error::from) } else { let contract_class_hash = world.base().call().await?; Ok(starknet::core::utils::get_contract_address( @@ -40,7 +39,7 @@ pub async fn get_contract_address( /// Retrieves a contract address from its name /// using a world contract reader, or parses a hex string into -/// a [`FieldElement`]. +/// a [`Felt`]. /// /// # Arguments /// @@ -49,13 +48,13 @@ pub async fn get_contract_address( /// /// # Returns /// -/// A [`FieldElement`] with the address of the contract on success. +/// A [`Felt`] with the address of the contract on success. pub async fn get_contract_address_from_reader( world_reader: &WorldContractReader

, name_or_address: String, -) -> Result { +) -> Result { if name_or_address.starts_with("0x") { - FieldElement::from_hex_be(&name_or_address).map_err(anyhow::Error::from) + Felt::from_hex(&name_or_address).map_err(anyhow::Error::from) } else { let contract_class_hash = world_reader.base().call().await?; Ok(starknet::core::utils::get_contract_address( @@ -95,7 +94,7 @@ where if show_receipt { ui.print(format!("Receipt:\n{}", serde_json::to_string_pretty(&receipt)?)); } else { - match execution_status_from_maybe_pending_receipt(&receipt) { + match execution_status_from_receipt(&receipt.receipt) { ExecutionResult::Succeeded => { ui.print("Status: OK".to_string()); } @@ -122,7 +121,7 @@ where /// The parsed [`BlockId`] on success. pub fn parse_block_id(block_str: String) -> Result { if block_str.starts_with("0x") { - let hash = FieldElement::from_hex_be(&block_str) + let hash = Felt::from_hex(&block_str) .map_err(|_| anyhow!("Unable to parse block hash: {}", block_str))?; Ok(BlockId::Hash(hash)) } else if block_str.eq("pending") { @@ -136,3 +135,12 @@ pub fn parse_block_id(block_str: String) -> Result { } } } + +/// Convert a [`Felt`] into a [`BigDecimal`] with a given number of decimals. +pub fn felt_to_bigdecimal(felt: F, decimals: D) -> BigDecimal +where + F: AsRef, + D: Into, +{ + BigDecimal::from((felt.as_ref().to_bigint(), decimals.into())) +} diff --git a/crates/sozo/signers/src/lib.rs b/crates/sozo/signers/src/lib.rs index 3c3816aed8..b833a6dc0c 100644 --- a/crates/sozo/signers/src/lib.rs +++ b/crates/sozo/signers/src/lib.rs @@ -1,6 +1,6 @@ use std::env; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::signers::{LocalWallet, SigningKey}; pub trait FromEnv { @@ -12,7 +12,7 @@ pub trait FromEnv { impl FromEnv for LocalWallet { fn from_env() -> anyhow::Result { let private_key_str = env::var("STARK_PRIVATE_KEY")?; - let private_key = FieldElement::from_hex_be(&private_key_str)?; + let private_key = Felt::from_hex(&private_key_str)?; Ok(LocalWallet::from_signing_key(SigningKey::from_secret_scalar(private_key))) } diff --git a/crates/torii/client/Cargo.toml b/crates/torii/client/Cargo.toml index ba8775d482..97023170ec 100644 --- a/crates/torii/client/Cargo.toml +++ b/crates/torii/client/Cargo.toml @@ -13,6 +13,7 @@ dojo-world = { path = "../../dojo-world", features = [ "contracts" ] } futures-util.workspace = true futures.workspace = true libp2p-gossipsub = "0.46.1" +num-traits.workspace = true parking_lot.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/torii/client/src/client/mod.rs b/crates/torii/client/src/client/mod.rs index 0f7a096317..d68b73e199 100644 --- a/crates/torii/client/src/client/mod.rs +++ b/crates/torii/client/src/client/mod.rs @@ -12,14 +12,14 @@ use dojo_types::WorldMetadata; use dojo_world::contracts::WorldContractReader; use futures::lock::Mutex; use parking_lot::{RwLock, RwLockReadGuard}; +use starknet::core::types::Felt; use starknet::core::utils::cairo_short_string_to_felt; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; -use starknet_crypto::FieldElement; use tokio::sync::RwLock as AsyncRwLock; use torii_grpc::client::{EntityUpdateStreaming, EventUpdateStreaming, ModelDiffsStreaming}; use torii_grpc::proto::world::{RetrieveEntitiesResponse, RetrieveEventsResponse}; -use torii_grpc::types::schema::{Entity, SchemaError}; +use torii_grpc::types::schema::Entity; use torii_grpc::types::{EntityKeysClause, Event, EventQuery, KeysClause, ModelKeysClause, Query}; use torii_relay::client::EventLoop; use torii_relay::types::Message; @@ -55,7 +55,7 @@ impl Client { torii_url: String, rpc_url: String, relay_url: String, - world: FieldElement, + world: Felt, ) -> Result { let mut grpc_client = torii_grpc::client::WorldClient::new(torii_url, world).await?; @@ -135,11 +135,7 @@ impl Client { pub async fn starknet_events(&self, query: EventQuery) -> Result, Error> { let mut grpc_client = self.inner.write().await; let RetrieveEventsResponse { events } = grpc_client.retrieve_events(query).await?; - Ok(events - .into_iter() - .map(TryInto::try_into) - .collect::, _>>() - .map_err(SchemaError::SliceError)?) + Ok(events.into_iter().map(Event::from).collect::>()) } /// A direct stream to grpc subscribe entities @@ -283,7 +279,7 @@ impl Client { Ok(stream) } - async fn initiate_model(&self, model: &str, keys: Vec) -> Result<(), Error> { + async fn initiate_model(&self, model: &str, keys: Vec) -> Result<(), Error> { let model_reader = self.world_reader.model_reader(model).await?; let values = model_reader.entity_storage(&keys).await?; self.storage.set_model_storage( diff --git a/crates/torii/client/src/client/storage.rs b/crates/torii/client/src/client/storage.rs index cc20ac2d92..7b13f2b180 100644 --- a/crates/torii/client/src/client/storage.rs +++ b/crates/torii/client/src/client/storage.rs @@ -4,16 +4,16 @@ use std::sync::Arc; use dojo_types::WorldMetadata; use futures::channel::mpsc::{channel, Receiver, Sender}; use parking_lot::{Mutex, RwLock}; +use starknet::core::types::Felt; use starknet::core::utils::parse_cairo_short_string; -use starknet_crypto::FieldElement; use super::error::{Error, ParseError}; use crate::utils::compute_all_storage_addresses; -pub type EntityKeys = Vec; +pub type EntityKeys = Vec; -pub type StorageKey = FieldElement; -pub type StorageValue = FieldElement; +pub type StorageKey = Felt; +pub type StorageValue = Felt; /// An in-memory storage for storing the component values of entities. // TODO: check if we can use sql db instead. @@ -21,7 +21,7 @@ pub struct ModelStorage { metadata: Arc>, storage: RwLock>, // a map of model name to a set of model keys. - model_index: RwLock>>, + model_index: RwLock>>, // listener for storage updates. senders: Mutex>>, @@ -47,11 +47,7 @@ impl ModelStorage { /// /// # Returns /// A receiver that will receive updates for the specified storage keys. - pub fn add_listener( - &self, - model: FieldElement, - keys: &[FieldElement], - ) -> Result, Error> { + pub fn add_listener(&self, model: Felt, keys: &[Felt]) -> Result, Error> { let storage_addresses = self.get_model_storage_addresses(model, keys)?; let (sender, receiver) = channel(128); @@ -68,9 +64,9 @@ impl ModelStorage { /// Retrieves the raw values of an model. pub fn get_model_storage( &self, - model: FieldElement, - raw_keys: &[FieldElement], - ) -> Result>, Error> { + model: Felt, + raw_keys: &[Felt], + ) -> Result>, Error> { let storage_addresses = self.get_model_storage_addresses(model, raw_keys)?; Ok(storage_addresses .into_iter() @@ -81,9 +77,9 @@ impl ModelStorage { /// Set the raw values of an model. pub fn set_model_storage( &self, - model: FieldElement, - raw_keys: Vec, - raw_values: Vec, + model: Felt, + raw_keys: Vec, + raw_values: Vec, ) -> Result<(), Error> { let storage_addresses = self.get_model_storage_addresses(model, &raw_keys)?; self.set_storages_at(storage_addresses.into_iter().zip(raw_values).collect()); @@ -93,7 +89,7 @@ impl ModelStorage { } /// Set the value of storage slots in bulk - pub(super) fn set_storages_at(&self, storage_models: Vec<(FieldElement, FieldElement)>) { + pub(super) fn set_storages_at(&self, storage_models: Vec<(Felt, Felt)>) { let mut senders: HashSet = Default::default(); for (key, _) in &storage_models { @@ -119,9 +115,9 @@ impl ModelStorage { fn get_model_storage_addresses( &self, - model: FieldElement, - raw_keys: &[FieldElement], - ) -> Result, Error> { + model: Felt, + raw_keys: &[Felt], + ) -> Result, Error> { let model_name = parse_cairo_short_string(&model).map_err(ParseError::ParseCairoShortString)?; @@ -135,7 +131,7 @@ impl ModelStorage { Ok(compute_all_storage_addresses(model, raw_keys, model_packed_size)) } - fn index_model(&self, model: FieldElement, raw_keys: Vec) { + fn index_model(&self, model: Felt, raw_keys: Vec) { self.model_index.write().entry(model).or_default().insert(raw_keys); } } diff --git a/crates/torii/client/src/client/subscription.rs b/crates/torii/client/src/client/subscription.rs index 73415975e3..0a02cc67c1 100644 --- a/crates/torii/client/src/client/subscription.rs +++ b/crates/torii/client/src/client/subscription.rs @@ -8,9 +8,8 @@ use dojo_types::WorldMetadata; use futures::channel::mpsc::{self, Receiver, Sender}; use futures_util::StreamExt; use parking_lot::{Mutex, RwLock}; -use starknet::core::types::{StateDiff, StateUpdate}; +use starknet::core::types::{Felt, StateDiff, StateUpdate}; use starknet::core::utils::cairo_short_string_to_felt; -use starknet_crypto::FieldElement; use torii_grpc::client::ModelDiffsStreaming; use torii_grpc::types::ModelKeysClause; @@ -26,7 +25,7 @@ pub struct SubscribedModels { metadata: Arc>, pub(crate) models_keys: RwLock>, /// All the relevant storage addresses derived from the subscribed models - pub(crate) subscribed_storage_addresses: RwLock>, + pub(crate) subscribed_storage_addresses: RwLock>, } impl SubscribedModels { @@ -199,7 +198,7 @@ impl SubscriptionService { return; }; - let entries: Vec<(FieldElement, FieldElement)> = { + let entries: Vec<(Felt, Felt)> = { let subscribed_models = self.subscribed_models.subscribed_storage_addresses.read(); entries .into_iter() diff --git a/crates/torii/client/src/utils.rs b/crates/torii/client/src/utils.rs index 77cefb837b..b476ba91c3 100644 --- a/crates/torii/client/src/utils.rs +++ b/crates/torii/client/src/utils.rs @@ -1,21 +1,22 @@ +use num_traits::FromPrimitive; +use starknet::core::types::Felt; use starknet::macros::short_string; -use starknet_crypto::{poseidon_hash_many, FieldElement}; +use starknet_crypto::poseidon_hash_many; /// Compute the base storage address for a given component of an entity. -pub fn compute_storage_base_address( - model: FieldElement, - entity_keys: &[FieldElement], -) -> FieldElement { +pub fn compute_storage_base_address(model: Felt, entity_keys: &[Felt]) -> Felt { poseidon_hash_many(&[short_string!("dojo_storage"), model, poseidon_hash_many(entity_keys)]) } /// Compute all the storage addresses that are used for a given component of an entity when it is /// stored in the World storage. pub(crate) fn compute_all_storage_addresses( - model: FieldElement, - entity_keys: &[FieldElement], + model: Felt, + entity_keys: &[Felt], packed_size: u32, -) -> Vec { +) -> Vec { let base = compute_storage_base_address(model, entity_keys); - (0..packed_size).map(|i| base + i.into()).collect::>() + (0..packed_size) + .map(|i| base + Felt::from_u32(i).expect("u32 should fit in Felt")) + .collect::>() } diff --git a/crates/torii/core/Cargo.toml b/crates/torii/core/Cargo.toml index 4f0168d20f..8ca61922eb 100644 --- a/crates/torii/core/Cargo.toml +++ b/crates/torii/core/Cargo.toml @@ -22,6 +22,7 @@ futures-util.workspace = true hex.workspace = true lazy_static.workspace = true log.workspace = true +num-traits.workspace = true once_cell.workspace = true reqwest.workspace = true scarb-ui.workspace = true diff --git a/crates/torii/core/src/engine.rs b/crates/torii/core/src/engine.rs index 409c879ef1..9e1d7906f6 100644 --- a/crates/torii/core/src/engine.rs +++ b/crates/torii/core/src/engine.rs @@ -4,12 +4,12 @@ use std::time::Duration; use anyhow::Result; use dojo_world::contracts::world::WorldContractReader; use starknet::core::types::{ - BlockId, BlockTag, Event, EventFilter, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, - MaybePendingTransactionReceipt, PendingTransactionReceipt, Transaction, TransactionReceipt, + BlockId, BlockTag, Event, EventFilter, Felt, MaybePendingBlockWithTxHashes, + MaybePendingBlockWithTxs, ReceiptBlock, Transaction, TransactionReceipt, + TransactionReceiptWithBlockInfo, }; use starknet::core::utils::get_selector_from_name; use starknet::providers::Provider; -use starknet_crypto::FieldElement; use tokio::sync::broadcast::Sender; use tokio::sync::mpsc::Sender as BoundedSender; use tokio::time::sleep; @@ -121,8 +121,8 @@ impl Engine

{ pub async fn sync_to_head( &mut self, from: u64, - mut pending_block_tx: Option, - ) -> Result<(u64, Option)> { + mut pending_block_tx: Option, + ) -> Result<(u64, Option)> { let latest_block_number = self.provider.block_hash_and_number().await?.block_number; if from < latest_block_number { @@ -139,8 +139,8 @@ impl Engine

{ pub async fn sync_pending( &mut self, block_number: u64, - mut pending_block_tx: Option, - ) -> Result> { + mut pending_block_tx: Option, + ) -> Result> { let block = if let MaybePendingBlockWithTxs::PendingBlock(pending) = self.provider.get_block_with_txs(BlockId::Tag(BlockTag::Pending)).await? { @@ -207,8 +207,8 @@ impl Engine

{ &mut self, from: u64, to: u64, - pending_block_tx: Option, - ) -> Result> { + pending_block_tx: Option, + ) -> Result> { // Process all blocks from current to latest. let get_events = |token: Option| { self.provider.get_events( @@ -246,15 +246,20 @@ impl Engine

{ // receipt Should not/rarely happen. Thus the additional // fetch is acceptable. None => { - match self.provider.get_transaction_receipt(event.transaction_hash).await? { - MaybePendingTransactionReceipt::Receipt( - TransactionReceipt::Invoke(receipt), - ) => receipt.block_number, - MaybePendingTransactionReceipt::Receipt( - TransactionReceipt::L1Handler(receipt), - ) => receipt.block_number, - // If it's a pending transaction, we assume the block number is the - // latest + 1 + let TransactionReceiptWithBlockInfo { receipt, block } = + self.provider.get_transaction_receipt(event.transaction_hash).await?; + + match receipt { + TransactionReceipt::Invoke(_) | TransactionReceipt::L1Handler(_) => { + if let ReceiptBlock::Block { block_number, .. } = block { + block_number + } else { + // If the block is pending, we assume the block number is the + // latest + 1 + to + 1 + } + } + _ => to + 1, } } @@ -343,25 +348,15 @@ impl Engine

{ async fn process_transaction_and_receipt( &mut self, - transaction_hash: FieldElement, + transaction_hash: Felt, transaction: &Transaction, block_number: u64, block_timestamp: u64, ) -> Result<()> { let receipt = self.provider.get_transaction_receipt(transaction_hash).await?; - let events = match &receipt { - MaybePendingTransactionReceipt::Receipt(TransactionReceipt::Invoke(receipt)) => { - Some(&receipt.events) - } - MaybePendingTransactionReceipt::Receipt(TransactionReceipt::L1Handler(receipt)) => { - Some(&receipt.events) - } - MaybePendingTransactionReceipt::PendingReceipt(PendingTransactionReceipt::Invoke( - receipt, - )) => Some(&receipt.events), - MaybePendingTransactionReceipt::PendingReceipt( - PendingTransactionReceipt::L1Handler(receipt), - ) => Some(&receipt.events), + let events = match &receipt.receipt { + TransactionReceipt::Invoke(receipt) => Some(&receipt.events), + TransactionReceipt::L1Handler(receipt) => Some(&receipt.events), _ => None, }; @@ -416,8 +411,8 @@ impl Engine

{ &mut self, block_number: u64, block_timestamp: u64, - transaction_receipt: &MaybePendingTransactionReceipt, - transaction_hash: FieldElement, + transaction_receipt: &TransactionReceiptWithBlockInfo, + transaction_hash: Felt, transaction: &Transaction, ) -> Result<()> { for processor in &self.processors.transaction { @@ -441,14 +436,14 @@ impl Engine

{ &mut self, block_number: u64, block_timestamp: u64, - transaction_receipt: &MaybePendingTransactionReceipt, + transaction_receipt: &TransactionReceiptWithBlockInfo, event_id: &str, event: &Event, ) -> Result<()> { self.db.store_event( event_id, event, - *transaction_receipt.transaction_hash(), + *transaction_receipt.receipt.transaction_hash(), block_timestamp, ); for processor in &self.processors.event { diff --git a/crates/torii/core/src/error.rs b/crates/torii/core/src/error.rs index 28fdc6039a..5006d83ded 100644 --- a/crates/torii/core/src/error.rs +++ b/crates/torii/core/src/error.rs @@ -2,7 +2,7 @@ use std::num::ParseIntError; use dojo_types::primitive::PrimitiveError; use dojo_types::schema::EnumError; -use starknet::core::types::{FromByteSliceError, FromStrError}; +use starknet::core::types::FromStrError; use starknet::core::utils::{CairoShortStringToFeltError, NonAsciiNameError}; #[derive(Debug, thiserror::Error)] @@ -28,8 +28,6 @@ pub enum ParseError { #[error(transparent)] CairoShortStringToFelt(#[from] CairoShortStringToFeltError), #[error(transparent)] - FromByteSliceError(#[from] FromByteSliceError), - #[error(transparent)] ParseIntError(#[from] ParseIntError), #[error(transparent)] CairoSerdeError(#[from] cainome::cairo_serde::Error), diff --git a/crates/torii/core/src/lib.rs b/crates/torii/core/src/lib.rs index abd0af414a..bf88c9fd51 100644 --- a/crates/torii/core/src/lib.rs +++ b/crates/torii/core/src/lib.rs @@ -1,7 +1,7 @@ use serde::Deserialize; use sqlx::FromRow; -use crate::types::SQLFieldElement; +use crate::types::SQLFelt; pub mod cache; pub mod engine; @@ -18,11 +18,11 @@ pub mod utils; #[derive(FromRow, Deserialize)] pub struct World { #[sqlx(try_from = "String")] - world_address: SQLFieldElement, + world_address: SQLFelt, #[sqlx(try_from = "String")] - world_class_hash: SQLFieldElement, + world_class_hash: SQLFelt, #[sqlx(try_from = "String")] - executor_address: SQLFieldElement, + executor_address: SQLFelt, #[sqlx(try_from = "String")] - executor_class_hash: SQLFieldElement, + executor_class_hash: SQLFelt, } diff --git a/crates/torii/core/src/model.rs b/crates/torii/core/src/model.rs index 39a28aad14..e9d21749fd 100644 --- a/crates/torii/core/src/model.rs +++ b/crates/torii/core/src/model.rs @@ -9,7 +9,7 @@ use dojo_world::contracts::abi::model::Layout; use dojo_world::contracts::model::ModelReader; use sqlx::sqlite::SqliteRow; use sqlx::{Pool, Row, Sqlite}; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; use starknet::core::utils::get_selector_from_name; use super::error::{self, Error}; @@ -19,9 +19,9 @@ pub struct ModelSQLReader { /// The name of the model name: String, /// The class hash of the model - class_hash: FieldElement, + class_hash: Felt, /// The contract address of the model - contract_address: FieldElement, + contract_address: Felt, pool: Pool, packed_size: u32, unpacked_size: u32, @@ -45,10 +45,9 @@ impl ModelSQLReader { .fetch_one(&pool) .await?; - let class_hash = - FieldElement::from_hex_be(&class_hash).map_err(error::ParseError::FromStr)?; + let class_hash = Felt::from_hex(&class_hash).map_err(error::ParseError::FromStr)?; let contract_address = - FieldElement::from_hex_be(&contract_address).map_err(error::ParseError::FromStr)?; + Felt::from_hex(&contract_address).map_err(error::ParseError::FromStr)?; let layout = serde_json::from_str(&layout).map_err(error::ParseError::FromJsonStr)?; @@ -63,16 +62,16 @@ impl ModelReader for ModelSQLReader { self.name.to_string() } - fn selector(&self) -> FieldElement { + fn selector(&self) -> Felt { // this should never fail get_selector_from_name(&self.name).unwrap() } - fn class_hash(&self) -> FieldElement { + fn class_hash(&self) -> Felt { self.class_hash } - fn contract_address(&self) -> FieldElement { + fn contract_address(&self) -> Felt { self.contract_address } @@ -452,20 +451,19 @@ pub fn map_row_to_ty( } Primitive::Felt252(_) => { let value = row.try_get::(&column_name)?; - primitive.set_felt252(Some( - FieldElement::from_str(&value).map_err(ParseError::FromStr)?, - ))?; + primitive + .set_felt252(Some(Felt::from_str(&value).map_err(ParseError::FromStr)?))?; } Primitive::ClassHash(_) => { let value = row.try_get::(&column_name)?; primitive.set_contract_address(Some( - FieldElement::from_str(&value).map_err(ParseError::FromStr)?, + Felt::from_str(&value).map_err(ParseError::FromStr)?, ))?; } Primitive::ContractAddress(_) => { let value = row.try_get::(&column_name)?; primitive.set_contract_address(Some( - FieldElement::from_str(&value).map_err(ParseError::FromStr)?, + Felt::from_str(&value).map_err(ParseError::FromStr)?, ))?; } }; diff --git a/crates/torii/core/src/processors/event_message.rs b/crates/torii/core/src/processors/event_message.rs index f74bc730a9..cb8e7a1971 100644 --- a/crates/torii/core/src/processors/event_message.rs +++ b/crates/torii/core/src/processors/event_message.rs @@ -2,7 +2,7 @@ use anyhow::{Error, Result}; use async_trait::async_trait; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::world::WorldContractReader; -use starknet::core::types::{Event, MaybePendingTransactionReceipt}; +use starknet::core::types::{Event, TransactionReceiptWithBlockInfo}; use starknet::providers::Provider; use tracing::info; @@ -42,7 +42,7 @@ where db: &mut Sql, _block_number: u64, block_timestamp: u64, - _transaction_receipt: &MaybePendingTransactionReceipt, + _transaction_receipt: &TransactionReceiptWithBlockInfo, event_id: &str, event: &Event, ) -> Result<(), Error> { diff --git a/crates/torii/core/src/processors/metadata_update.rs b/crates/torii/core/src/processors/metadata_update.rs index ed2432f712..12bd45e46e 100644 --- a/crates/torii/core/src/processors/metadata_update.rs +++ b/crates/torii/core/src/processors/metadata_update.rs @@ -8,9 +8,8 @@ use cainome::cairo_serde::{ByteArray, CairoSerde}; use dojo_world::contracts::world::WorldContractReader; use dojo_world::metadata::{Uri, WorldMetadata}; use reqwest::Client; -use starknet::core::types::{Event, MaybePendingTransactionReceipt}; +use starknet::core::types::{Event, Felt, TransactionReceiptWithBlockInfo}; use starknet::providers::Provider; -use starknet_crypto::FieldElement; use tokio_util::bytes::Bytes; use tracing::{error, info}; @@ -53,7 +52,7 @@ where db: &mut Sql, _block_number: u64, block_timestamp: u64, - _transaction_receipt: &MaybePendingTransactionReceipt, + _transaction_receipt: &TransactionReceiptWithBlockInfo, _event_id: &str, event: &Event, ) -> Result<(), Error> { @@ -77,7 +76,7 @@ where } } -async fn try_retrieve(mut db: Sql, resource: FieldElement, uri_str: String) { +async fn try_retrieve(mut db: Sql, resource: Felt, uri_str: String) { match metadata(uri_str.clone()).await { Ok((metadata, icon_img, cover_img)) => { db.update_metadata(&resource, &uri_str, &metadata, &icon_img, &cover_img) diff --git a/crates/torii/core/src/processors/mod.rs b/crates/torii/core/src/processors/mod.rs index 5dfd43c766..fcc30e0e1a 100644 --- a/crates/torii/core/src/processors/mod.rs +++ b/crates/torii/core/src/processors/mod.rs @@ -1,9 +1,8 @@ use anyhow::{Error, Result}; use async_trait::async_trait; use dojo_world::contracts::world::WorldContractReader; -use starknet::core::types::{Event, MaybePendingTransactionReceipt, Transaction}; +use starknet::core::types::{Event, Felt, Transaction, TransactionReceiptWithBlockInfo}; use starknet::providers::Provider; -use starknet_crypto::FieldElement; use crate::sql::Sql; @@ -37,7 +36,7 @@ where db: &mut Sql, block_number: u64, block_timestamp: u64, - transaction_receipt: &MaybePendingTransactionReceipt, + transaction_receipt: &TransactionReceiptWithBlockInfo, event_id: &str, event: &Event, ) -> Result<(), Error>; @@ -64,8 +63,8 @@ pub trait TransactionProcessor { provider: &P, block_number: u64, block_timestamp: u64, - transaction_receipt: &MaybePendingTransactionReceipt, - transaction_hash: FieldElement, + transaction_receipt: &TransactionReceiptWithBlockInfo, + transaction_hash: Felt, transaction: &Transaction, ) -> Result<(), Error>; } diff --git a/crates/torii/core/src/processors/register_model.rs b/crates/torii/core/src/processors/register_model.rs index b23afab5d3..c57896e303 100644 --- a/crates/torii/core/src/processors/register_model.rs +++ b/crates/torii/core/src/processors/register_model.rs @@ -3,7 +3,7 @@ use async_trait::async_trait; use cainome::cairo_serde::{ByteArray, CairoSerde}; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::world::WorldContractReader; -use starknet::core::types::{Event, MaybePendingTransactionReceipt}; +use starknet::core::types::{Event, TransactionReceiptWithBlockInfo}; use starknet::providers::Provider; use tracing::{debug, info}; @@ -43,7 +43,7 @@ where db: &mut Sql, _block_number: u64, block_timestamp: u64, - _transaction_receipt: &MaybePendingTransactionReceipt, + _transaction_receipt: &TransactionReceiptWithBlockInfo, _event_id: &str, event: &Event, ) -> Result<(), Error> { diff --git a/crates/torii/core/src/processors/store_del_record.rs b/crates/torii/core/src/processors/store_del_record.rs index c3dc2328d2..bc53f5d98f 100644 --- a/crates/torii/core/src/processors/store_del_record.rs +++ b/crates/torii/core/src/processors/store_del_record.rs @@ -2,7 +2,7 @@ use anyhow::{Error, Ok, Result}; use async_trait::async_trait; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::world::WorldContractReader; -use starknet::core::types::{Event, MaybePendingTransactionReceipt}; +use starknet::core::types::{Event, TransactionReceiptWithBlockInfo}; use starknet::providers::Provider; use tracing::info; @@ -43,7 +43,7 @@ where db: &mut Sql, _block_number: u64, _block_timestamp: u64, - _transaction_receipt: &MaybePendingTransactionReceipt, + _transaction_receipt: &TransactionReceiptWithBlockInfo, _event_id: &str, event: &Event, ) -> Result<(), Error> { diff --git a/crates/torii/core/src/processors/store_set_record.rs b/crates/torii/core/src/processors/store_set_record.rs index f1f6e20e96..548fe49fbe 100644 --- a/crates/torii/core/src/processors/store_set_record.rs +++ b/crates/torii/core/src/processors/store_set_record.rs @@ -1,8 +1,9 @@ -use anyhow::{Error, Ok, Result}; +use anyhow::{Context, Error, Ok, Result}; use async_trait::async_trait; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::world::WorldContractReader; -use starknet::core::types::{Event, MaybePendingTransactionReceipt}; +use num_traits::ToPrimitive; +use starknet::core::types::{Event, TransactionReceiptWithBlockInfo}; use starknet::providers::Provider; use tracing::info; @@ -43,7 +44,7 @@ where db: &mut Sql, _block_number: u64, block_timestamp: u64, - _transaction_receipt: &MaybePendingTransactionReceipt, + _transaction_receipt: &TransactionReceiptWithBlockInfo, event_id: &str, event: &Event, ) -> Result<(), Error> { @@ -58,13 +59,15 @@ where ); let keys_start = NUM_KEYS_INDEX + 1; - let keys_end: usize = keys_start + usize::from(u8::try_from(event.data[NUM_KEYS_INDEX])?); + let keys_end: usize = + keys_start + event.data[NUM_KEYS_INDEX].to_usize().context("invalid usize")?; let keys = event.data[keys_start..keys_end].to_vec(); // keys_end is already the length of the values array. let values_start = keys_end + 1; - let values_end: usize = values_start + usize::from(u8::try_from(event.data[keys_end])?); + let values_end: usize = + values_start + event.data[keys_end].to_usize().context("invalid usize")?; let values = event.data[values_start..values_end].to_vec(); let mut keys_and_unpacked = [keys, values].concat(); diff --git a/crates/torii/core/src/processors/store_transaction.rs b/crates/torii/core/src/processors/store_transaction.rs index 7ceaaf0d89..b94d5552a2 100644 --- a/crates/torii/core/src/processors/store_transaction.rs +++ b/crates/torii/core/src/processors/store_transaction.rs @@ -1,8 +1,7 @@ use anyhow::{Error, Ok, Result}; use async_trait::async_trait; -use starknet::core::types::{MaybePendingTransactionReceipt, Transaction}; +use starknet::core::types::{Felt, Transaction, TransactionReceiptWithBlockInfo}; use starknet::providers::Provider; -use starknet_crypto::FieldElement; use super::TransactionProcessor; use crate::sql::Sql; @@ -18,8 +17,8 @@ impl TransactionProcessor

for StoreTransactionProcessor { _provider: &P, block_number: u64, block_timestamp: u64, - _receipt: &MaybePendingTransactionReceipt, - transaction_hash: FieldElement, + _receipt: &TransactionReceiptWithBlockInfo, + transaction_hash: Felt, transaction: &Transaction, ) -> Result<(), Error> { let transaction_id = format!("{:#064x}:{:#x}", block_number, transaction_hash); diff --git a/crates/torii/core/src/query_queue.rs b/crates/torii/core/src/query_queue.rs index 106a57cf17..c623bb218d 100644 --- a/crates/torii/core/src/query_queue.rs +++ b/crates/torii/core/src/query_queue.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; use sqlx::{Executor, Pool, Sqlite}; -use starknet_crypto::FieldElement; +use starknet::core::types::Felt; #[derive(Debug, Clone)] pub enum Argument { @@ -9,7 +9,7 @@ pub enum Argument { Int(i64), Bool(bool), String(String), - FieldElement(FieldElement), + FieldElement(Felt), } #[derive(Debug, Clone)] diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 2f972c7c43..eaafa3a92a 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -9,7 +9,7 @@ use dojo_world::contracts::abi::model::Layout; use dojo_world::metadata::WorldMetadata; use sqlx::pool::PoolConnection; use sqlx::{Pool, Sqlite}; -use starknet::core::types::{Event, FieldElement, InvokeTransaction, Transaction}; +use starknet::core::types::{Event, Felt, InvokeTransaction, Transaction}; use starknet::core::utils::get_selector_from_name; use starknet_crypto::poseidon_hash_many; @@ -31,13 +31,13 @@ mod test; #[derive(Debug, Clone)] pub struct Sql { - world_address: FieldElement, + world_address: Felt, pub pool: Pool, query_queue: QueryQueue, } impl Sql { - pub async fn new(pool: Pool, world_address: FieldElement) -> Result { + pub async fn new(pool: Pool, world_address: Felt) -> Result { let mut query_queue = QueryQueue::new(pool.clone()); query_queue.enqueue( @@ -54,7 +54,7 @@ impl Sql { Ok(Self { pool, world_address, query_queue }) } - pub async fn head(&self) -> Result<(u64, Option)> { + pub async fn head(&self) -> Result<(u64, Option)> { let mut conn: PoolConnection = self.pool.acquire().await?; let indexer_query = sqlx::query_as::<_, (i64, Option)>( "SELECT head, pending_block_tx FROM indexers WHERE id = ?", @@ -64,11 +64,11 @@ impl Sql { let indexer: (i64, Option) = indexer_query.fetch_one(&mut *conn).await?; Ok(( indexer.0.try_into().expect("doesn't fit in u64"), - indexer.1.map(|f| FieldElement::from_str(&f)).transpose()?, + indexer.1.map(|f| Felt::from_str(&f)).transpose()?, )) } - pub fn set_head(&mut self, head: u64, pending_block_tx: Option) { + pub fn set_head(&mut self, head: u64, pending_block_tx: Option) { let head = Argument::Int(head.try_into().expect("doesn't fit in u64")); let id = Argument::FieldElement(self.world_address); let pending_block_tx = if let Some(f) = pending_block_tx { @@ -98,8 +98,8 @@ impl Sql { &mut self, model: Ty, layout: Layout, - class_hash: FieldElement, - contract_address: FieldElement, + class_hash: Felt, + contract_address: Felt, packed_size: u32, unpacked_size: u32, block_timestamp: u64, @@ -254,7 +254,7 @@ impl Sql { Ok(()) } - pub async fn delete_entity(&mut self, keys: Vec, entity: Ty) -> Result<()> { + pub async fn delete_entity(&mut self, keys: Vec, entity: Ty) -> Result<()> { let entity_id = format!("{:#x}", poseidon_hash_many(&keys)); let path = vec![entity.name()]; // delete entity models data @@ -272,7 +272,7 @@ impl Sql { Ok(()) } - pub fn set_metadata(&mut self, resource: &FieldElement, uri: &str, block_timestamp: u64) { + pub fn set_metadata(&mut self, resource: &Felt, uri: &str, block_timestamp: u64) { let resource = Argument::FieldElement(*resource); let uri = Argument::String(uri.to_string()); let executed_at = Argument::String(utc_dt_string_from_timestamp(block_timestamp)); @@ -287,7 +287,7 @@ impl Sql { pub async fn update_metadata( &mut self, - resource: &FieldElement, + resource: &Felt, uri: &str, metadata: &WorldMetadata, icon_img: &Option, @@ -324,7 +324,7 @@ impl Sql { } } - pub async fn entity(&self, model: String, key: FieldElement) -> Result> { + pub async fn entity(&self, model: String, key: Felt) -> Result> { let query = sqlx::query_as::<_, (i32, String, String)>("SELECT * FROM ? WHERE id = ?") .bind(model) .bind(format!("{:#x}", key)); @@ -334,7 +334,7 @@ impl Sql { Ok(serde_json::from_str(&row.2).unwrap()) } - pub async fn entities(&self, model: String) -> Result>> { + pub async fn entities(&self, model: String) -> Result>> { let query = sqlx::query_as::<_, (i32, String, String)>("SELECT * FROM ?").bind(model); let mut conn: PoolConnection = self.pool.acquire().await?; let mut rows = query.fetch_all(&mut *conn).await?; @@ -369,8 +369,8 @@ impl Sql { Argument::FieldElement(l1_handler_transaction.transaction_hash), Argument::FieldElement(l1_handler_transaction.contract_address), Argument::String(felts_sql_string(&l1_handler_transaction.calldata)), - Argument::FieldElement(FieldElement::ZERO), // has no max_fee - Argument::String("".to_string()), // has no signature + Argument::FieldElement(Felt::ZERO), // has no max_fee + Argument::String("".to_string()), // has no signature Argument::FieldElement((l1_handler_transaction.nonce).into()), ), _ => return, @@ -398,7 +398,7 @@ impl Sql { &mut self, event_id: &str, event: &Event, - transaction_hash: FieldElement, + transaction_hash: Felt, block_timestamp: u64, ) { let id = Argument::String(event_id.to_string()); @@ -1027,7 +1027,7 @@ impl Sql { } } -fn felts_sql_string(felts: &[FieldElement]) -> String { +fn felts_sql_string(felts: &[Felt]) -> String { felts.iter().map(|k| format!("{:#x}", k)).collect::>().join(FELT_DELIMITER) + FELT_DELIMITER } diff --git a/crates/torii/core/src/sql_test.rs b/crates/torii/core/src/sql_test.rs index baf7b65e6f..9edc00a56b 100644 --- a/crates/torii/core/src/sql_test.rs +++ b/crates/torii/core/src/sql_test.rs @@ -12,11 +12,11 @@ use scarb::ops; use sozo_ops::migration::execute_strategy; use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; use starknet::accounts::{Account, Call}; -use starknet::core::types::{BlockId, BlockTag}; +use starknet::core::types::{BlockId, BlockTag, Felt}; use starknet::core::utils::get_selector_from_name; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::{JsonRpcClient, Provider}; -use starknet_crypto::{poseidon_hash_many, FieldElement}; +use starknet_crypto::poseidon_hash_many; use tokio::sync::broadcast; use crate::engine::{Engine, EngineConfig, Processors}; @@ -101,7 +101,7 @@ async fn test_load_from_remote() { // spawn let tx = account - .execute(vec![Call { + .execute_v1(vec![Call { to: migration_output .contracts .first() @@ -225,7 +225,7 @@ async fn test_load_from_remote_del() { // spawn account - .execute(vec![Call { + .execute_v1(vec![Call { to: migration_output .contracts .first() @@ -244,7 +244,7 @@ async fn test_load_from_remote_del() { // Set player config. account - .execute(vec![Call { + .execute_v1(vec![Call { to: migration_output .contracts .first() @@ -254,7 +254,7 @@ async fn test_load_from_remote_del() { .contract_address, selector: get_selector_from_name("set_player_config").unwrap(), // Empty ByteArray. - calldata: vec![FieldElement::ZERO, FieldElement::ZERO, FieldElement::ZERO], + calldata: vec![Felt::ZERO, Felt::ZERO, Felt::ZERO], }]) .send_with_cfg(&TxnConfig::init_wait()) .await @@ -263,7 +263,7 @@ async fn test_load_from_remote_del() { tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; account - .execute(vec![Call { + .execute_v1(vec![Call { to: migration_output .contracts .first() diff --git a/crates/torii/core/src/types.rs b/crates/torii/core/src/types.rs index f410c594c4..b92f9e2364 100644 --- a/crates/torii/core/src/types.rs +++ b/crates/torii/core/src/types.rs @@ -4,26 +4,26 @@ use chrono::{DateTime, Utc}; use dojo_types::schema::Ty; use serde::{Deserialize, Serialize}; use sqlx::FromRow; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; #[derive(Serialize, Deserialize)] -pub struct SQLFieldElement(pub FieldElement); +pub struct SQLFelt(pub Felt); -impl From for FieldElement { - fn from(field_element: SQLFieldElement) -> Self { +impl From for Felt { + fn from(field_element: SQLFelt) -> Self { field_element.0 } } -impl TryFrom for SQLFieldElement { +impl TryFrom for SQLFelt { type Error = anyhow::Error; fn try_from(value: String) -> Result { - Ok(SQLFieldElement(FieldElement::from_hex_be(&value)?)) + Ok(SQLFelt(Felt::from_hex(&value)?)) } } -impl fmt::LowerHex for SQLFieldElement { +impl fmt::LowerHex for SQLFelt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } diff --git a/crates/torii/graphql/src/tests/entities_test.rs b/crates/torii/graphql/src/tests/entities_test.rs index c6efd000d9..a0e1ccf936 100644 --- a/crates/torii/graphql/src/tests/entities_test.rs +++ b/crates/torii/graphql/src/tests/entities_test.rs @@ -3,7 +3,8 @@ mod tests { use anyhow::Result; use async_graphql::dynamic::Schema; use serde_json::Value; - use starknet_crypto::{poseidon_hash_many, FieldElement}; + use starknet::core::types::Felt; + use starknet_crypto::poseidon_hash_many; use crate::schema::build_schema; use crate::tests::{ @@ -38,7 +39,7 @@ mod tests { result.get("entities").ok_or("entities not found").unwrap().clone() } - async fn entity_model_query(schema: &Schema, id: &FieldElement) -> Value { + async fn entity_model_query(schema: &Schema, id: &Felt) -> Value { let query = format!( r#" {{ @@ -226,7 +227,7 @@ mod tests { assert_eq!(connection.page_info.end_cursor, None); // entity model union - let id = poseidon_hash_many(&[FieldElement::ZERO]); + let id = poseidon_hash_many(&[Felt::ZERO]); let entity = entity_model_query(&schema, &id).await; let models = entity.get("models").ok_or("no models found").unwrap(); @@ -239,7 +240,7 @@ mod tests { assert_eq!(&record_sibling.__typename, "RecordSibling"); assert_eq!(record_sibling.record_id, 0); - let id = poseidon_hash_many(&[FieldElement::ZERO, FieldElement::ONE]); + let id = poseidon_hash_many(&[Felt::ZERO, Felt::ONE]); let entity = entity_model_query(&schema, &id).await; let models = entity.get("models").ok_or("no models found").unwrap(); let subrecord: Subrecord = serde_json::from_value(models[0].clone()).unwrap(); diff --git a/crates/torii/graphql/src/tests/metadata_test.rs b/crates/torii/graphql/src/tests/metadata_test.rs index c834ea1d3c..fd386cdf98 100644 --- a/crates/torii/graphql/src/tests/metadata_test.rs +++ b/crates/torii/graphql/src/tests/metadata_test.rs @@ -2,13 +2,13 @@ mod tests { use dojo_world::metadata::{project_to_world_metadata, ProjectMetadata}; use sqlx::SqlitePool; - use starknet_crypto::FieldElement; + use starknet::core::types::Felt; use torii_core::sql::Sql; use crate::schema::build_schema; use crate::tests::{run_graphql_query, Connection, Content, Metadata as SqlMetadata, Social}; - const RESOURCE: FieldElement = FieldElement::ZERO; + const RESOURCE: Felt = Felt::ZERO; const URI: &str = "ipfs://QmcDVFdDph5N2AoW7L2vruyhy6A3wiU8Mh5hEyfVY68ynh"; const BLOCK_TIMESTAMP: u64 = 1710754478; const QUERY: &str = r#" @@ -47,7 +47,7 @@ mod tests { #[sqlx::test(migrations = "../migrations")] async fn test_metadata(pool: SqlitePool) { - let mut db = Sql::new(pool.clone(), FieldElement::ZERO).await.unwrap(); + let mut db = Sql::new(pool.clone(), Felt::ZERO).await.unwrap(); let schema = build_schema(&pool).await.unwrap(); let cover_img = "QWxsIHlvdXIgYmFzZSBiZWxvbmcgdG8gdXM="; @@ -93,7 +93,7 @@ mod tests { #[sqlx::test(migrations = "../migrations")] async fn test_empty_content(pool: SqlitePool) { - let mut db = Sql::new(pool.clone(), FieldElement::ZERO).await.unwrap(); + let mut db = Sql::new(pool.clone(), Felt::ZERO).await.unwrap(); let schema = build_schema(&pool).await.unwrap(); db.set_metadata(&RESOURCE, URI, BLOCK_TIMESTAMP); diff --git a/crates/torii/graphql/src/tests/mod.rs b/crates/torii/graphql/src/tests/mod.rs index 4a39faae1d..40c6ca43ee 100644 --- a/crates/torii/graphql/src/tests/mod.rs +++ b/crates/torii/graphql/src/tests/mod.rs @@ -23,7 +23,7 @@ use sozo_ops::migration::execute_strategy; use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; use sqlx::SqlitePool; use starknet::accounts::{Account, Call}; -use starknet::core::types::{BlockId, BlockTag, FieldElement, InvokeTransactionResult}; +use starknet::core::types::{BlockId, BlockTag, Felt, InvokeTransactionResult}; use starknet::macros::selector; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; @@ -263,8 +263,8 @@ pub async fn model_fixtures(db: &mut Sql) { ], }), Layout::Fixed(vec![]), - FieldElement::ONE, - FieldElement::TWO, + Felt::ONE, + Felt::TWO, 0, 0, 1710754478_u64, @@ -319,8 +319,8 @@ pub async fn spinup_types_test() -> Result { manifest.contracts.iter().find(|contract| contract.name.eq("records")).unwrap(); let record_contract_address = records_contract.inner.address.unwrap(); let InvokeTransactionResult { transaction_hash } = account - .execute(vec![Call { - calldata: vec![FieldElement::from_str("0xa").unwrap()], + .execute_v1(vec![Call { + calldata: vec![Felt::from_str("0xa").unwrap()], to: record_contract_address, selector: selector!("create"), }]) @@ -332,8 +332,8 @@ pub async fn spinup_types_test() -> Result { // Execute `delete` and delete Record with id 20 let InvokeTransactionResult { transaction_hash } = account - .execute(vec![Call { - calldata: vec![FieldElement::from_str("0x14").unwrap()], + .execute_v1(vec![Call { + calldata: vec![Felt::from_str("0x14").unwrap()], to: record_contract_address, selector: selector!("delete"), }]) diff --git a/crates/torii/graphql/src/tests/models_test.rs b/crates/torii/graphql/src/tests/models_test.rs index 4787549187..99cd71ffcb 100644 --- a/crates/torii/graphql/src/tests/models_test.rs +++ b/crates/torii/graphql/src/tests/models_test.rs @@ -5,7 +5,7 @@ mod tests { use anyhow::Result; use async_graphql::dynamic::Schema; use serde_json::Value; - use starknet_crypto::FieldElement; + use starknet::core::types::Felt; use crate::schema::build_schema; use crate::tests::{ @@ -301,9 +301,9 @@ mod tests { records_model_query(&schema, "(order: { field: RANDOM_U128, direction: ASC })").await; let connection: Connection = serde_json::from_value(records).unwrap(); let first_record_felt = - FieldElement::from_str(&connection.edges.first().unwrap().node.random_u128).unwrap(); + Felt::from_str(&connection.edges.first().unwrap().node.random_u128).unwrap(); let last_record_felt = - FieldElement::from_str(&connection.edges.last().unwrap().node.random_u128).unwrap(); + Felt::from_str(&connection.edges.last().unwrap().node.random_u128).unwrap(); assert_eq!(connection.total_count, 10); assert!(first_record_felt <= last_record_felt); diff --git a/crates/torii/graphql/src/tests/subscription_test.rs b/crates/torii/graphql/src/tests/subscription_test.rs index ab971f193d..09b84c40cd 100644 --- a/crates/torii/graphql/src/tests/subscription_test.rs +++ b/crates/torii/graphql/src/tests/subscription_test.rs @@ -9,9 +9,9 @@ mod tests { use dojo_world::contracts::abi::model::Layout; use serial_test::serial; use sqlx::SqlitePool; - use starknet::core::types::Event; + use starknet::core::types::{Event, Felt}; use starknet::core::utils::get_selector_from_name; - use starknet_crypto::{poseidon_hash_many, FieldElement}; + use starknet_crypto::poseidon_hash_many; use tokio::sync::mpsc; use torii_core::sql::Sql; @@ -20,12 +20,12 @@ mod tests { #[sqlx::test(migrations = "../migrations")] #[serial] async fn test_entity_subscription(pool: SqlitePool) { - let mut db = Sql::new(pool.clone(), FieldElement::ZERO).await.unwrap(); + let mut db = Sql::new(pool.clone(), Felt::ZERO).await.unwrap(); model_fixtures(&mut db).await; // 0. Preprocess expected entity value let model_name = "Record".to_string(); - let key = vec![FieldElement::ONE]; + let key = vec![Felt::ONE]; let entity_id = format!("{:#x}", poseidon_hash_many(&key)); let keys_str = key.iter().map(|k| format!("{:#x}", k)).collect::>().join(","); let block_timestamp = 1710754478_u64; @@ -40,8 +40,8 @@ mod tests { "typeU16": 1, "type_u64": "0x1", "typeBool": true, - "type_felt": format!("{:#x}", FieldElement::from(1u128)), - "typeContractAddress": format!("{:#x}", FieldElement::ONE) + "type_felt": format!("{:#x}", Felt::from(1u128)), + "typeContractAddress": format!("{:#x}", Felt::ONE) }] } }); @@ -93,12 +93,12 @@ mod tests { Member { name: "type_felt".to_string(), key: false, - ty: Ty::Primitive(Primitive::Felt252(Some(FieldElement::from(1u128)))), + ty: Ty::Primitive(Primitive::Felt252(Some(Felt::from(1u128)))), }, Member { name: "typeContractAddress".to_string(), key: true, - ty: Ty::Primitive(Primitive::ContractAddress(Some(FieldElement::ONE))), + ty: Ty::Primitive(Primitive::ContractAddress(Some(Felt::ONE))), }, ], }), @@ -116,7 +116,7 @@ mod tests { &pool, r#"subscription { entityUpdated { - id + id keys models { __typename @@ -143,12 +143,12 @@ mod tests { #[sqlx::test(migrations = "../migrations")] #[serial] async fn test_entity_subscription_with_id(pool: SqlitePool) { - let mut db = Sql::new(pool.clone(), FieldElement::ZERO).await.unwrap(); + let mut db = Sql::new(pool.clone(), Felt::ZERO).await.unwrap(); model_fixtures(&mut db).await; // 0. Preprocess expected entity value let model_name = "Record".to_string(); - let key = vec![FieldElement::ONE]; + let key = vec![Felt::ONE]; let entity_id = format!("{:#x}", poseidon_hash_many(&key)); let block_timestamp = 1710754478_u64; let keys_str = key.iter().map(|k| format!("{:#x}", k)).collect::>().join(","); @@ -160,8 +160,8 @@ mod tests { "__typename": model_name, "depth": "Zero", "record_id": 0, - "type_felt": format!("{:#x}", FieldElement::from(1u128)), - "typeContractAddress": format!("{:#x}", FieldElement::ONE) + "type_felt": format!("{:#x}", Felt::from(1u128)), + "typeContractAddress": format!("{:#x}", Felt::ONE) }] } }); @@ -198,12 +198,12 @@ mod tests { Member { name: "type_felt".to_string(), key: false, - ty: Ty::Primitive(Primitive::Felt252(Some(FieldElement::from(1u128)))), + ty: Ty::Primitive(Primitive::Felt252(Some(Felt::from(1u128)))), }, Member { name: "typeContractAddress".to_string(), key: true, - ty: Ty::Primitive(Primitive::ContractAddress(Some(FieldElement::ONE))), + ty: Ty::Primitive(Primitive::ContractAddress(Some(Felt::ONE))), }, ], }), @@ -221,7 +221,7 @@ mod tests { &pool, r#"subscription { entityUpdated(id: "0x579e8877c7755365d5ec1ec7d3a94a457eff5d1f40482bbe9729c064cdead2") { - id + id keys models { __typename @@ -245,12 +245,12 @@ mod tests { #[sqlx::test(migrations = "../migrations")] #[serial] async fn test_model_subscription(pool: SqlitePool) { - let mut db = Sql::new(pool.clone(), FieldElement::ZERO).await.unwrap(); + let mut db = Sql::new(pool.clone(), Felt::ZERO).await.unwrap(); // 0. Preprocess model value let model_name = "Subrecord".to_string(); let model_id = format!("{:#x}", get_selector_from_name(&model_name).unwrap()); - let class_hash = FieldElement::TWO; - let contract_address = FieldElement::THREE; + let class_hash = Felt::TWO; + let contract_address = Felt::THREE; let block_timestamp: u64 = 1710754478_u64; let expected_value: async_graphql::Value = value!({ "modelRegistered": { "id": model_id, "name":model_name } @@ -306,12 +306,12 @@ mod tests { #[sqlx::test(migrations = "../migrations")] #[serial] async fn test_model_subscription_with_id(pool: SqlitePool) { - let mut db = Sql::new(pool.clone(), FieldElement::ZERO).await.unwrap(); + let mut db = Sql::new(pool.clone(), Felt::ZERO).await.unwrap(); // 0. Preprocess model value let model_name = "Subrecord".to_string(); let model_id = format!("{:#x}", get_selector_from_name(&model_name).unwrap()); - let class_hash = FieldElement::TWO; - let contract_address = FieldElement::THREE; + let class_hash = Felt::TWO; + let contract_address = Felt::THREE; let block_timestamp: u64 = 1710754478_u64; let expected_value: async_graphql::Value = value!({ "modelRegistered": { "id": model_id, "name":model_name } @@ -369,7 +369,7 @@ mod tests { #[sqlx::test(migrations = "../migrations")] #[serial] async fn test_event_emitted(pool: SqlitePool) { - let mut db = Sql::new(pool.clone(), FieldElement::ZERO).await.unwrap(); + let mut db = Sql::new(pool.clone(), Felt::ZERO).await.unwrap(); let block_timestamp: u64 = 1710754478_u64; let (tx, mut rx) = mpsc::channel(7); tokio::spawn(async move { @@ -378,17 +378,17 @@ mod tests { db.store_event( "0x0", &Event { - from_address: FieldElement::ZERO, + from_address: Felt::ZERO, keys: vec![ - FieldElement::from_str("0xdead").unwrap(), - FieldElement::from_str("0xbeef").unwrap(), + Felt::from_str("0xdead").unwrap(), + Felt::from_str("0xbeef").unwrap(), ], data: vec![ - FieldElement::from_str("0xc0de").unwrap(), - FieldElement::from_str("0xface").unwrap(), + Felt::from_str("0xc0de").unwrap(), + Felt::from_str("0xface").unwrap(), ], }, - FieldElement::ZERO, + Felt::ZERO, block_timestamp, ); @@ -407,19 +407,19 @@ mod tests { }} }} "#, - FieldElement::from_str("0xbeef").unwrap() + Felt::from_str("0xbeef").unwrap() ), ) .await; let expected_value: async_graphql::Value = value!({ "eventEmitted": { "keys": vec![ - format!("{:#x}", FieldElement::from_str("0xdead").unwrap()), - format!("{:#x}", FieldElement::from_str("0xbeef").unwrap()) + format!("{:#x}", Felt::from_str("0xdead").unwrap()), + format!("{:#x}", Felt::from_str("0xbeef").unwrap()) ], "data": vec![ - format!("{:#x}", FieldElement::from_str("0xc0de").unwrap()), - format!("{:#x}", FieldElement::from_str("0xface").unwrap()) - ], "transactionHash": format!("{:#x}", FieldElement::ZERO)} + format!("{:#x}", Felt::from_str("0xc0de").unwrap()), + format!("{:#x}", Felt::from_str("0xface").unwrap()) + ], "transactionHash": format!("{:#x}", Felt::ZERO)} }); assert_eq!(response_value, expected_value); diff --git a/crates/torii/grpc/Cargo.toml b/crates/torii/grpc/Cargo.toml index 3673a790a2..73ade208de 100644 --- a/crates/torii/grpc/Cargo.toml +++ b/crates/torii/grpc/Cargo.toml @@ -10,6 +10,7 @@ bytes.workspace = true dojo-types = { path = "../../dojo-types" } futures-util.workspace = true futures.workspace = true +num-traits.workspace = true parking_lot.workspace = true rayon.workspace = true starknet-crypto.workspace = true diff --git a/crates/torii/grpc/src/client.rs b/crates/torii/grpc/src/client.rs index e0c994283d..7a0fd4a9b8 100644 --- a/crates/torii/grpc/src/client.rs +++ b/crates/torii/grpc/src/client.rs @@ -3,8 +3,7 @@ use std::num::ParseIntError; use futures_util::stream::MapOk; use futures_util::{Stream, StreamExt, TryStreamExt}; -use starknet::core::types::{FromStrError, StateDiff, StateUpdate}; -use starknet_crypto::FieldElement; +use starknet::core::types::{Felt, FromStrError, StateDiff, StateUpdate}; use crate::proto::world::{ world_client, MetadataRequest, RetrieveEntitiesRequest, RetrieveEntitiesResponse, @@ -32,7 +31,7 @@ pub enum Error { /// A lightweight wrapper around the grpc client. pub struct WorldClient { - _world_address: FieldElement, + _world_address: Felt, #[cfg(not(target_arch = "wasm32"))] inner: world_client::WorldClient, #[cfg(target_arch = "wasm32")] @@ -41,7 +40,7 @@ pub struct WorldClient { impl WorldClient { #[cfg(not(target_arch = "wasm32"))] - pub async fn new(dst: D, _world_address: FieldElement) -> Result + pub async fn new(dst: D, _world_address: Felt) -> Result where D: TryInto, D::Error: Into>, @@ -54,7 +53,7 @@ impl WorldClient { // we make this function async so that we can keep the function signature similar #[cfg(target_arch = "wasm32")] - pub async fn new(endpoint: String, _world_address: FieldElement) -> Result { + pub async fn new(endpoint: String, _world_address: Felt) -> Result { Ok(Self { _world_address, inner: world_client::WorldClient::new(tonic_web_wasm_client::Client::new(endpoint)), @@ -116,7 +115,7 @@ impl WorldClient { Ok(EntityUpdateStreaming(stream.map_ok(Box::new(|res| match res.entity { Some(entity) => entity.try_into().expect("must able to serialize"), - None => Entity { hashed_keys: FieldElement::ZERO, models: vec![] }, + None => Entity { hashed_keys: Felt::ZERO, models: vec![] }, })))) } @@ -135,7 +134,7 @@ impl WorldClient { Ok(EntityUpdateStreaming(stream.map_ok(Box::new(|res| match res.entity { Some(entity) => entity.try_into().expect("must able to serialize"), - None => Entity { hashed_keys: FieldElement::ZERO, models: vec![] }, + None => Entity { hashed_keys: Felt::ZERO, models: vec![] }, })))) } @@ -154,8 +153,8 @@ impl WorldClient { .map(|res| res.into_inner())?; Ok(EventUpdateStreaming(stream.map_ok(Box::new(|res| match res.event { - Some(event) => event.try_into().expect("must able to serialize"), - None => Event { keys: vec![], data: vec![], transaction_hash: FieldElement::ZERO }, + Some(event) => event.into(), + None => Event { keys: vec![], data: vec![], transaction_hash: Felt::ZERO }, })))) } @@ -235,9 +234,9 @@ impl Stream for EventUpdateStreaming { fn empty_state_update() -> StateUpdate { StateUpdate { - block_hash: FieldElement::ZERO, - new_root: FieldElement::ZERO, - old_root: FieldElement::ZERO, + block_hash: Felt::ZERO, + new_root: Felt::ZERO, + old_root: Felt::ZERO, state_diff: StateDiff { declared_classes: vec![], deployed_contracts: vec![], diff --git a/crates/torii/grpc/src/server/mod.rs b/crates/torii/grpc/src/server/mod.rs index f0394fb30b..9cd741ec89 100644 --- a/crates/torii/grpc/src/server/mod.rs +++ b/crates/torii/grpc/src/server/mod.rs @@ -20,10 +20,10 @@ use proto::world::{ }; use sqlx::sqlite::SqliteRow; use sqlx::{Pool, Row, Sqlite}; +use starknet::core::types::Felt; use starknet::core::utils::{cairo_short_string_to_felt, get_selector_from_name}; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; -use starknet_crypto::FieldElement; use subscriptions::event::EventManager; use tokio::net::TcpListener; use tokio::sync::mpsc::Receiver; @@ -56,7 +56,7 @@ pub(crate) static EVENT_MESSAGES_ENTITY_RELATION_COLUMN: &str = "event_message_i #[derive(Clone)] pub struct DojoWorld { pool: Pool, - world_address: FieldElement, + world_address: Felt, model_cache: Arc, entity_manager: Arc, event_message_manager: Arc, @@ -68,7 +68,7 @@ impl DojoWorld { pub fn new( pool: Pool, block_rx: Receiver, - world_address: FieldElement, + world_address: Felt, provider: Arc>, ) -> Self { let model_cache = Arc::new(ModelCache::new(pool.clone())); @@ -216,11 +216,7 @@ impl DojoWorld { let ids = hashed_keys .hashed_keys .iter() - .map(|id| { - Ok(FieldElement::from_byte_slice_be(id) - .map(|id| format!("{table}.id = '{id:#x}'")) - .map_err(ParseError::FromByteSliceError)?) - }) + .map(|id| Ok(format!("{table}.id = '{:#x}'", Felt::from_bytes_be_slice(id)))) .collect::, Error>>()?; format!("WHERE {}", ids.join(" OR ")) @@ -535,9 +531,7 @@ impl DojoWorld { .hashed_keys .iter() .map(|id| { - Ok(FieldElement::from_byte_slice_be(id) - .map(|id| format!("{table}.id = '{id:#x}'")) - .map_err(ParseError::FromByteSliceError)?) + Ok(format!("{table}.id = '{:#x}'", Felt::from_bytes_be_slice(id))) }) .collect::, Error>>()?; where_clauses.push(format!("({})", ids.join(" OR "))); @@ -728,7 +722,7 @@ impl DojoWorld { &self, keys: Option, ) -> Result>, Error> { - self.entity_manager.add_subscriber(keys.map(|keys| keys.try_into().unwrap())).await + self.entity_manager.add_subscriber(keys.map(|keys| keys.into())).await } async fn retrieve_entities( @@ -805,7 +799,7 @@ impl DojoWorld { &self, keys: Option, ) -> Result>, Error> { - self.event_message_manager.add_subscriber(keys.map(|keys| keys.try_into().unwrap())).await + self.event_message_manager.add_subscriber(keys.map(|keys| keys.into())).await } async fn retrieve_event_messages( @@ -893,7 +887,7 @@ impl DojoWorld { &self, clause: proto::types::KeysClause, ) -> Result>, Error> { - self.event_manager.add_subscriber(clause.try_into().unwrap()).await + self.event_manager.add_subscriber(clause.into()).await } } @@ -901,9 +895,7 @@ fn process_event_field(data: &str) -> Result>, Error> { Ok(data .trim_end_matches('/') .split('/') - .map(|d| { - FieldElement::from_str(d).map_err(ParseError::FromStr).map(|f| f.to_bytes_be().to_vec()) - }) + .map(|d| Felt::from_str(d).map_err(ParseError::FromStr).map(|f| f.to_bytes_be().to_vec())) .collect::, _>>()?) } @@ -911,7 +903,7 @@ fn map_row_to_event(row: &(String, String, String)) -> Result>, schemas: &[Ty], ) -> Result { - let hashed_keys = - FieldElement::from_str(&row.get::("id")).map_err(ParseError::FromStr)?; + let hashed_keys = Felt::from_str(&row.get::("id")).map_err(ParseError::FromStr)?; let models = schemas .iter() .map(|schema| { @@ -944,9 +935,7 @@ fn build_keys_pattern(clause: &proto::types::KeysClause) -> Result, Error>>()?; let mut keys_pattern = format!("^{}", keys.join("/")); @@ -1097,7 +1086,7 @@ pub async fn new( mut shutdown_rx: tokio::sync::broadcast::Receiver<()>, pool: &Pool, block_rx: Receiver, - world_address: FieldElement, + world_address: Felt, provider: Arc>, ) -> Result< (SocketAddr, impl Future> + 'static), diff --git a/crates/torii/grpc/src/server/subscriptions/entity.rs b/crates/torii/grpc/src/server/subscriptions/entity.rs index b93385ad07..8f00cbdd5d 100644 --- a/crates/torii/grpc/src/server/subscriptions/entity.rs +++ b/crates/torii/grpc/src/server/subscriptions/entity.rs @@ -9,7 +9,7 @@ use futures::Stream; use futures_util::StreamExt; use rand::Rng; use sqlx::{Pool, Sqlite}; -use starknet_crypto::FieldElement; +use starknet::core::types::Felt; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::RwLock; use torii_core::cache::ModelCache; @@ -91,12 +91,12 @@ impl Service { entity: &Entity, ) -> Result<(), Error> { let mut closed_stream = Vec::new(); - let hashed = FieldElement::from_str(&entity.id).map_err(ParseError::FromStr)?; + let hashed = Felt::from_str(&entity.id).map_err(ParseError::FromStr)?; let keys = entity .keys .trim_end_matches(FELT_DELIMITER) .split(FELT_DELIMITER) - .map(FieldElement::from_str) + .map(Felt::from_str) .collect::, _>>() .map_err(ParseError::FromStr)?; diff --git a/crates/torii/grpc/src/server/subscriptions/event.rs b/crates/torii/grpc/src/server/subscriptions/event.rs index 856f2211e6..59cba5fedf 100644 --- a/crates/torii/grpc/src/server/subscriptions/event.rs +++ b/crates/torii/grpc/src/server/subscriptions/event.rs @@ -8,7 +8,7 @@ use std::task::{Context, Poll}; use futures::Stream; use futures_util::StreamExt; use rand::Rng; -use starknet_crypto::FieldElement; +use starknet::core::types::Felt; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::RwLock; use torii_core::error::{Error, ParseError}; @@ -75,14 +75,14 @@ impl Service { .keys .trim_end_matches(FELT_DELIMITER) .split(FELT_DELIMITER) - .map(FieldElement::from_str) + .map(Felt::from_str) .collect::, _>>() .map_err(ParseError::from)?; let data = event .data .trim_end_matches(FELT_DELIMITER) .split(FELT_DELIMITER) - .map(FieldElement::from_str) + .map(Felt::from_str) .collect::, _>>() .map_err(ParseError::from)?; @@ -121,7 +121,7 @@ impl Service { event: Some(proto::types::Event { keys: keys.iter().map(|k| k.to_bytes_be().to_vec()).collect(), data: data.iter().map(|d| d.to_bytes_be().to_vec()).collect(), - transaction_hash: FieldElement::from_str(&event.transaction_hash) + transaction_hash: Felt::from_str(&event.transaction_hash) .map_err(ParseError::from)? .to_bytes_be() .to_vec(), diff --git a/crates/torii/grpc/src/server/subscriptions/event_message.rs b/crates/torii/grpc/src/server/subscriptions/event_message.rs index b345710bf0..568ea85e6e 100644 --- a/crates/torii/grpc/src/server/subscriptions/event_message.rs +++ b/crates/torii/grpc/src/server/subscriptions/event_message.rs @@ -9,7 +9,7 @@ use futures::Stream; use futures_util::StreamExt; use rand::Rng; use sqlx::{Pool, Sqlite}; -use starknet_crypto::FieldElement; +use starknet::core::types::Felt; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::RwLock; use torii_core::cache::ModelCache; @@ -90,12 +90,12 @@ impl Service { entity: &EventMessage, ) -> Result<(), Error> { let mut closed_stream = Vec::new(); - let hashed = FieldElement::from_str(&entity.id).map_err(ParseError::FromStr)?; + let hashed = Felt::from_str(&entity.id).map_err(ParseError::FromStr)?; let keys = entity .keys .trim_end_matches(FELT_DELIMITER) .split(FELT_DELIMITER) - .map(FieldElement::from_str) + .map(Felt::from_str) .collect::, _>>() .map_err(ParseError::FromStr)?; diff --git a/crates/torii/grpc/src/server/subscriptions/model_diff.rs b/crates/torii/grpc/src/server/subscriptions/model_diff.rs index fbd90d01b8..f5088f072d 100644 --- a/crates/torii/grpc/src/server/subscriptions/model_diff.rs +++ b/crates/torii/grpc/src/server/subscriptions/model_diff.rs @@ -5,17 +5,18 @@ use std::task::Poll; use futures_util::future::BoxFuture; use futures_util::FutureExt; +use num_traits::FromPrimitive; use rand::Rng; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use starknet::core::types::{ - BlockId, ContractStorageDiffItem, MaybePendingStateUpdate, StateUpdate, StorageEntry, + BlockId, ContractStorageDiffItem, Felt, MaybePendingStateUpdate, StateUpdate, StorageEntry, }; use starknet::macros::short_string; use starknet::providers::Provider; -use starknet_crypto::{poseidon_hash_many, FieldElement}; +use starknet_crypto::poseidon_hash_many; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::RwLock; -use torii_core::error::{Error, ParseError}; +use torii_core::error::Error; use tracing::{debug, error, trace}; use super::error::SubscriptionError; @@ -26,7 +27,7 @@ use crate::types::ModelKeysClause; pub(crate) const LOG_TARGET: &str = "torii::grpc::server::subscriptions::model_diff"; pub struct ModelMetadata { - pub name: FieldElement, + pub name: Felt, pub packed_size: usize, } @@ -39,7 +40,7 @@ impl ModelDiffRequest {} pub struct ModelDiffSubscriber { /// The storage addresses that the subscriber is interested in. - storage_addresses: HashSet, + storage_addresses: HashSet, /// The channel to send the response back to the subscriber. sender: Sender>, } @@ -62,8 +63,7 @@ impl StateDiffManager { let storage_addresses = reqs .into_iter() .map(|req| { - let keys: ModelKeysClause = - req.keys.try_into().map_err(ParseError::FromByteSliceError)?; + let keys: ModelKeysClause = req.keys.into(); let base = poseidon_hash_many(&[ short_string!("dojo_storage"), @@ -73,15 +73,15 @@ impl StateDiffManager { let res = (0..req.model.packed_size) .into_par_iter() - .map(|i| base + i.into()) - .collect::>(); + .map(|i| base + Felt::from_usize(i).expect("failed to convert usize to Felt")) + .collect::>(); Ok(res) }) .collect::, Error>>()? .into_iter() .flatten() - .collect::>(); + .collect::>(); // NOTE: unlock issue with firefox/safari // initially send empty stream message to return from @@ -106,7 +106,7 @@ type RequestStateUpdateResult = Result { - world_address: FieldElement, + world_address: Felt, idle_provider: Option

, block_num_rcv: Receiver, state_update_queue: VecDeque, @@ -121,7 +121,7 @@ where { pub fn new_with_block_rcv( block_num_rcv: Receiver, - world_address: FieldElement, + world_address: Felt, provider: P, subs_manager: Arc, ) -> Self { @@ -146,7 +146,7 @@ where async fn publish_updates( subs: Arc, - contract_address: FieldElement, + contract_address: Felt, state_update: StateUpdate, ) -> PublishStateUpdateResult { let mut closed_stream = Vec::new(); diff --git a/crates/torii/grpc/src/server/tests/entities_test.rs b/crates/torii/grpc/src/server/tests/entities_test.rs index 9c3d2a710d..c32076e496 100644 --- a/crates/torii/grpc/src/server/tests/entities_test.rs +++ b/crates/torii/grpc/src/server/tests/entities_test.rs @@ -73,7 +73,7 @@ async fn test_entities_queries() { // spawn let tx = account - .execute(vec![Call { + .execute_v1(vec![Call { to: migration_output .contracts .first() diff --git a/crates/torii/grpc/src/types/mod.rs b/crates/torii/grpc/src/types/mod.rs index 3840daa1f0..0666e382f9 100644 --- a/crates/torii/grpc/src/types/mod.rs +++ b/crates/torii/grpc/src/types/mod.rs @@ -6,9 +6,8 @@ use dojo_types::primitive::Primitive; use dojo_types::schema::Ty; use serde::{Deserialize, Serialize}; use starknet::core::types::{ - ContractStorageDiffItem, FromByteSliceError, FromStrError, StateDiff, StateUpdate, StorageEntry, + ContractStorageDiffItem, Felt, FromStrError, StateDiff, StateUpdate, StorageEntry, }; -use starknet_crypto::FieldElement; use strum_macros::{AsRefStr, EnumIter, FromRepr}; use crate::proto::{self}; @@ -31,19 +30,19 @@ pub enum Clause { #[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] pub enum EntityKeysClause { - HashedKeys(Vec), + HashedKeys(Vec), Keys(KeysClause), } #[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] pub struct ModelKeysClause { pub model: String, - pub keys: Vec, + pub keys: Vec, } #[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] pub struct KeysClause { - pub keys: Vec>, + pub keys: Vec>, pub pattern_matching: PatternMatching, pub models: Vec, } @@ -136,15 +135,15 @@ impl TryFrom for dojo_types::schema::ModelMetadata type Error = FromStrError; fn try_from(value: proto::types::ModelMetadata) -> Result { let schema: Ty = serde_json::from_slice(&value.schema).unwrap(); - let layout: Vec = value.layout.into_iter().map(FieldElement::from).collect(); + let layout: Vec = value.layout.into_iter().map(Felt::from).collect(); Ok(Self { schema, layout, name: value.name, packed_size: value.packed_size, unpacked_size: value.unpacked_size, - class_hash: FieldElement::from_str(&value.class_hash)?, - contract_address: FieldElement::from_str(&value.contract_address)?, + class_hash: Felt::from_str(&value.class_hash)?, + contract_address: Felt::from_str(&value.contract_address)?, }) } } @@ -160,8 +159,8 @@ impl TryFrom for dojo_types::WorldMetadata { Ok(dojo_types::WorldMetadata { models, - world_address: FieldElement::from_str(&value.world_address)?, - world_class_hash: FieldElement::from_str(&value.world_class_hash)?, + world_address: Felt::from_str(&value.world_address)?, + world_class_hash: Felt::from_str(&value.world_class_hash)?, }) } } @@ -195,19 +194,15 @@ impl From for proto::types::KeysClause { } } -impl TryFrom for KeysClause { - type Error = FromByteSliceError; - - fn try_from(value: proto::types::KeysClause) -> Result { +impl From for KeysClause { + fn from(value: proto::types::KeysClause) -> Self { let keys = value .keys .iter() - .map(|k| { - if k.is_empty() { Ok(None) } else { Ok(Some(FieldElement::from_byte_slice_be(k)?)) } - }) - .collect::>, _>>()?; + .map(|k| if k.is_empty() { None } else { Some(Felt::from_bytes_be_slice(k)) }) + .collect::>>(); - Ok(Self { keys, pattern_matching: value.pattern_matching().into(), models: value.models }) + Self { keys, pattern_matching: value.pattern_matching().into(), models: value.models } } } @@ -244,23 +239,20 @@ impl From for proto::types::EntityKeysClause { } } -impl TryFrom for EntityKeysClause { - type Error = FromByteSliceError; - - fn try_from(value: proto::types::EntityKeysClause) -> Result { +impl From for EntityKeysClause { + fn from(value: proto::types::EntityKeysClause) -> Self { match value.clause_type.expect("must have") { proto::types::entity_keys_clause::ClauseType::HashedKeys(clause) => { let keys = clause .hashed_keys .into_iter() - .map(|k| FieldElement::from_byte_slice_be(&k)) - .collect::, _>>()?; + .map(|k| Felt::from_bytes_be_slice(&k)) + .collect::>(); - Ok(Self::HashedKeys(keys)) - } - proto::types::entity_keys_clause::ClauseType::Keys(clause) => { - Ok(Self::Keys(clause.try_into()?)) + Self::HashedKeys(keys) } + + proto::types::entity_keys_clause::ClauseType::Keys(clause) => Self::Keys(clause.into()), } } } @@ -274,17 +266,10 @@ impl From for proto::types::ModelKeysClause { } } -impl TryFrom for ModelKeysClause { - type Error = FromByteSliceError; - - fn try_from(value: proto::types::ModelKeysClause) -> Result { - let keys = value - .keys - .into_iter() - .map(|k| FieldElement::from_byte_slice_be(&k)) - .collect::, _>>()?; - - Ok(Self { model: value.model, keys }) +impl From for ModelKeysClause { + fn from(value: proto::types::ModelKeysClause) -> Self { + let keys = value.keys.into_iter().map(|v| Felt::from_bytes_be_slice(&v)).collect(); + Self { model: value.model, keys } } } @@ -326,10 +311,7 @@ impl From for proto::types::Value { impl TryFrom for StorageEntry { type Error = FromStrError; fn try_from(value: proto::types::StorageEntry) -> Result { - Ok(Self { - key: FieldElement::from_str(&value.key)?, - value: FieldElement::from_str(&value.value)?, - }) + Ok(Self { key: Felt::from_str(&value.key)?, value: Felt::from_str(&value.value)? }) } } @@ -337,7 +319,7 @@ impl TryFrom for ContractStorageDiffItem { type Error = FromStrError; fn try_from(value: proto::types::StorageDiff) -> Result { Ok(Self { - address: FieldElement::from_str(&value.address)?, + address: Felt::from_str(&value.address)?, storage_entries: value .storage_entries .into_iter() @@ -369,9 +351,9 @@ impl TryFrom for StateUpdate { type Error = FromStrError; fn try_from(value: proto::types::ModelUpdate) -> Result { Ok(Self { - new_root: FieldElement::ZERO, - old_root: FieldElement::ZERO, - block_hash: FieldElement::from_str(&value.block_hash)?, + new_root: Felt::ZERO, + old_root: Felt::ZERO, + block_hash: Felt::from_str(&value.block_hash)?, state_diff: value.model_diff.expect("must have").try_into()?, }) } @@ -379,32 +361,17 @@ impl TryFrom for StateUpdate { #[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] pub struct Event { - pub keys: Vec, - pub data: Vec, - pub transaction_hash: FieldElement, + pub keys: Vec, + pub data: Vec, + pub transaction_hash: Felt, } -impl TryFrom for Event { - type Error = FromByteSliceError; - - fn try_from(value: proto::types::Event) -> Result { - let keys = value - .keys - .into_iter() - .map(|k| FieldElement::from_byte_slice_be(&k)) - .collect::, _>>()?; - - let data = value - .data - .into_iter() - .map(|d| FieldElement::from_byte_slice_be(&d)) - .collect::, _>>()?; - - Ok(Self { - keys, - data, - transaction_hash: FieldElement::from_byte_slice_be(&value.transaction_hash)?, - }) +impl From for Event { + fn from(value: proto::types::Event) -> Self { + let keys = value.keys.into_iter().map(|k| Felt::from_bytes_be_slice(&k)).collect(); + let data = value.data.into_iter().map(|d| Felt::from_bytes_be_slice(&d)).collect(); + let transaction_hash = Felt::from_bytes_be_slice(&value.transaction_hash); + Self { keys, data, transaction_hash } } } diff --git a/crates/torii/grpc/src/types/schema.rs b/crates/torii/grpc/src/types/schema.rs index 36c0e926b3..728a5da5f6 100644 --- a/crates/torii/grpc/src/types/schema.rs +++ b/crates/torii/grpc/src/types/schema.rs @@ -2,8 +2,7 @@ use crypto_bigint::{Encoding, U256}; use dojo_types::primitive::Primitive; use dojo_types::schema::{Enum, EnumOption, Member, Struct, Ty}; use serde::{Deserialize, Serialize}; -use starknet::core::types::FromByteSliceError; -use starknet_crypto::FieldElement; +use starknet::core::types::Felt; use crate::proto::{self}; @@ -13,13 +12,11 @@ pub enum SchemaError { MissingExpectedData, #[error("Unsupported type")] UnsupportedType, - #[error(transparent)] - SliceError(#[from] FromByteSliceError), } #[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] pub struct Entity { - pub hashed_keys: FieldElement, + pub hashed_keys: Felt, pub models: Vec, } @@ -33,7 +30,7 @@ impl TryFrom for Entity { type Error = SchemaError; fn try_from(entity: proto::types::Entity) -> Result { Ok(Self { - hashed_keys: FieldElement::from_byte_slice_be(&entity.hashed_keys)?, + hashed_keys: Felt::from_bytes_be_slice(&entity.hashed_keys), models: entity .models .into_iter() @@ -230,10 +227,7 @@ impl TryFrom for Primitive { | Some(proto::types::PrimitiveType::Felt252) | Some(proto::types::PrimitiveType::ClassHash) | Some(proto::types::PrimitiveType::ContractAddress) => { - Primitive::Felt252(Some( - FieldElement::from_byte_slice_be(bytes) - .map_err(SchemaError::SliceError)?, - )) + Primitive::Felt252(Some(Felt::from_bytes_be_slice(bytes))) } Some(proto::types::PrimitiveType::U256) => { Primitive::U256(Some(U256::from_be_slice(bytes))) diff --git a/crates/torii/libp2p/src/server/mod.rs b/crates/torii/libp2p/src/server/mod.rs index 83803a55ab..2e4bec0c91 100644 --- a/crates/torii/libp2p/src/server/mod.rs +++ b/crates/torii/libp2p/src/server/mod.rs @@ -20,10 +20,10 @@ use libp2p::swarm::{NetworkBehaviour, SwarmEvent}; use libp2p::{identify, identity, noise, ping, relay, tcp, yamux, PeerId, Swarm, Transport}; use libp2p_webrtc as webrtc; use rand::thread_rng; -use starknet::core::types::{BlockId, BlockTag, FunctionCall}; +use starknet::core::types::{BlockId, BlockTag, Felt, FunctionCall}; use starknet::core::utils::get_selector_from_name; use starknet::providers::Provider; -use starknet_crypto::{poseidon_hash_many, verify, FieldElement}; +use starknet_crypto::{poseidon_hash_many, verify}; use torii_core::sql::Sql; use tracing::{info, warn}; use webrtc::tokio::Certificate; @@ -271,18 +271,17 @@ impl Relay

{ } } - let entity_identity = - match FieldElement::from_str(&entity_identity.unwrap()) { - Ok(identity) => identity, - Err(e) => { - warn!( - target: LOG_TARGET, - error = %e, - "Parsing identity." - ); - continue; - } - }; + let entity_identity = match Felt::from_str(&entity_identity.unwrap()) { + Ok(identity) => identity, + Err(e) => { + warn!( + target: LOG_TARGET, + error = %e, + "Parsing identity." + ); + continue; + } + }; // TODO: have a nonce in model to check // against entity nonce and message nonce @@ -428,7 +427,7 @@ impl Relay

{ } } -fn ty_keys(ty: &Ty) -> Result, Error> { +fn ty_keys(ty: &Ty) -> Result, Error> { if let Ty::Struct(s) = &ty { let mut keys = Vec::new(); for m in s.keys() { @@ -585,13 +584,13 @@ pub fn parse_value_to_ty(value: &PrimitiveType, ty: &mut Ty) -> Result<(), Error *v = Some(u128::from_str(string).unwrap()); } Primitive::Felt252(v) => { - *v = Some(FieldElement::from_str(string).unwrap()); + *v = Some(Felt::from_str(string).unwrap()); } Primitive::ClassHash(v) => { - *v = Some(FieldElement::from_str(string).unwrap()); + *v = Some(Felt::from_str(string).unwrap()); } Primitive::ContractAddress(v) => { - *v = Some(FieldElement::from_str(string).unwrap()); + *v = Some(Felt::from_str(string).unwrap()); } Primitive::Bool(v) => { *v = Some(bool::from_str(string).unwrap()); diff --git a/crates/torii/libp2p/src/tests.rs b/crates/torii/libp2p/src/tests.rs index 7db5ab677b..9d61f02cc0 100644 --- a/crates/torii/libp2p/src/tests.rs +++ b/crates/torii/libp2p/src/tests.rs @@ -12,7 +12,7 @@ mod test { use dojo_types::primitive::Primitive; use dojo_types::schema::{Enum, EnumOption, Member, Struct, Ty}; use serde_json::Number; - use starknet_crypto::FieldElement; + use starknet::core::types::Felt; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -65,17 +65,17 @@ mod test { let mut ty = Ty::Primitive(Primitive::Felt252(None)); let value = PrimitiveType::String("1".to_string()); parse_value_to_ty(&value, &mut ty).unwrap(); - assert_eq!(ty, Ty::Primitive(Primitive::Felt252(Some(FieldElement::ONE)))); + assert_eq!(ty, Ty::Primitive(Primitive::Felt252(Some(Felt::ONE)))); let mut ty = Ty::Primitive(Primitive::ClassHash(None)); let value = PrimitiveType::String("1".to_string()); parse_value_to_ty(&value, &mut ty).unwrap(); - assert_eq!(ty, Ty::Primitive(Primitive::ClassHash(Some(FieldElement::ONE)))); + assert_eq!(ty, Ty::Primitive(Primitive::ClassHash(Some(Felt::ONE)))); let mut ty = Ty::Primitive(Primitive::ContractAddress(None)); let value = PrimitiveType::String("1".to_string()); parse_value_to_ty(&value, &mut ty).unwrap(); - assert_eq!(ty, Ty::Primitive(Primitive::ContractAddress(Some(FieldElement::ONE)))); + assert_eq!(ty, Ty::Primitive(Primitive::ContractAddress(Some(Felt::ONE)))); let mut ty = Ty::Primitive(Primitive::Bool(None)); let value = PrimitiveType::Bool(true); @@ -203,7 +203,7 @@ mod test { children: vec![ Member { name: "player".to_string(), - ty: Ty::Primitive(Primitive::ContractAddress(Some(FieldElement::ONE))), + ty: Ty::Primitive(Primitive::ContractAddress(Some(Felt::ONE))), key: true, }, Member { @@ -280,7 +280,7 @@ mod test { use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; use starknet::signers::SigningKey; - use starknet_crypto::FieldElement; + use starknet_crypto::Felt; use tokio::select; use tokio::time::sleep; use torii_core::sql::Sql; @@ -307,7 +307,7 @@ mod test { let account = sequencer.raw_account(); - let mut db = Sql::new(pool.clone(), FieldElement::from_bytes_be(&[0; 32]).unwrap()).await?; + let mut db = Sql::new(pool.clone(), Felt::from_bytes_be(&[0; 32])).await?; // Register the model of our Message db.register_model( @@ -327,8 +327,8 @@ mod test { ], }), Layout::Fixed(vec![]), - FieldElement::ZERO, - FieldElement::ZERO, + Felt::ZERO, + Felt::ZERO, 0, 0, 0, diff --git a/crates/torii/libp2p/src/typed_data.rs b/crates/torii/libp2p/src/typed_data.rs index 733c7ca29d..6877596273 100644 --- a/crates/torii/libp2p/src/typed_data.rs +++ b/crates/torii/libp2p/src/typed_data.rs @@ -4,8 +4,9 @@ use cainome::cairo_serde::ByteArray; use indexmap::IndexMap; use serde::{Deserialize, Serialize}; use serde_json::Number; +use starknet::core::types::Felt; use starknet::core::utils::{cairo_short_string_to_felt, get_selector_from_name}; -use starknet_crypto::{poseidon_hash_many, FieldElement}; +use starknet_crypto::poseidon_hash_many; use crate::errors::Error; @@ -233,8 +234,8 @@ pub(crate) fn get_value_type( Err(Error::InvalidMessageError(format!("Field {} not found in types", name))) } -fn get_hex(value: &str) -> Result { - if let Ok(felt) = FieldElement::from_str(value) { +fn get_hex(value: &str) -> Result { + if let Ok(felt) = Felt::from_str(value) { Ok(felt) } else { // assume its a short string and encode @@ -250,7 +251,7 @@ impl PrimitiveType { types: &IndexMap>, preset_types: &IndexMap>, ctx: &mut Ctx, - ) -> Result { + ) -> Result { match self { PrimitiveType::Object(obj) => { ctx.is_preset = preset_types.contains_key(r#type); @@ -273,7 +274,7 @@ impl PrimitiveType { }; // variant index - hashes.push(FieldElement::from(variant_type.index as u32)); + hashes.push(Felt::from(variant_type.index as u32)); // variant parameters for (idx, param) in arr.iter().enumerate() { @@ -329,8 +330,7 @@ impl PrimitiveType { .as_slice(), )), PrimitiveType::Bool(boolean) => { - let v = - if *boolean { FieldElement::from(1_u32) } else { FieldElement::from(0_u32) }; + let v = if *boolean { Felt::from(1_u32) } else { Felt::from(0_u32) }; Ok(v) } PrimitiveType::String(string) => match r#type { @@ -341,14 +341,14 @@ impl PrimitiveType { Error::InvalidMessageError(format!("Invalid string for bytearray: {}", e)) })?; - let mut hashes = vec![FieldElement::from(byte_array.data.len())]; + let mut hashes = vec![Felt::from(byte_array.data.len())]; for hash in byte_array.data { hashes.push(hash.felt()); } hashes.push(byte_array.pending_word); - hashes.push(FieldElement::from(byte_array.pending_word_len)); + hashes.push(Felt::from(byte_array.pending_word_len)); Ok(poseidon_hash_many(hashes.as_slice())) } @@ -363,7 +363,7 @@ impl PrimitiveType { _ => Err(Error::InvalidMessageError(format!("Invalid type {} for string", r#type))), }, PrimitiveType::Number(number) => { - let felt = FieldElement::from_str(&number.to_string()).map_err(|_| { + let felt = Felt::from_str(&number.to_string()).map_err(|_| { Error::InvalidMessageError(format!("Invalid number {}", number)) })?; Ok(felt) @@ -391,7 +391,7 @@ impl Domain { } } - pub fn encode(&self, types: &IndexMap>) -> Result { + pub fn encode(&self, types: &IndexMap>) -> Result { let mut object = IndexMap::new(); object.insert("name".to_string(), PrimitiveType::String(self.name.clone())); @@ -430,7 +430,7 @@ impl TypedData { Self { types, primary_type: primary_type.to_string(), domain, message } } - pub fn encode(&self, account: FieldElement) -> Result { + pub fn encode(&self, account: Felt) -> Result { let preset_types = get_preset_types(); if self.domain.revision.clone().unwrap_or("1".to_string()) != "1" { @@ -460,7 +460,7 @@ impl TypedData { #[cfg(test)] mod tests { use starknet::core::utils::starknet_keccak; - use starknet_crypto::FieldElement; + use starknet_crypto::Felt; use super::*; @@ -579,17 +579,14 @@ mod tests { assert_eq!( domain_hash, - FieldElement::from_hex_be( - "0x555f72e550b308e50c1a4f8611483a174026c982a9893a05c185eeb85399657" - ) - .unwrap() + Felt::from_hex("0x555f72e550b308e50c1a4f8611483a174026c982a9893a05c185eeb85399657") + .unwrap() ); } #[test] fn test_message_hash() { - let address = - FieldElement::from_hex_be("0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826").unwrap(); + let address = Felt::from_hex("0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826").unwrap(); let path = "mocks/example_baseTypes.json"; let file = std::fs::File::open(path).unwrap(); @@ -601,10 +598,8 @@ mod tests { assert_eq!( message_hash, - FieldElement::from_hex_be( - "0x790d9fa99cf9ad91c515aaff9465fcb1c87784d9cfb27271ed193675cd06f9c" - ) - .unwrap() + Felt::from_hex("0x790d9fa99cf9ad91c515aaff9465fcb1c87784d9cfb27271ed193675cd06f9c") + .unwrap() ); let path = "mocks/example_enum.json"; @@ -617,10 +612,8 @@ mod tests { assert_eq!( message_hash, - FieldElement::from_hex_be( - "0x3df10475ad5a8f49db4345a04a5b09164d2e24b09f6e1e236bc1ccd87627cc" - ) - .unwrap() + Felt::from_hex("0x3df10475ad5a8f49db4345a04a5b09164d2e24b09f6e1e236bc1ccd87627cc") + .unwrap() ); let path = "mocks/example_presetTypes.json"; @@ -633,10 +626,8 @@ mod tests { assert_eq!( message_hash, - FieldElement::from_hex_be( - "0x26e7b8cedfa63cdbed14e7e51b60ee53ac82bdf26724eb1e3f0710cb8987522" - ) - .unwrap() + Felt::from_hex("0x26e7b8cedfa63cdbed14e7e51b60ee53ac82bdf26724eb1e3f0710cb8987522") + .unwrap() ); } } diff --git a/crates/torii/libp2p/src/types.rs b/crates/torii/libp2p/src/types.rs index cfad2d5b87..927167123b 100644 --- a/crates/torii/libp2p/src/types.rs +++ b/crates/torii/libp2p/src/types.rs @@ -1,11 +1,11 @@ use serde::{Deserialize, Serialize}; -use starknet_crypto::FieldElement; +use starknet::core::types::Felt; use crate::typed_data::TypedData; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Message { pub message: TypedData, - pub signature_r: FieldElement, - pub signature_s: FieldElement, + pub signature_r: Felt, + pub signature_s: Felt, } diff --git a/crates/torii/types-test/Scarb.lock b/crates/torii/types-test/Scarb.lock index 20ffa2fec2..50ca9b8af4 100644 --- a/crates/torii/types-test/Scarb.lock +++ b/crates/torii/types-test/Scarb.lock @@ -15,7 +15,7 @@ source = "git+https://github.com/dojoengine/dojo?tag=v0.7.2#3da5cad9fdd39b81551e [[package]] name = "types_test" -version = "0.7.2" +version = "0.7.3" dependencies = [ "dojo", ] diff --git a/examples/rpc/starknet/starknet_getBlockWithReceipts.hurl b/examples/rpc/starknet/starknet_getBlockWithReceipts.hurl new file mode 100644 index 0000000000..9df401069a --- /dev/null +++ b/examples/rpc/starknet/starknet_getBlockWithReceipts.hurl @@ -0,0 +1,21 @@ +POST http://0.0.0.0:5050 +Content-Type: application/json +{ + "jsonrpc": "2.0", + "method": "starknet_getBlockWithReceipts", + "params": [ + "latest" + ], + "id":1 +} + +HTTP 200 +[Asserts] +jsonpath "$.error" not exists +jsonpath "$.result.transactions" isCollection +jsonpath "$.result.block_number" isInteger +jsonpath "$.result.block_hash" matches /^0x[A-Fa-f0-9]+$/ +jsonpath "$.result.parent_hash" matches /^0x[A-Fa-f0-9]+$/ +jsonpath "$.result.starknet_version" matches /^[0-9]+.[0-9]+.[0-9]+$/ +jsonpath "$.result.transactions[*].transaction" exists +jsonpath "$.result.transactions[*].receipt" exists diff --git a/examples/rpc/starknet/starknet_specVersion.hurl b/examples/rpc/starknet/starknet_specVersion.hurl index 2372882226..7ccc8bdefe 100644 --- a/examples/rpc/starknet/starknet_specVersion.hurl +++ b/examples/rpc/starknet/starknet_specVersion.hurl @@ -10,4 +10,4 @@ Content-Type: application/json HTTP 200 [Asserts] jsonpath "$.error" not exists -jsonpath "$.result" equals "0.6.0" +jsonpath "$.result" equals "0.7.1" diff --git a/examples/spawn-and-move/Scarb.lock b/examples/spawn-and-move/Scarb.lock index dd1c6d6c47..6d38546cd6 100644 --- a/examples/spawn-and-move/Scarb.lock +++ b/examples/spawn-and-move/Scarb.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "dojo_examples" -version = "0.7.2" +version = "0.7.3" dependencies = [ "dojo", ]