diff --git a/Cargo.lock b/Cargo.lock index 388e03e252..9a1c82a5c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,7 +45,7 @@ dependencies = [ "starknet 0.12.0", "starknet-crypto 0.7.2", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", "tokio", "toml 0.8.19", "tsify-next", @@ -251,7 +251,7 @@ dependencies = [ "alloy-transport 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures", "futures-util", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -270,7 +270,7 @@ dependencies = [ "alloy-transport 0.3.6 (git+https://github.com/alloy-rs/alloy)", "futures", "futures-util", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -391,7 +391,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tracing", ] @@ -404,7 +404,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tracing", ] @@ -426,7 +426,7 @@ dependencies = [ "async-trait", "auto_impl", "futures-utils-wasm", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -446,7 +446,7 @@ dependencies = [ "async-trait", "auto_impl", "futures-utils-wasm", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -483,7 +483,7 @@ dependencies = [ "rand 0.8.5", "serde_json", "tempfile", - "thiserror", + "thiserror 1.0.63", "tracing", "url", ] @@ -541,7 +541,7 @@ dependencies = [ "reqwest 0.12.7", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -577,7 +577,7 @@ dependencies = [ "reqwest 0.12.7", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -602,7 +602,7 @@ checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -729,7 +729,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -742,7 +742,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -757,7 +757,7 @@ dependencies = [ "async-trait", "k256", "rand 0.8.5", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -771,7 +771,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -788,7 +788,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "syn-solidity", "tiny-keccak", ] @@ -806,7 +806,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.77", + "syn 2.0.90", "syn-solidity", ] @@ -845,7 +845,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tokio", "tower 0.5.1", "tracing", @@ -863,7 +863,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tokio", "tower 0.5.1", "tracing", @@ -1017,7 +1017,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1259,7 +1259,7 @@ dependencies = [ "nom", "num-traits 0.2.19", "rusticata-macros", - "thiserror", + "thiserror 1.0.63", "time", ] @@ -1275,7 +1275,7 @@ dependencies = [ "nom", "num-traits 0.2.19", "rusticata-macros", - "thiserror", + "thiserror 1.0.63", "time", ] @@ -1299,7 +1299,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "synstructure 0.13.1", ] @@ -1322,7 +1322,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1445,7 +1445,7 @@ dependencies = [ "serde_urlencoded", "static_assertions_next", "tempfile", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -1461,8 +1461,8 @@ dependencies = [ "proc-macro2", "quote", "strum 0.26.3", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -1568,7 +1568,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1616,7 +1616,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1633,7 +1633,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1683,7 +1683,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1989,7 +1989,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -2011,7 +2011,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.77", + "syn 2.0.90", "which 4.4.2", ] @@ -2143,7 +2143,7 @@ dependencies = [ "starknet_api", "strum 0.25.0", "strum_macros 0.25.3", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -2168,7 +2168,7 @@ dependencies = [ "cid", "dashmap 6.1.0", "multihash 0.19.1", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -2186,7 +2186,7 @@ dependencies = [ [[package]] name = "bonsai-trie" version = "0.1.0" -source = "git+https://github.com/madara-alliance/bonsai-trie/?rev=56d7d62#56d7d62232fd72419f1d50de8bc747b70a9db68f" +source = "git+https://github.com/dojoengine/bonsai-trie/?branch=kariy/public-path#9108a1264fd82f5e68f5056f8df767042440825f" dependencies = [ "bitvec", "derive_more 0.99.18", @@ -2195,8 +2195,10 @@ dependencies = [ "parity-scale-codec", "rayon", "serde", + "slotmap", "smallvec", "starknet-types-core", + "thiserror 2.0.6", ] [[package]] @@ -2219,7 +2221,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "syn_derive", ] @@ -2403,7 +2405,7 @@ dependencies = [ "hashbrown 0.13.2", "instant", "once_cell", - "thiserror", + "thiserror 1.0.63", "tokio", ] @@ -2445,7 +2447,7 @@ dependencies = [ "serde_json", "starknet 0.12.0", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", "tracing", "tracing-subscriber", "url", @@ -2471,7 +2473,7 @@ dependencies = [ "serde_json", "starknet 0.12.0", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", "tracing", "tracing-subscriber", "url", @@ -2497,7 +2499,7 @@ dependencies = [ "serde_json", "starknet 0.12.0", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", "tracing", "tracing-subscriber", "url", @@ -2512,7 +2514,7 @@ dependencies = [ "serde", "serde_with 3.11.0", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -2522,7 +2524,7 @@ source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299 dependencies = [ "serde", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -2532,7 +2534,7 @@ source = "git+https://github.com/cartridge-gg/cainome?rev=5c2616c273faca7700d2ba dependencies = [ "serde", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -2542,7 +2544,7 @@ source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.10#6fefd8bf4370c7 dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "unzip-n", ] @@ -2553,7 +2555,7 @@ source = "git+https://github.com/cartridge-gg/cainome?rev=5c2616c273faca7700d2ba dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "unzip-n", ] @@ -2566,8 +2568,8 @@ dependencies = [ "quote", "serde_json", "starknet 0.12.0", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -2579,8 +2581,8 @@ dependencies = [ "quote", "serde_json", "starknet 0.12.0", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -2592,8 +2594,8 @@ dependencies = [ "quote", "serde_json", "starknet 0.12.0", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -2610,8 +2612,8 @@ dependencies = [ "quote", "serde_json", "starknet 0.12.0", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -2628,8 +2630,8 @@ dependencies = [ "quote", "serde_json", "starknet 0.12.0", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -2646,8 +2648,8 @@ dependencies = [ "quote", "serde_json", "starknet 0.12.0", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -2664,8 +2666,8 @@ dependencies = [ "quote", "serde_json", "starknet 0.12.0", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -2682,8 +2684,8 @@ dependencies = [ "quote", "serde_json", "starknet 0.12.0", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -2700,8 +2702,8 @@ dependencies = [ "quote", "serde_json", "starknet 0.12.0", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.63", ] [[package]] @@ -2741,7 +2743,7 @@ dependencies = [ "rust-analyzer-salsa", "semver 1.0.23", "smol_str", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -2840,7 +2842,7 @@ dependencies = [ "rust-analyzer-salsa", "serde", "smol_str", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -2922,7 +2924,7 @@ checksum = "e32e958decd95ae122ee64daa26721da2f76e83231047f947fd9cdc5d3c90cc6" dependencies = [ "quote", "scarb-stable-hash 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -2978,7 +2980,7 @@ checksum = "d72f17373740f242d6995e896b9195c2cedff7e8b14e496afdd16b405039d1fb" dependencies = [ "cairo-lang-debug", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -2991,7 +2993,7 @@ dependencies = [ "cairo-lang-utils", "serde", "smol_str", - "thiserror", + "thiserror 1.0.63", "toml 0.8.19", ] @@ -3023,7 +3025,7 @@ dependencies = [ "sha2 0.10.8", "smol_str", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -3076,7 +3078,7 @@ dependencies = [ "sha3", "smol_str", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -3092,7 +3094,7 @@ dependencies = [ "itertools 0.12.1", "num-bigint", "num-traits 0.2.19", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -3108,7 +3110,7 @@ dependencies = [ "itertools 0.12.1", "num-bigint", "num-traits 0.2.19", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -3153,7 +3155,7 @@ dependencies = [ "num-bigint", "num-traits 0.2.19", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -3193,7 +3195,7 @@ dependencies = [ "serde_json", "smol_str", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -3216,7 +3218,7 @@ dependencies = [ "sha3", "smol_str", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -3434,7 +3436,7 @@ dependencies = [ "serde", "serde_json", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -3466,7 +3468,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -3532,7 +3534,7 @@ dependencies = [ "http 1.1.0", "jsonrpsee 0.24.6", "serde", - "thiserror", + "thiserror 1.0.63", "tracing", ] @@ -3608,7 +3610,7 @@ dependencies = [ "serde", "serde_repr", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.63", "time", ] @@ -3802,7 +3804,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -3814,7 +3816,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -3938,7 +3940,7 @@ dependencies = [ "mime", "mime_guess", "rand 0.8.5", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -4367,7 +4369,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -4428,7 +4430,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -4450,7 +4452,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -4533,7 +4535,7 @@ dependencies = [ "monch", "os_pipe", "path-dedot", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-util", ] @@ -4606,7 +4608,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -4627,7 +4629,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -4637,7 +4639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" dependencies = [ "derive_builder_core", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -4650,7 +4652,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -4670,7 +4672,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "unicode-xid", ] @@ -4683,7 +4685,7 @@ dependencies = [ "console", "shell-words", "tempfile", - "thiserror", + "thiserror 1.0.63", "zeroize", ] @@ -4808,7 +4810,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -4836,7 +4838,7 @@ dependencies = [ "serde_json", "sozo-scarbext", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", "tokio", ] @@ -4928,7 +4930,7 @@ dependencies = [ "metrics-exporter-prometheus", "metrics-process", "metrics-util", - "thiserror", + "thiserror 1.0.63", "tracing", ] @@ -4950,7 +4952,7 @@ dependencies = [ "serde", "serde_json", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", "toml 0.8.19", "url", ] @@ -4973,7 +4975,7 @@ dependencies = [ "starknet-crypto 0.7.2", "strum 0.25.0", "strum_macros 0.25.3", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -4994,7 +4996,7 @@ dependencies = [ "starknet-crypto 0.7.2", "strum 0.25.0", "strum_macros 0.25.3", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -5010,7 +5012,7 @@ dependencies = [ "rpassword", "serde_json", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -5035,7 +5037,7 @@ dependencies = [ "serde_with 3.11.0", "starknet 0.12.0", "starknet-crypto 0.7.2", - "thiserror", + "thiserror 1.0.63", "tokio", "toml 0.8.19", "tracing", @@ -5215,7 +5217,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -5227,7 +5229,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -5308,7 +5310,7 @@ dependencies = [ "serde_json", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.63", "uuid 0.8.2", ] @@ -5706,7 +5708,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -5796,7 +5798,7 @@ checksum = "553630feadf7b76442b0849fd25fdf89b860d933623aec9693fed19af0400c78" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -5904,7 +5906,7 @@ dependencies = [ "regex", "signal-hook", "smallvec", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -5917,7 +5919,7 @@ dependencies = [ "gix-date", "gix-utils", "itoa", - "thiserror", + "thiserror 1.0.63", "winnow", ] @@ -5932,7 +5934,7 @@ dependencies = [ "gix-object", "gix-worktree-stream", "jiff", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -5948,7 +5950,7 @@ dependencies = [ "gix-trace", "kstring", "smallvec", - "thiserror", + "thiserror 1.0.63", "unicode-bom", ] @@ -5958,7 +5960,7 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a371db66cbd4e13f0ed9dc4c0fea712d7276805fccc877f77e96374d317e87ae" dependencies = [ - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -5967,7 +5969,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45c8751169961ba7640b513c3b24af61aa962c967aaf04116734975cd5af0c52" dependencies = [ - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -5993,7 +5995,7 @@ dependencies = [ "gix-features", "gix-hash", "memmap2", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6012,7 +6014,7 @@ dependencies = [ "memchr", "once_cell", "smallvec", - "thiserror", + "thiserror 1.0.63", "unicode-bom", "winnow", ] @@ -6027,7 +6029,7 @@ dependencies = [ "bstr", "gix-path", "libc", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6044,7 +6046,7 @@ dependencies = [ "gix-sec", "gix-trace", "gix-url", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6056,7 +6058,7 @@ dependencies = [ "bstr", "itoa", "jiff", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6076,7 +6078,7 @@ dependencies = [ "gix-trace", "gix-worktree", "imara-diff", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6096,7 +6098,7 @@ dependencies = [ "gix-trace", "gix-utils", "gix-worktree", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6112,7 +6114,7 @@ dependencies = [ "gix-path", "gix-ref", "gix-sec", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6134,7 +6136,7 @@ dependencies = [ "parking_lot 0.12.3", "prodash", "sha1_smol", - "thiserror", + "thiserror 1.0.63", "walkdir", ] @@ -6156,7 +6158,7 @@ dependencies = [ "gix-trace", "gix-utils", "smallvec", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6189,7 +6191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93d7df7366121b5018f947a04d37f034717e113dcf9ccd85c34b58e57a74d5e" dependencies = [ "faster-hex", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6241,7 +6243,7 @@ dependencies = [ "memmap2", "rustix 0.38.37", "smallvec", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6252,7 +6254,7 @@ checksum = "e3bc7fe297f1f4614774989c00ec8b1add59571dc9b024b4c00acb7dedd4e19d" dependencies = [ "gix-tempfile", "gix-utils", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6264,7 +6266,7 @@ dependencies = [ "bstr", "gix-actor", "gix-date", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6280,7 +6282,7 @@ dependencies = [ "gix-object", "gix-revwalk", "smallvec", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6298,7 +6300,7 @@ dependencies = [ "gix-validate", "itoa", "smallvec", - "thiserror", + "thiserror 1.0.63", "winnow", ] @@ -6319,7 +6321,7 @@ dependencies = [ "gix-quote", "parking_lot 0.12.3", "tempfile", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6337,7 +6339,7 @@ dependencies = [ "gix-path", "memmap2", "smallvec", - "thiserror", + "thiserror 1.0.63", "uluru", ] @@ -6350,7 +6352,7 @@ dependencies = [ "bstr", "faster-hex", "gix-trace", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6363,7 +6365,7 @@ dependencies = [ "gix-trace", "home", "once_cell", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6378,7 +6380,7 @@ dependencies = [ "gix-config-value", "gix-glob", "gix-path", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6391,7 +6393,7 @@ dependencies = [ "gix-config-value", "parking_lot 0.12.3", "rustix 0.38.37", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6402,7 +6404,7 @@ checksum = "cbff4f9b9ea3fa7a25a70ee62f545143abef624ac6aa5884344e70c8b0a1d9ff" dependencies = [ "bstr", "gix-utils", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6422,7 +6424,7 @@ dependencies = [ "gix-utils", "gix-validate", "memmap2", - "thiserror", + "thiserror 1.0.63", "winnow", ] @@ -6437,7 +6439,7 @@ dependencies = [ "gix-revision", "gix-validate", "smallvec", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6453,7 +6455,7 @@ dependencies = [ "gix-object", "gix-revwalk", "gix-trace", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6468,7 +6470,7 @@ dependencies = [ "gix-hashtable", "gix-object", "smallvec", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6503,7 +6505,7 @@ dependencies = [ "gix-pathspec", "gix-worktree", "portable-atomic", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6518,7 +6520,7 @@ dependencies = [ "gix-pathspec", "gix-refspec", "gix-url", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6557,7 +6559,7 @@ dependencies = [ "gix-object", "gix-revwalk", "smallvec", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6570,7 +6572,7 @@ dependencies = [ "gix-features", "gix-path", "home", - "thiserror", + "thiserror 1.0.63", "url", ] @@ -6592,7 +6594,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f2badbb64e57b404593ee26b752c26991910fd0d81fe6f9a71c1a8309b6c86" dependencies = [ "bstr", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6631,7 +6633,7 @@ dependencies = [ "gix-path", "gix-worktree", "io-close", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6649,7 +6651,7 @@ dependencies = [ "gix-path", "gix-traverse", "parking_lot 0.12.3", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6696,7 +6698,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -6717,7 +6719,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -6799,7 +6801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2ebc8013b4426d5b81a4364c419a95ed0b404af2b82e2457de52d9348f0e474" dependencies = [ "combine 3.8.1", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -6917,7 +6919,7 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -7029,7 +7031,7 @@ dependencies = [ "serde", "serde_json", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "tracing-log 0.1.4", @@ -7075,7 +7077,7 @@ dependencies = [ "once_cell", "rand 0.8.5", "socket2 0.5.7", - "thiserror", + "thiserror 1.0.63", "tinyvec", "tokio", "tracing", @@ -7098,7 +7100,7 @@ dependencies = [ "rand 0.8.5", "resolv-conf", "smallvec", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -7785,7 +7787,7 @@ dependencies = [ "rand 0.8.5", "rtcp", "rtp 0.9.0", - "thiserror", + "thiserror 1.0.63", "tokio", "waitgroup", "webrtc-srtp", @@ -7800,7 +7802,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -7850,7 +7852,7 @@ dependencies = [ "hyper-multipart-rfc7578", "hyper-rustls 0.23.2", "ipfs-api-prelude", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -7870,7 +7872,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-util", "tracing", @@ -8018,7 +8020,7 @@ dependencies = [ "combine 4.6.7", "jni-sys", "log", - "thiserror", + "thiserror 1.0.63", "walkdir", ] @@ -8033,7 +8035,7 @@ dependencies = [ "combine 4.6.7", "jni-sys", "log", - "thiserror", + "thiserror 1.0.63", "walkdir", "windows-sys 0.45.0", ] @@ -8116,7 +8118,7 @@ dependencies = [ "pin-project", "rustls-native-certs 0.6.3", "soketto 0.7.1", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-rustls 0.24.1", "tokio-util", @@ -8139,7 +8141,7 @@ dependencies = [ "rustls-pki-types", "rustls-platform-verifier", "soketto 0.8.0", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-rustls 0.26.0", "tokio-util", @@ -8170,7 +8172,7 @@ dependencies = [ "serde", "serde_json", "soketto 0.7.1", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "wasm-bindgen-futures", @@ -8194,7 +8196,7 @@ dependencies = [ "rustc-hash 2.0.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-stream", "tracing", @@ -8214,7 +8216,7 @@ dependencies = [ "rustc-hash 1.1.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -8237,7 +8239,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tokio", "tower 0.4.13", "tracing", @@ -8267,7 +8269,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -8302,7 +8304,7 @@ dependencies = [ "beef", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tracing", ] @@ -8315,7 +8317,7 @@ dependencies = [ "http 1.1.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -8442,7 +8444,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -8480,7 +8482,7 @@ dependencies = [ "starknet 0.12.0", "starknet-types-core", "tempfile", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -8492,7 +8494,6 @@ version = "1.0.8" dependencies = [ "anyhow", "arbitrary", - "bitvec", "criterion", "dojo-metrics", "katana-primitives", @@ -8507,9 +8508,8 @@ dependencies = [ "serde_json", "smallvec", "starknet 0.12.0", - "starknet-types-core", "tempfile", - "thiserror", + "thiserror 1.0.63", "tracing", ] @@ -8525,6 +8525,7 @@ dependencies = [ "katana-primitives", "katana-provider", "katana-rpc-types", + "katana-trie", "num-traits 0.2.19", "oneshot", "parking_lot 0.12.3", @@ -8535,7 +8536,7 @@ dependencies = [ "serde_json", "similar-asserts", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -8549,7 +8550,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -8613,7 +8614,7 @@ dependencies = [ "serde_json", "starknet 0.12.0", "tempfile", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -8628,7 +8629,7 @@ dependencies = [ "katana-primitives", "katana-provider", "katana-stage", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -8644,7 +8645,7 @@ dependencies = [ "katana-provider", "parking_lot 0.12.3", "rand 0.8.5", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -8677,7 +8678,7 @@ dependencies = [ "starknet-types-core", "strum 0.25.0", "strum_macros 0.25.3", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -8702,7 +8703,7 @@ dependencies = [ "starknet 0.12.0", "starknet-types-core", "tempfile", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -8735,6 +8736,7 @@ dependencies = [ "katana-rpc-types", "katana-rpc-types-builder", "katana-tasks", + "katana-trie", "metrics", "num-traits 0.2.19", "rand 0.8.5", @@ -8744,7 +8746,7 @@ dependencies = [ "similar-asserts", "starknet 0.12.0", "tempfile", - "thiserror", + "thiserror 1.0.63", "tokio", "tower 0.4.13", "tower-http 0.4.4", @@ -8779,6 +8781,7 @@ dependencies = [ "katana-pool", "katana-primitives", "katana-provider", + "katana-trie", "num-traits 0.2.19", "rstest 0.18.2", "serde", @@ -8787,7 +8790,7 @@ dependencies = [ "serde_with 3.11.0", "similar-asserts", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -8821,7 +8824,7 @@ version = "1.0.8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -8860,7 +8863,7 @@ dependencies = [ "katana-tasks", "num-traits 0.2.19", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -8871,7 +8874,7 @@ version = "1.0.8" dependencies = [ "futures", "rayon", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-metrics", "tokio-util", @@ -8890,7 +8893,7 @@ dependencies = [ "slab", "starknet 0.12.0", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -9032,7 +9035,7 @@ checksum = "ee58dbc414bd23885d7da915e0457618b36d1fc950a6169ef2cb29829d1b1a1d" dependencies = [ "bytes", "lazy_static", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -9099,7 +9102,7 @@ dependencies = [ "multiaddr 0.18.1", "pin-project", "rw-stream-sink", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -9144,7 +9147,7 @@ dependencies = [ "rand 0.8.5", "rw-stream-sink", "smallvec", - "thiserror", + "thiserror 1.0.63", "tracing", "unsigned-varint 0.8.0", "void", @@ -9213,7 +9216,7 @@ dependencies = [ "quick-protobuf", "quick-protobuf-codec", "smallvec", - "thiserror", + "thiserror 1.0.63", "tracing", "void", ] @@ -9231,7 +9234,7 @@ dependencies = [ "quick-protobuf", "rand 0.8.5", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.63", "tracing", "zeroize", ] @@ -9293,7 +9296,7 @@ dependencies = [ "sha2 0.10.8", "snow", "static_assertions", - "thiserror", + "thiserror 1.0.63", "tracing", "x25519-dalek", "zeroize", @@ -9334,7 +9337,7 @@ dependencies = [ "ring 0.17.8", "rustls 0.23.13", "socket2 0.5.7", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -9357,7 +9360,7 @@ dependencies = [ "quick-protobuf-codec", "rand 0.8.5", "static_assertions", - "thiserror", + "thiserror 1.0.63", "tracing", "void", "web-time", @@ -9396,7 +9399,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -9428,7 +9431,7 @@ dependencies = [ "ring 0.17.8", "rustls 0.23.13", "rustls-webpki 0.101.7", - "thiserror", + "thiserror 1.0.63", "x509-parser 0.16.0", "yasna", ] @@ -9468,7 +9471,7 @@ dependencies = [ "rcgen", "serde", "stun 0.6.0", - "thiserror", + "thiserror 1.0.63", "tinytemplate", "tokio", "tokio-util", @@ -9493,7 +9496,7 @@ dependencies = [ "rand 0.8.5", "serde", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.63", "tinytemplate", "tracing", ] @@ -9512,7 +9515,7 @@ dependencies = [ "libp2p-identity", "libp2p-webrtc-utils", "send_wrapper 0.6.0", - "thiserror", + "thiserror 1.0.63", "tracing", "wasm-bindgen", "wasm-bindgen-futures", @@ -9533,7 +9536,7 @@ dependencies = [ "pin-project-lite", "rw-stream-sink", "soketto 0.8.0", - "thiserror", + "thiserror 1.0.63", "tracing", "url", "webpki-roots 0.25.4", @@ -9550,7 +9553,7 @@ dependencies = [ "libp2p-core", "parking_lot 0.12.3", "send_wrapper 0.6.0", - "thiserror", + "thiserror 1.0.63", "tracing", "wasm-bindgen", "web-sys", @@ -9564,7 +9567,7 @@ dependencies = [ "either", "futures", "libp2p-core", - "thiserror", + "thiserror 1.0.63", "tracing", "yamux 0.12.1", "yamux 0.13.3", @@ -9626,7 +9629,7 @@ checksum = "cb26336e6dc7cc76e7927d2c9e7e3bb376d7af65a6f56a0b16c47d18a9b1abc5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -9810,7 +9813,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -9829,7 +9832,7 @@ dependencies = [ "metrics", "metrics-util", "quanta", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -10163,7 +10166,7 @@ dependencies = [ "anyhow", "byteorder", "paste", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -10177,7 +10180,7 @@ dependencies = [ "log", "netlink-packet-core", "netlink-sys", - "thiserror", + "thiserror 1.0.63", "tokio", ] @@ -10390,7 +10393,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -10508,7 +10511,7 @@ checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -10609,7 +10612,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -10888,7 +10891,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.63", "ucd-trie", ] @@ -10912,7 +10915,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -10966,7 +10969,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -11010,7 +11013,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -11201,7 +11204,7 @@ dependencies = [ "smallvec", "symbolic-demangle", "tempfile", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -11272,7 +11275,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -11303,7 +11306,7 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "thiserror", + "thiserror 1.0.63", "toml 0.5.11", ] @@ -11359,14 +11362,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -11420,7 +11423,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -11443,7 +11446,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -11474,7 +11477,7 @@ checksum = "6ff7ff745a347b87471d859a377a9a404361e7efc2a971d73424a6d183c0fc77" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -11514,7 +11517,7 @@ dependencies = [ "prost 0.12.6", "prost-types 0.12.6", "regex", - "syn 2.0.77", + "syn 2.0.90", "tempfile", ] @@ -11535,7 +11538,7 @@ dependencies = [ "prost 0.13.3", "prost-types 0.13.3", "regex", - "syn 2.0.77", + "syn 2.0.90", "tempfile", ] @@ -11549,7 +11552,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -11562,7 +11565,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -11599,7 +11602,7 @@ dependencies = [ "serde", "serde_json", "starknet-types-core", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -11694,7 +11697,7 @@ dependencies = [ "asynchronous-codec", "bytes", "quick-protobuf", - "thiserror", + "thiserror 1.0.63", "unsigned-varint 0.8.0", ] @@ -11721,7 +11724,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls 0.23.13", "socket2 0.5.7", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", ] @@ -11738,7 +11741,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls 0.23.13", "slab", - "thiserror", + "thiserror 1.0.63", "tinyvec", "tracing", ] @@ -11888,7 +11891,7 @@ dependencies = [ "rand_chacha", "simd_helpers", "system-deps", - "thiserror", + "thiserror 1.0.63", "v_frame", "wasm-bindgen", ] @@ -12005,7 +12008,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -12209,7 +12212,7 @@ dependencies = [ "libc", "parking_lot 0.12.3", "reth-mdbx-sys", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -12412,7 +12415,7 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.1", - "syn 2.0.77", + "syn 2.0.90", "unicode-ident", ] @@ -12425,7 +12428,7 @@ dependencies = [ "quote", "rand 0.8.5", "rustc_version 0.4.1", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -12435,7 +12438,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33648a781874466a62d89e265fee9f17e32bc7d05a256e6cca41bf97eadcd8aa" dependencies = [ "bytes", - "thiserror", + "thiserror 1.0.63", "webrtc-util 0.8.1", ] @@ -12450,7 +12453,7 @@ dependencies = [ "netlink-packet-route", "netlink-proto", "nix 0.24.3", - "thiserror", + "thiserror 1.0.63", "tokio", ] @@ -12473,7 +12476,7 @@ dependencies = [ "bytes", "rand 0.8.5", "serde", - "thiserror", + "thiserror 1.0.63", "webrtc-util 0.8.1", ] @@ -12486,7 +12489,7 @@ dependencies = [ "bytes", "rand 0.8.5", "serde", - "thiserror", + "thiserror 1.0.63", "webrtc-util 0.8.1", ] @@ -12547,7 +12550,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -12907,7 +12910,7 @@ dependencies = [ "starknet 0.12.0", "starknet-crypto 0.7.2", "tempdir", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -12938,7 +12941,7 @@ dependencies = [ "serde_json", "serde_with 3.11.0", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -13010,7 +13013,7 @@ dependencies = [ "smallvec", "smol_str", "tar", - "thiserror", + "thiserror 1.0.63", "tokio", "toml 0.8.19", "toml_edit", @@ -13043,7 +13046,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -13056,7 +13059,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -13140,7 +13143,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -13185,7 +13188,7 @@ checksum = "13254db766b17451aced321e7397ebf0a446ef0c8d2942b6e67a95815421093f" dependencies = [ "rand 0.8.5", "substring", - "thiserror", + "thiserror 1.0.63", "url", ] @@ -13353,7 +13356,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -13364,7 +13367,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -13408,7 +13411,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -13475,7 +13478,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -13487,7 +13490,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -13522,7 +13525,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -13737,7 +13740,7 @@ dependencies = [ "serde_json", "starknet 0.12.0", "tempfile", - "thiserror", + "thiserror 1.0.63", "tokio", "tower-http 0.5.2", "tracing", @@ -13746,6 +13749,15 @@ dependencies = [ "webbrowser", ] +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + [[package]] name = "smallvec" version = "1.13.2" @@ -13874,7 +13886,7 @@ dependencies = [ "starknet 0.12.0", "starknet-crypto 0.7.2", "tabled", - "thiserror", + "thiserror 1.0.63", "tokio", "toml 0.8.19", "tracing", @@ -13909,7 +13921,7 @@ dependencies = [ "spinoff", "starknet 0.12.0", "starknet-crypto 0.7.2", - "thiserror", + "thiserror 1.0.63", "tokio", "toml 0.8.19", "tracing", @@ -13950,7 +13962,7 @@ dependencies = [ "serde_json", "sozo-scarbext", "starknet 0.12.0", - "thiserror", + "thiserror 1.0.63", "url", "urlencoding", "walkdir", @@ -14061,7 +14073,7 @@ dependencies = [ "sha2 0.10.8", "smallvec", "sqlformat", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-stream", "tracing", @@ -14079,7 +14091,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -14103,7 +14115,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.77", + "syn 2.0.90", "tempfile", "tokio", "url", @@ -14147,7 +14159,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror", + "thiserror 1.0.63", "tracing", "uuid 1.10.0", "whoami", @@ -14187,7 +14199,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror", + "thiserror 1.0.63", "tracing", "uuid 1.10.0", "whoami", @@ -14267,7 +14279,7 @@ dependencies = [ "starknet-crypto 0.7.2", "starknet-providers 0.11.0", "starknet-signers 0.9.0", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -14282,7 +14294,7 @@ dependencies = [ "starknet-crypto 0.7.2", "starknet-providers 0.12.0", "starknet-signers 0.10.0", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -14297,7 +14309,7 @@ dependencies = [ "starknet-accounts 0.10.0", "starknet-core 0.11.1", "starknet-providers 0.11.0", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -14312,7 +14324,7 @@ dependencies = [ "starknet-accounts 0.11.0", "starknet-core 0.12.0", "starknet-providers 0.12.0", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -14420,7 +14432,7 @@ checksum = "bbc159a1934c7be9761c237333a57febe060ace2bc9e3b337a59a37af206d19f" dependencies = [ "starknet-curve 0.4.2", "starknet-ff", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -14471,7 +14483,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8986a940af916fc0a034f4e42c6ba76d94f1e97216d75447693dfd7aefaf3ef2" dependencies = [ "starknet-core 0.12.0", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -14491,7 +14503,7 @@ dependencies = [ "serde_json", "serde_with 2.3.3", "starknet-core 0.11.1", - "thiserror", + "thiserror 1.0.63", "url", ] @@ -14512,7 +14524,7 @@ dependencies = [ "serde_json", "serde_with 3.11.0", "starknet-core 0.12.0", - "thiserror", + "thiserror 1.0.63", "url", ] @@ -14530,7 +14542,7 @@ dependencies = [ "rand 0.8.5", "starknet-core 0.11.1", "starknet-crypto 0.7.2", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -14547,7 +14559,7 @@ dependencies = [ "rand 0.8.5", "starknet-core 0.12.0", "starknet-crypto 0.7.2", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -14587,7 +14599,7 @@ dependencies = [ "starknet-types-core", "strum 0.24.1", "strum_macros 0.24.3", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -14688,7 +14700,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -14701,7 +14713,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -14717,7 +14729,7 @@ dependencies = [ "rand 0.8.5", "ring 0.17.8", "subtle", - "thiserror", + "thiserror 1.0.63", "tokio", "url", "webrtc-util 0.8.1", @@ -14736,7 +14748,7 @@ dependencies = [ "rand 0.8.5", "ring 0.17.8", "subtle", - "thiserror", + "thiserror 1.0.63", "tokio", "url", "webrtc-util 0.9.0", @@ -14808,9 +14820,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -14826,7 +14838,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -14838,7 +14850,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -14876,7 +14888,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -15031,7 +15043,16 @@ version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.63", +] + +[[package]] +name = "thiserror" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" +dependencies = [ + "thiserror-impl 2.0.6", ] [[package]] @@ -15042,7 +15063,18 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -15198,7 +15230,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -15426,7 +15458,7 @@ dependencies = [ "proc-macro2", "prost-build 0.12.6", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -15440,7 +15472,7 @@ dependencies = [ "prost-build 0.13.3", "prost-types 0.13.3", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -15492,7 +15524,7 @@ dependencies = [ "httparse", "js-sys", "pin-project", - "thiserror", + "thiserror 1.0.63", "tonic 0.12.3", "tower-service", "wasm-bindgen", @@ -15586,7 +15618,7 @@ dependencies = [ "serde_json", "starknet 0.12.0", "starknet-crypto 0.7.2", - "thiserror", + "thiserror 1.0.63", "tokio", "tonic 0.11.0", "tonic 0.12.3", @@ -15628,7 +15660,7 @@ dependencies = [ "starknet 0.12.0", "starknet-crypto 0.7.2", "tempfile", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-util", "tracing", @@ -15664,7 +15696,7 @@ dependencies = [ "strum 0.25.0", "strum_macros 0.25.3", "tempfile", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-stream", "toml 0.8.19", @@ -15705,7 +15737,7 @@ dependencies = [ "strum 0.25.0", "strum_macros 0.25.3", "tempfile", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-stream", "tonic 0.11.0", @@ -15745,7 +15777,7 @@ dependencies = [ "starknet 0.12.0", "starknet-crypto 0.7.2", "tempfile", - "thiserror", + "thiserror 1.0.63", "tokio", "torii-core", "tracing", @@ -15911,7 +15943,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -15940,7 +15972,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -16066,7 +16098,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -16083,7 +16115,7 @@ dependencies = [ "log", "rand 0.8.5", "sha1", - "thiserror", + "thiserror 1.0.63", "url", "utf-8", ] @@ -16102,7 +16134,7 @@ dependencies = [ "log", "rand 0.8.5", "sha1", - "thiserror", + "thiserror 1.0.63", "url", "utf-8", ] @@ -16121,7 +16153,7 @@ dependencies = [ "rand 0.8.5", "ring 0.17.8", "stun 0.5.1", - "thiserror", + "thiserror 1.0.63", "tokio", "tokio-util", "webrtc-util 0.8.1", @@ -16144,7 +16176,7 @@ checksum = "560b82d656506509d43abe30e0ba64c56b1953ab3d4fe7ba5902747a7a3cedd5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -16212,7 +16244,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" dependencies = [ - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -16619,7 +16651,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -16653,7 +16685,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -16687,7 +16719,7 @@ checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -16820,7 +16852,7 @@ dependencies = [ "sha2 0.10.8", "smol_str", "stun 0.5.1", - "thiserror", + "thiserror 1.0.63", "time", "tokio", "turn", @@ -16844,7 +16876,7 @@ checksum = "e8c08e648e10572b9edbe741074e0f4d3cb221aa7cdf9a814ee71606de312f33" dependencies = [ "bytes", "log", - "thiserror", + "thiserror 1.0.63", "tokio", "webrtc-sctp", "webrtc-util 0.8.1", @@ -16880,7 +16912,7 @@ dependencies = [ "sha1", "sha2 0.10.8", "subtle", - "thiserror", + "thiserror 1.0.63", "tokio", "webrtc-util 0.8.1", "x25519-dalek", @@ -16901,7 +16933,7 @@ dependencies = [ "serde", "serde_json", "stun 0.5.1", - "thiserror", + "thiserror 1.0.63", "tokio", "turn", "url", @@ -16919,7 +16951,7 @@ checksum = "ce981f93104a8debb3563bb0cedfe4aa2f351fdf6b53f346ab50009424125c08" dependencies = [ "log", "socket2 0.5.7", - "thiserror", + "thiserror 1.0.63", "tokio", "webrtc-util 0.8.1", ] @@ -16934,7 +16966,7 @@ dependencies = [ "bytes", "rand 0.8.5", "rtp 0.10.0", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -16949,7 +16981,7 @@ dependencies = [ "crc", "log", "rand 0.8.5", - "thiserror", + "thiserror 1.0.63", "tokio", "webrtc-util 0.8.1", ] @@ -16972,7 +17004,7 @@ dependencies = [ "rtp 0.9.0", "sha1", "subtle", - "thiserror", + "thiserror 1.0.63", "tokio", "webrtc-util 0.8.1", ] @@ -16992,7 +17024,7 @@ dependencies = [ "log", "nix 0.26.4", "rand 0.8.5", - "thiserror", + "thiserror 1.0.63", "tokio", "winapi", ] @@ -17013,7 +17045,7 @@ dependencies = [ "nix 0.26.4", "portable-atomic", "rand 0.8.5", - "thiserror", + "thiserror 1.0.63", "tokio", "winapi", ] @@ -17154,7 +17186,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -17165,7 +17197,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -17475,7 +17507,7 @@ dependencies = [ "oid-registry 0.6.1", "ring 0.16.20", "rusticata-macros", - "thiserror", + "thiserror 1.0.63", "time", ] @@ -17492,7 +17524,7 @@ dependencies = [ "nom", "oid-registry 0.7.1", "rusticata-macros", - "thiserror", + "thiserror 1.0.63", "time", ] @@ -17630,7 +17662,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -17650,7 +17682,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 544e7d06ee..d4072e4deb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -277,3 +277,8 @@ starknet-crypto = "0.7.1" starknet-types-core = { version = "0.1.7", features = [ "arbitrary", "hash" ] } bitvec = "1.0.1" + +# macro +proc-macro2 = "1.0" +quote = "1.0" +syn = { version = "2.0", default-features = false } diff --git a/crates/katana/core/src/backend/mod.rs b/crates/katana/core/src/backend/mod.rs index 47908816bc..92646de084 100644 --- a/crates/katana/core/src/backend/mod.rs +++ b/crates/katana/core/src/backend/mod.rs @@ -13,7 +13,7 @@ use katana_primitives::state::{compute_state_diff_hash, StateUpdates}; use katana_primitives::transaction::{TxHash, TxWithHash}; use katana_primitives::Felt; use katana_provider::traits::block::{BlockHashProvider, BlockWriter}; -use katana_provider::traits::trie::{ClassTrieWriter, ContractTrieWriter}; +use katana_provider::traits::trie::TrieWriter; use katana_trie::compute_merkle_root; use parking_lot::RwLock; use starknet::macros::short_string; @@ -158,21 +158,15 @@ impl Backend { } #[derive(Debug, Clone)] -pub struct UncommittedBlock<'a, P> -where - P: ClassTrieWriter + ContractTrieWriter, -{ +pub struct UncommittedBlock<'a, P: TrieWriter> { header: PartialHeader, transactions: Vec, receipts: &'a [ReceiptWithTxHash], state_updates: &'a StateUpdates, - trie_provider: P, + provider: P, } -impl<'a, P> UncommittedBlock<'a, P> -where - P: ClassTrieWriter + ContractTrieWriter, -{ +impl<'a, P: TrieWriter> UncommittedBlock<'a, P> { pub fn new( header: PartialHeader, transactions: Vec, @@ -180,7 +174,7 @@ where state_updates: &'a StateUpdates, trie_provider: P, ) -> Self { - Self { header, transactions, receipts, state_updates, trie_provider } + Self { header, transactions, receipts, state_updates, provider: trie_provider } } pub fn commit(self) -> SealedBlock { @@ -258,19 +252,16 @@ where // state_commitment = hPos("STARKNET_STATE_V0", contract_trie_root, class_trie_root) fn compute_new_state_root(&self) -> Felt { - let class_trie_root = ClassTrieWriter::insert_updates( - &self.trie_provider, - self.header.number, - &self.state_updates.declared_classes, - ) - .unwrap(); - - let contract_trie_root = ContractTrieWriter::insert_updates( - &self.trie_provider, - self.header.number, - self.state_updates, - ) - .unwrap(); + println!("ohayo im committing now"); + let class_trie_root = self + .provider + .trie_insert_declared_classes(self.header.number, &self.state_updates.declared_classes) + .expect("failed to update class trie"); + + let contract_trie_root = self + .provider + .trie_insert_contract_updates(self.header.number, self.state_updates) + .expect("failed to update contract trie"); hash::Poseidon::hash_array(&[ short_string!("STARKNET_STATE_V0"), diff --git a/crates/katana/core/src/backend/storage.rs b/crates/katana/core/src/backend/storage.rs index b7d9f095c6..22f0f5efad 100644 --- a/crates/katana/core/src/backend/storage.rs +++ b/crates/katana/core/src/backend/storage.rs @@ -15,13 +15,13 @@ use katana_provider::traits::block::{BlockProvider, BlockWriter}; use katana_provider::traits::contract::{ContractClassWriter, ContractClassWriterExt}; use katana_provider::traits::env::BlockEnvProvider; use katana_provider::traits::stage::StageCheckpointProvider; -use katana_provider::traits::state::{StateFactoryProvider, StateRootProvider, StateWriter}; +use katana_provider::traits::state::{StateFactoryProvider, StateWriter}; use katana_provider::traits::state_update::StateUpdateProvider; use katana_provider::traits::transaction::{ ReceiptProvider, TransactionProvider, TransactionStatusProvider, TransactionTraceProvider, TransactionsProviderExt, }; -use katana_provider::traits::trie::{ClassTrieWriter, ContractTrieWriter}; +use katana_provider::traits::trie::TrieWriter; use katana_provider::BlockchainProvider; use num_traits::ToPrimitive; use starknet::core::types::{BlockStatus, MaybePendingBlockWithTxHashes}; @@ -40,14 +40,12 @@ pub trait Database: + TransactionsProviderExt + ReceiptProvider + StateUpdateProvider - + StateRootProvider + StateWriter + ContractClassWriter + ContractClassWriterExt + StateFactoryProvider + BlockEnvProvider - + ClassTrieWriter - + ContractTrieWriter + + TrieWriter + StageCheckpointProvider + 'static + Send @@ -65,14 +63,12 @@ impl Database for T where + TransactionsProviderExt + ReceiptProvider + StateUpdateProvider - + StateRootProvider + StateWriter + ContractClassWriter + ContractClassWriterExt + StateFactoryProvider + BlockEnvProvider - + ClassTrieWriter - + ContractTrieWriter + + TrieWriter + StageCheckpointProvider + 'static + Send diff --git a/crates/katana/executor/Cargo.toml b/crates/katana/executor/Cargo.toml index 0939be3dea..785d18d3d4 100644 --- a/crates/katana/executor/Cargo.toml +++ b/crates/katana/executor/Cargo.toml @@ -9,6 +9,7 @@ version.workspace = true [dependencies] katana-primitives.workspace = true katana-provider.workspace = true +katana-trie.workspace = true parking_lot = { workspace = true, optional = true } starknet = { workspace = true, optional = true } diff --git a/crates/katana/executor/src/abstraction/mod.rs b/crates/katana/executor/src/abstraction/mod.rs index 53afde647d..78483e8ddd 100644 --- a/crates/katana/executor/src/abstraction/mod.rs +++ b/crates/katana/executor/src/abstraction/mod.rs @@ -11,8 +11,9 @@ use katana_primitives::trace::TxExecInfo; use katana_primitives::transaction::TxWithHash; use katana_primitives::Felt; use katana_provider::traits::contract::ContractClassProvider; -use katana_provider::traits::state::StateProvider; +use katana_provider::traits::state::{StateProofProvider, StateProvider, StateRootProvider}; use katana_provider::ProviderResult; +use katana_trie::MultiProof; pub type ExecutorResult = Result; @@ -204,3 +205,35 @@ impl<'a> StateProvider for StateProviderDb<'a> { self.0.storage(address, storage_key) } } + +impl<'a> StateProofProvider for StateProviderDb<'a> { + fn class_multiproof(&self, classes: Vec) -> ProviderResult { + self.0.class_multiproof(classes) + } + + fn contract_multiproof(&self, addresses: Vec) -> ProviderResult { + self.0.contract_multiproof(addresses) + } + + fn storage_multiproof( + &self, + address: ContractAddress, + key: Vec, + ) -> ProviderResult { + self.0.storage_multiproof(address, key) + } +} + +impl<'a> StateRootProvider for StateProviderDb<'a> { + fn classes_root(&self) -> ProviderResult { + self.0.classes_root() + } + + fn contracts_root(&self) -> ProviderResult { + self.0.contracts_root() + } + + fn state_root(&self) -> ProviderResult { + self.0.state_root() + } +} diff --git a/crates/katana/executor/src/implementation/blockifier/state.rs b/crates/katana/executor/src/implementation/blockifier/state.rs index 37563e7d88..cbda7a187f 100644 --- a/crates/katana/executor/src/implementation/blockifier/state.rs +++ b/crates/katana/executor/src/implementation/blockifier/state.rs @@ -10,7 +10,7 @@ use katana_primitives::class::{self, CompiledClass, ContractClass}; use katana_primitives::Felt; use katana_provider::error::ProviderError; use katana_provider::traits::contract::ContractClassProvider; -use katana_provider::traits::state::StateProvider; +use katana_provider::traits::state::{StateProofProvider, StateProvider, StateRootProvider}; use katana_provider::ProviderResult; use parking_lot::Mutex; @@ -238,6 +238,44 @@ impl StateReader for CachedState { } } +impl StateProofProvider for CachedState { + fn class_multiproof( + &self, + classes: Vec, + ) -> ProviderResult { + let _ = classes; + unimplemented!("not supported in executor's state") + } + + fn contract_multiproof( + &self, + addresses: Vec, + ) -> ProviderResult { + let _ = addresses; + unimplemented!("not supported in executor's state") + } + + fn storage_multiproof( + &self, + address: katana_primitives::ContractAddress, + key: Vec, + ) -> ProviderResult { + let _ = address; + let _ = key; + unimplemented!("not supported in executor's state") + } +} + +impl StateRootProvider for CachedState { + fn classes_root(&self) -> ProviderResult { + unimplemented!("not supported in executor's state") + } + + fn contracts_root(&self) -> ProviderResult { + unimplemented!("not supported in executor's state") + } +} + #[cfg(test)] mod tests { diff --git a/crates/katana/executor/src/implementation/noop.rs b/crates/katana/executor/src/implementation/noop.rs index 31a66baf54..09643823dc 100644 --- a/crates/katana/executor/src/implementation/noop.rs +++ b/crates/katana/executor/src/implementation/noop.rs @@ -6,7 +6,7 @@ use katana_primitives::fee::TxFeeInfo; use katana_primitives::transaction::{ExecutableTxWithHash, TxWithHash}; use katana_primitives::Felt; use katana_provider::traits::contract::ContractClassProvider; -use katana_provider::traits::state::StateProvider; +use katana_provider::traits::state::{StateProofProvider, StateProvider, StateRootProvider}; use katana_provider::ProviderResult; use crate::abstraction::{ @@ -170,3 +170,38 @@ impl StateProvider for NoopStateProvider { Ok(None) } } + +impl StateProofProvider for NoopStateProvider { + fn class_multiproof(&self, classes: Vec) -> ProviderResult { + let _ = classes; + Ok(katana_trie::MultiProof(Default::default())) + } + + fn contract_multiproof( + &self, + addresses: Vec, + ) -> ProviderResult { + let _ = addresses; + Ok(katana_trie::MultiProof(Default::default())) + } + + fn storage_multiproof( + &self, + address: ContractAddress, + key: Vec, + ) -> ProviderResult { + let _ = address; + let _ = key; + Ok(katana_trie::MultiProof(Default::default())) + } +} + +impl StateRootProvider for NoopStateProvider { + fn classes_root(&self) -> ProviderResult { + Ok(Felt::ZERO) + } + + fn contracts_root(&self) -> ProviderResult { + Ok(Felt::ZERO) + } +} diff --git a/crates/katana/primitives/src/lib.rs b/crates/katana/primitives/src/lib.rs index be6b106c39..23fddf3707 100644 --- a/crates/katana/primitives/src/lib.rs +++ b/crates/katana/primitives/src/lib.rs @@ -24,3 +24,4 @@ pub mod utils; pub use contract::ContractAddress; pub use starknet::macros::felt; pub use starknet_types_core::felt::{Felt, FromStrError}; +pub use starknet_types_core::hash; diff --git a/crates/katana/rpc/rpc-api/src/starknet.rs b/crates/katana/rpc/rpc-api/src/starknet.rs index bf2b10e410..42a25e8581 100644 --- a/crates/katana/rpc/rpc-api/src/starknet.rs +++ b/crates/katana/rpc/rpc-api/src/starknet.rs @@ -3,8 +3,9 @@ use jsonrpsee::core::RpcResult; use jsonrpsee::proc_macros::rpc; use katana_primitives::block::{BlockIdOrTag, BlockNumber}; +use katana_primitives::class::ClassHash; use katana_primitives::transaction::TxHash; -use katana_primitives::Felt; +use katana_primitives::{ContractAddress, Felt}; use katana_rpc_types::block::{ BlockHashAndNumber, BlockTxCount, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, @@ -18,6 +19,7 @@ use katana_rpc_types::transaction::{ BroadcastedDeclareTx, BroadcastedDeployAccountTx, BroadcastedInvokeTx, BroadcastedTx, DeclareTxResult, DeployAccountTxResult, InvokeTxResult, Tx, }; +use katana_rpc_types::trie::{ContractStorageKeys, GetStorageProofResponse}; use katana_rpc_types::{ FeeEstimate, FeltAsHex, FunctionCall, SimulationFlag, SimulationFlagForEstimateFee, SyncingStatus, @@ -183,6 +185,18 @@ pub trait StarknetApi { block_id: BlockIdOrTag, contract_address: Felt, ) -> RpcResult; + + /// Get merkle paths in one of the state tries: global state, classes, individual contract. A + /// single request can query for any mix of the three types of storage proofs (classes, + /// contracts, and storage). + #[method(name = "getStorageProof")] + async fn get_storage_proof( + &self, + block_id: BlockIdOrTag, + class_hashes: Option>, + contract_addresses: Option>, + contracts_storage_keys: Option>, + ) -> RpcResult; } /// Write API. diff --git a/crates/katana/rpc/rpc-types-builder/src/state_update.rs b/crates/katana/rpc/rpc-types-builder/src/state_update.rs index 8d898485d0..ba9fa920fb 100644 --- a/crates/katana/rpc/rpc-types-builder/src/state_update.rs +++ b/crates/katana/rpc/rpc-types-builder/src/state_update.rs @@ -1,7 +1,7 @@ use katana_primitives::block::BlockHashOrNumber; use katana_primitives::Felt; use katana_provider::traits::block::{BlockHashProvider, BlockNumberProvider}; -use katana_provider::traits::state::StateRootProvider; +use katana_provider::traits::state::{StateFactoryProvider, StateRootProvider}; use katana_provider::traits::state_update::StateUpdateProvider; use katana_provider::ProviderResult; use katana_rpc_types::state_update::{StateDiff, StateUpdate}; @@ -21,7 +21,7 @@ impl

StateUpdateBuilder

{ impl

StateUpdateBuilder

where - P: BlockHashProvider + BlockNumberProvider + StateRootProvider + StateUpdateProvider, + P: BlockHashProvider + BlockNumberProvider + StateFactoryProvider + StateUpdateProvider, { /// Builds a state update for the given block. pub fn build(self) -> ProviderResult> { @@ -30,16 +30,23 @@ where return Ok(None); }; - let new_root = StateRootProvider::state_root(&self.provider, self.block_id)? - .expect("should exist if block exists"); + let new_root = self + .provider + .historical(self.block_id)? + .expect("should exist if block exists") + .state_root()?; + let old_root = { let block_num = BlockNumberProvider::block_number_by_hash(&self.provider, block_hash)? .expect("should exist if block exists"); match block_num { 0 => Felt::ZERO, - _ => StateRootProvider::state_root(&self.provider, (block_num - 1).into())? - .expect("should exist if not genesis"), + _ => self + .provider + .historical((block_num - 1).into())? + .expect("should exist if block exists") + .state_root()?, } }; diff --git a/crates/katana/rpc/rpc-types/Cargo.toml b/crates/katana/rpc/rpc-types/Cargo.toml index 7df238583b..8cdfe76dc3 100644 --- a/crates/katana/rpc/rpc-types/Cargo.toml +++ b/crates/katana/rpc/rpc-types/Cargo.toml @@ -13,6 +13,7 @@ katana-executor.workspace = true katana-pool.workspace = true katana-primitives.workspace = true katana-provider.workspace = true +katana-trie.workspace = true anyhow.workspace = true derive_more.workspace = true diff --git a/crates/katana/rpc/rpc-types/src/lib.rs b/crates/katana/rpc/rpc-types/src/lib.rs index d67db902a4..3ee07c1a19 100644 --- a/crates/katana/rpc/rpc-types/src/lib.rs +++ b/crates/katana/rpc/rpc-types/src/lib.rs @@ -13,6 +13,7 @@ pub mod receipt; pub mod state_update; pub mod trace; pub mod transaction; +pub mod trie; mod utils; use std::ops::Deref; diff --git a/crates/katana/rpc/rpc-types/src/trie.rs b/crates/katana/rpc/rpc-types/src/trie.rs new file mode 100644 index 0000000000..993534537a --- /dev/null +++ b/crates/katana/rpc/rpc-types/src/trie.rs @@ -0,0 +1,193 @@ +use std::collections::HashMap; + +use katana_primitives::contract::StorageKey; +use katana_primitives::{ContractAddress, Felt}; +use katana_trie::bonsai::BitSlice; +use katana_trie::{MultiProof, Path, ProofNode}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct ContractStorageKeys { + #[serde(rename = "contract_address")] + pub address: ContractAddress, + #[serde(rename = "storage_keys")] + pub keys: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct GlobalRoots { + /// The associated block hash (needed in case the caller used a block tag for the block_id + /// parameter). + pub block_hash: Felt, + pub classes_tree_root: Felt, + pub contracts_tree_root: Felt, +} + +/// Node in the Merkle-Patricia trie. +#[derive(Debug, Serialize, Deserialize)] +pub enum MerkleNode { + /// Represents a path to the highest non-zero descendant node. + Edge { + /// An integer whose binary representation represents the path from the current node to its + /// highest non-zero descendant (bounded by 2^251) + path: Felt, + /// The length of the path (bounded by 251). + length: u8, + /// The hash of the unique non-zero maximal-height descendant node. + child: Felt, + }, + + /// An internal node whose both children are non-zero. + Binary { + /// The hash of the left child. + left: Felt, + /// The hash of the right child. + right: Felt, + }, +} + +/// The response type for `starknet_getStorageProof` method. +/// +/// The requested storage proofs. Note that if a requested leaf has the default value, the path to +/// it may end in an edge node whose path is not a prefix of the requested leaf, thus effectively +/// proving non-membership +#[derive(Debug, Serialize, Deserialize)] +pub struct GetStorageProofResponse { + pub global_roots: GlobalRoots, + pub classes_proof: ClassesProof, + pub contracts_proof: ContractsProof, + pub contracts_storage_proofs: ContractStorageProofs, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct ClassesProof { + pub nodes: Nodes, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct ContractsProof { + /// The nodes in the union of the paths from the contracts tree root to the requested leaves. + pub nodes: Nodes, + /// The nonce and class hash for each requested contract address, in the order in which they + /// appear in the request. These values are needed to construct the associated leaf node. + pub contract_leaves_data: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ContractLeafData { + pub nonce: Felt, + pub class_hash: Felt, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct ContractStorageProofs { + pub nodes: Vec, +} + +#[derive(Debug, Default)] +pub struct Nodes(pub HashMap); + +impl Serialize for Nodes { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + use serde::ser::SerializeSeq; + + #[derive(Debug, Serialize)] + struct NodeEntry<'a> { + node_hash: &'a Felt, + node: &'a MerkleNode, + } + + let mut seq = serializer.serialize_seq(Some(self.0.len()))?; + for (node_hash, node) in &self.0 { + seq.serialize_element(&NodeEntry { node_hash, node })?; + } + seq.end() + } +} + +impl<'de> Deserialize<'de> for Nodes { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Debug, Deserialize)] + struct NodeEntry { + node_hash: Felt, + node: MerkleNode, + } + + let entries: Vec = Vec::deserialize(deserializer)?; + let map = entries.into_iter().map(|entry| (entry.node_hash, entry.node)).collect(); + Ok(Nodes(map)) + } +} + +// --- Conversion from/to internal types for convenience + +impl From for Nodes { + fn from(value: MultiProof) -> Self { + Self(value.0.into_iter().map(|(hash, node)| (hash, MerkleNode::from(node))).collect()) + } +} + +impl From for MultiProof { + fn from(value: Nodes) -> Self { + Self(value.0.into_iter().map(|(hash, node)| (hash, ProofNode::from(node))).collect()) + } +} + +impl From for MerkleNode { + fn from(value: ProofNode) -> Self { + match value { + ProofNode::Binary { left, right } => MerkleNode::Binary { left, right }, + ProofNode::Edge { child, path } => { + MerkleNode::Edge { child, length: path.len() as u8, path: path_to_felt(path) } + } + } + } +} + +impl From for ProofNode { + fn from(value: MerkleNode) -> Self { + match value { + MerkleNode::Binary { left, right } => Self::Binary { left, right }, + MerkleNode::Edge { path, child, .. } => Self::Edge { child, path: felt_to_path(path) }, + } + } +} + +fn felt_to_path(felt: Felt) -> Path { + Path(BitSlice::from_slice(&felt.to_bytes_be())[5..].to_bitvec()) +} + +fn path_to_felt(path: Path) -> Felt { + let mut arr = [0u8; 32]; + let slice = &mut BitSlice::from_slice_mut(&mut arr)[5..]; + slice[..path.len()].copy_from_bitslice(&path); + Felt::from_bytes_be(&arr) +} + +#[cfg(test)] +mod tests { + use katana_primitives::felt; + + use super::*; + + // This test is assuming that the `path` field in `MerkleNode::Edge` is already a valid trie + // path value. + #[rstest::rstest] + #[case(felt!("0x1234567890abcdef"))] + #[case(felt!("0xdeadbeef"))] + #[case(Felt::MAX)] + #[case(Felt::ZERO)] + fn test_path_felt_roundtrip(#[case] path_in_felt: Felt) { + let initial_path = felt_to_path(path_in_felt); + + let converted_felt = path_to_felt(initial_path.clone()); + let path = felt_to_path(converted_felt); + assert_eq!(initial_path, path); + } +} diff --git a/crates/katana/rpc/rpc/Cargo.toml b/crates/katana/rpc/rpc/Cargo.toml index 0c09844955..3910bbd2c9 100644 --- a/crates/katana/rpc/rpc/Cargo.toml +++ b/crates/katana/rpc/rpc/Cargo.toml @@ -43,6 +43,7 @@ jsonrpsee = { workspace = true, features = [ "client" ] } katana-cairo.workspace = true katana-node.workspace = true katana-rpc-api = { workspace = true, features = [ "client" ] } +katana-trie.workspace = true num-traits.workspace = true rand.workspace = true rstest.workspace = true diff --git a/crates/katana/rpc/rpc/src/starknet/mod.rs b/crates/katana/rpc/rpc/src/starknet/mod.rs index c0d4256987..ee4945a596 100644 --- a/crates/katana/rpc/rpc/src/starknet/mod.rs +++ b/crates/katana/rpc/rpc/src/starknet/mod.rs @@ -20,7 +20,7 @@ use katana_primitives::Felt; use katana_provider::traits::block::{BlockHashProvider, BlockIdReader, BlockNumberProvider}; use katana_provider::traits::contract::ContractClassProvider; use katana_provider::traits::env::BlockEnvProvider; -use katana_provider::traits::state::{StateFactoryProvider, StateProvider}; +use katana_provider::traits::state::{StateFactoryProvider, StateProvider, StateRootProvider}; use katana_provider::traits::transaction::{ ReceiptProvider, TransactionProvider, TransactionStatusProvider, }; @@ -34,6 +34,10 @@ use katana_rpc_types::event::{EventFilterWithPage, EventsPage}; use katana_rpc_types::receipt::{ReceiptBlock, TxReceiptWithBlockInfo}; use katana_rpc_types::state_update::MaybePendingStateUpdate; use katana_rpc_types::transaction::Tx; +use katana_rpc_types::trie::{ + ClassesProof, ContractLeafData, ContractStorageKeys, ContractStorageProofs, ContractsProof, + GetStorageProofResponse, GlobalRoots, Nodes, +}; use katana_rpc_types::FeeEstimate; use katana_rpc_types_builder::ReceiptBuilder; use katana_tasks::{BlockingTaskPool, TokioTaskSpawner}; @@ -1124,6 +1128,75 @@ where Ok(id) } + + async fn get_proofs( + &self, + block_id: BlockIdOrTag, + class_hashes: Option>, + contract_addresses: Option>, + contracts_storage_keys: Option>, + ) -> StarknetApiResult { + self.on_io_blocking_task(move |this| { + let provider = this.inner.backend.blockchain.provider(); + + let state = this.state(&block_id)?; + let block_hash = provider.latest_hash()?; + + // --- Get classes proof (if any) + + let classes_proof = if let Some(classes) = class_hashes { + let proofs = state.class_multiproof(classes)?; + ClassesProof { nodes: proofs.into() } + } else { + ClassesProof::default() + }; + + // --- Get contracts proof (if any) + + let contracts_proof = if let Some(addresses) = contract_addresses { + let proofs = state.contract_multiproof(addresses.clone())?; + let mut contract_leaves_data = Vec::new(); + + for address in addresses { + let nonce = state.nonce(address)?.unwrap_or_default(); + let class_hash = state.class_hash_of_contract(address)?.unwrap_or_default(); + contract_leaves_data.push(ContractLeafData { class_hash, nonce }); + } + + ContractsProof { nodes: proofs.into(), contract_leaves_data } + } else { + ContractsProof::default() + }; + + // --- Get contracts storage proof (if any) + + let contracts_storage_proofs = if let Some(contract_storage) = contracts_storage_keys { + let mut nodes: Vec = Vec::new(); + + for ContractStorageKeys { address, keys } in contract_storage { + let proofs = state.storage_multiproof(address, keys)?; + nodes.push(proofs.into()); + } + + ContractStorageProofs { nodes } + } else { + ContractStorageProofs::default() + }; + + let classes_tree_root = state.classes_root()?; + let contracts_tree_root = state.contracts_root()?; + + let global_roots = GlobalRoots { block_hash, classes_tree_root, contracts_tree_root }; + + Ok(GetStorageProofResponse { + global_roots, + classes_proof, + contracts_proof, + contracts_storage_proofs, + }) + }) + .await + } } impl Clone for StarknetApi diff --git a/crates/katana/rpc/rpc/src/starknet/read.rs b/crates/katana/rpc/rpc/src/starknet/read.rs index 89322967ba..a48cfe5f5b 100644 --- a/crates/katana/rpc/rpc/src/starknet/read.rs +++ b/crates/katana/rpc/rpc/src/starknet/read.rs @@ -1,8 +1,9 @@ use jsonrpsee::core::{async_trait, Error, RpcResult}; use katana_executor::{EntryPointCall, ExecutorFactory}; use katana_primitives::block::BlockIdOrTag; +use katana_primitives::class::ClassHash; use katana_primitives::transaction::{ExecutableTx, ExecutableTxWithHash, TxHash}; -use katana_primitives::Felt; +use katana_primitives::{ContractAddress, Felt}; use katana_rpc_api::starknet::StarknetApiServer; use katana_rpc_types::block::{ BlockHashAndNumber, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes, @@ -15,6 +16,7 @@ use katana_rpc_types::message::MsgFromL1; use katana_rpc_types::receipt::TxReceiptWithBlockInfo; use katana_rpc_types::state_update::MaybePendingStateUpdate; use katana_rpc_types::transaction::{BroadcastedTx, Tx}; +use katana_rpc_types::trie::{ContractStorageKeys, GetStorageProofResponse}; use katana_rpc_types::{FeeEstimate, FeltAsHex, FunctionCall, SimulationFlagForEstimateFee}; use starknet::core::types::TransactionStatus; @@ -265,4 +267,17 @@ impl StarknetApiServer for StarknetApi { ) -> RpcResult { Ok(self.transaction_status(transaction_hash).await?) } + + async fn get_storage_proof( + &self, + block_id: BlockIdOrTag, + class_hashes: Option>, + contract_addresses: Option>, + contracts_storage_keys: Option>, + ) -> RpcResult { + let proofs = self + .get_proofs(block_id, class_hashes, contract_addresses, contracts_storage_keys) + .await?; + Ok(proofs) + } } diff --git a/crates/katana/rpc/rpc/tests/proofs.rs b/crates/katana/rpc/rpc/tests/proofs.rs new file mode 100644 index 0000000000..b7c24592b2 --- /dev/null +++ b/crates/katana/rpc/rpc/tests/proofs.rs @@ -0,0 +1,64 @@ +use std::path::PathBuf; + +use dojo_test_utils::sequencer::{get_default_test_config, TestSequencer}; +use jsonrpsee::http_client::HttpClientBuilder; +use katana_node::config::SequencingConfig; +use katana_primitives::block::BlockIdOrTag; +use katana_primitives::hash; +use katana_primitives::hash::StarkHash; +use katana_rpc_api::starknet::StarknetApiClient; +use katana_rpc_types::trie::GetStorageProofResponse; +use katana_trie::bitvec::view::AsBits; +use katana_trie::bonsai::BitVec; +use katana_trie::MultiProof; +use starknet::accounts::Account; +use starknet::core::types::BlockTag; +use starknet::macros::short_string; + +mod common; + +#[tokio::test] +async fn classes_proofs() { + let sequencer = + TestSequencer::start(get_default_test_config(SequencingConfig::default())).await; + + let provider = sequencer.provider(); + let account = sequencer.account(); + + let path: PathBuf = PathBuf::from("tests/test_data/cairo1_contract.json"); + let (contract, compiled_class_hash) = common::prepare_contract_declaration_params(&path) + .expect("failed to prepare class declaration params"); + + let class_hash = contract.class_hash(); + let res = account + .declare_v2(contract.into(), compiled_class_hash) + .send() + .await + .expect("failed to send declare tx"); + + dojo_utils::TransactionWaiter::new(res.transaction_hash, &provider) + .await + .expect("failed to wait on tx"); + + // We need to use the jsonrpsee client because `starknet-rs` doesn't yet support RPC 0.8.0 + let client = HttpClientBuilder::default().build(sequencer.url()).unwrap(); + + let GetStorageProofResponse { global_roots, classes_proof, .. } = client + .get_storage_proof(BlockIdOrTag::Tag(BlockTag::Latest), Some(vec![class_hash]), None, None) + .await + .expect("failed to get storage proof"); + + let key: BitVec = class_hash.to_bytes_be().as_bits()[5..].to_owned(); + let value = + hash::Poseidon::hash(&short_string!("CONTRACT_CLASS_LEAF_V0"), &compiled_class_hash); + + let classes_proof = MultiProof::from(classes_proof.nodes); + + // the returned data is the list of values corresponds to the [key] + let results = classes_proof + .verify_proof::(global_roots.classes_tree_root, [key], 251) + .collect::, _>>() + .expect("failed to verify proofs"); + + assert_eq!(vec![value], results); +} diff --git a/crates/katana/runner/macro/Cargo.toml b/crates/katana/runner/macro/Cargo.toml index a8e2689be0..7c270bd298 100644 --- a/crates/katana/runner/macro/Cargo.toml +++ b/crates/katana/runner/macro/Cargo.toml @@ -8,6 +8,6 @@ version.workspace = true proc-macro = true [dependencies] -proc-macro2 = "1.0.86" -quote = "1.0" -syn = { version = "2.0", features = [ "fold", "full" ] } +proc-macro2.workspace = true +quote.workspace = true +syn = { workspace = true, features = [ "fold", "full" ] } diff --git a/crates/katana/storage/codecs/derive/Cargo.toml b/crates/katana/storage/codecs/derive/Cargo.toml index 986d362e50..f4e0cc5248 100644 --- a/crates/katana/storage/codecs/derive/Cargo.toml +++ b/crates/katana/storage/codecs/derive/Cargo.toml @@ -9,10 +9,10 @@ version.workspace = true proc-macro = true [dependencies] -proc-macro2 = "1.0.70" -quote = "1.0.33" +proc-macro2.workspace = true +quote.workspace = true serde.workspace = true -syn = { version = "2.0.41", features = [ "extra-traits", "full" ] } +syn = { workspace = true, features = [ "extra-traits", "full" ] } [package.metadata.cargo-udeps.ignore] normal = [ "serde" ] diff --git a/crates/katana/storage/db/Cargo.toml b/crates/katana/storage/db/Cargo.toml index b92f75b51a..8385b2dffe 100644 --- a/crates/katana/storage/db/Cargo.toml +++ b/crates/katana/storage/db/Cargo.toml @@ -18,14 +18,11 @@ parking_lot.workspace = true roaring = { version = "0.10.3", features = [ "serde" ] } serde.workspace = true serde_json.workspace = true -starknet.workspace = true -starknet-types-core.workspace = true tempfile.workspace = true thiserror.workspace = true tracing.workspace = true # codecs -bitvec.workspace = true postcard = { workspace = true, optional = true } smallvec = "1.13.2" @@ -37,6 +34,7 @@ rev = "b34b0d3" [dev-dependencies] arbitrary.workspace = true criterion.workspace = true +starknet.workspace = true [features] default = [ "postcard" ] diff --git a/crates/katana/storage/db/src/abstraction/transaction.rs b/crates/katana/storage/db/src/abstraction/transaction.rs index 9f62a7a572..0280e65c07 100644 --- a/crates/katana/storage/db/src/abstraction/transaction.rs +++ b/crates/katana/storage/db/src/abstraction/transaction.rs @@ -66,3 +66,115 @@ pub trait DbTxMut: DbTx { /// Clears all entries in the given database. This will empty the database. fn clear(&self) -> Result<(), DatabaseError>; } + +// --- Reference variations + +pub trait DbTxRef<'a>: Clone { + /// The cursor type. + type Cursor: DbCursor; + + /// The cursor type for dupsort table. + // TODO: ideally we should only define the cursor type once, + // find a way to not have to define both cursor types in both traits + type DupCursor: DbDupSortCursor; + + /// Creates a cursor to iterate over a table items. + fn cursor(&self) -> Result, DatabaseError>; + + /// Creates a cursor to iterate over a dupsort table items. + fn cursor_dup(&self) -> Result, DatabaseError>; + + /// Gets a value from a table using the given key. + fn get(&self, key: T::Key) -> Result, DatabaseError>; + + /// Returns number of entries in the table. + fn entries(&self) -> Result; +} + +pub trait DbTxMutRef<'a>: DbTxRef<'a> { + /// The mutable cursor type. + type Cursor: DbCursorMut; + + /// The mutable cursor type for dupsort table. + // TODO: find a way to not have to define both cursor types in both traits + type DupCursor: DbDupSortCursorMut; + + /// Creates a cursor to mutably iterate over a table items. + fn cursor_mut(&self) -> Result<>::Cursor, DatabaseError>; + + /// Creates a cursor to iterate over a dupsort table items. + fn cursor_dup_mut( + &self, + ) -> Result<>::DupCursor, DatabaseError>; + + /// Inserts an item into a database. + /// + /// This function stores key/data pairs in the database. The default behavior is to enter the + /// new key/data pair, replacing any previously existing key if duplicates are disallowed, or + /// adding a duplicate data item if duplicates are allowed (DatabaseFlags::DUP_SORT). + fn put(&self, key: T::Key, value: T::Value) -> Result<(), DatabaseError>; + + /// Delete items from a database, removing the key/data pair if it exists. + /// + /// If the data parameter is [Some] only the matching data item will be deleted. Otherwise, if + /// data parameter is [None], any/all value(s) for specified key will be deleted. + /// + /// Returns `true` if the key/value pair was present. + fn delete(&self, key: T::Key, value: Option) + -> Result; + + /// Clears all entries in the given database. This will empty the database. + fn clear(&self) -> Result<(), DatabaseError>; +} + +impl<'a, Tx: DbTx> DbTxRef<'a> for &'a Tx { + type Cursor = ::Cursor; + type DupCursor = ::DupCursor; + + fn cursor(&self) -> Result, DatabaseError> { + ::cursor::(self) + } + + fn cursor_dup(&self) -> Result, DatabaseError> { + ::cursor_dup::(self) + } + + fn entries(&self) -> Result { + ::entries::(self) + } + + fn get(&self, key: T::Key) -> Result, DatabaseError> { + ::get::(self, key) + } +} + +impl<'a, Tx: DbTxMut> DbTxMutRef<'a> for &'a Tx { + type Cursor = ::Cursor; + type DupCursor = ::DupCursor; + + fn cursor_mut(&self) -> Result<>::Cursor, DatabaseError> { + ::cursor_mut::(self) + } + + fn cursor_dup_mut( + &self, + ) -> Result<>::DupCursor, DatabaseError> { + ::cursor_dup_mut::(self) + } + + fn put(&self, key: T::Key, value: T::Value) -> Result<(), DatabaseError> { + ::put::(self, key, value) + } + + fn delete( + &self, + key: T::Key, + value: Option, + ) -> Result { + ::delete::(self, key, value) + } + + fn clear(&self) -> Result<(), DatabaseError> { + ::clear::(self) + } +} diff --git a/crates/katana/storage/db/src/mdbx/tx.rs b/crates/katana/storage/db/src/mdbx/tx.rs index da902c9f5d..a1d6529045 100644 --- a/crates/katana/storage/db/src/mdbx/tx.rs +++ b/crates/katana/storage/db/src/mdbx/tx.rs @@ -33,7 +33,7 @@ pub struct Tx { impl Tx { /// Creates new `Tx` object with a `RO` or `RW` transaction. pub fn new(inner: libmdbx::Transaction) -> Self { - Self { inner, db_handles: Default::default() } + Self { inner, db_handles: RwLock::new([None; NUM_TABLES]) } } pub fn get_dbi(&self) -> Result { diff --git a/crates/katana/storage/db/src/models/trie.rs b/crates/katana/storage/db/src/models/trie.rs index b10456af57..3e3628919c 100644 --- a/crates/katana/storage/db/src/models/trie.rs +++ b/crates/katana/storage/db/src/models/trie.rs @@ -1,18 +1,48 @@ use katana_trie::bonsai::ByteVec; use serde::{Deserialize, Serialize}; -use crate::codecs::{Decode, Encode}; +use crate::codecs::{Compress, Decode, Decompress, Encode}; use crate::error::CodecError; +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct TrieHistoryEntry { + pub key: TrieDatabaseKey, + pub value: TrieDatabaseValue, +} + +impl Compress for TrieHistoryEntry { + type Compressed = Vec; + + fn compress(self) -> Self::Compressed { + let mut buf = Vec::new(); + buf.extend(self.key.encode()); + buf.extend(self.value.compress()); + buf + } +} + +impl Decompress for TrieHistoryEntry { + fn decompress>(bytes: B) -> Result { + let bytes = bytes.as_ref(); + + let key = TrieDatabaseKey::decode(bytes)?; + // first byte is the key type, second byte is the actual key length + let key_bytes_length = 1 + 1 + key.key.len(); + let value = TrieDatabaseValue::decompress(&bytes[key_bytes_length..])?; + + Ok(Self { key, value }) + } +} + #[repr(u8)] -#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)] pub enum TrieDatabaseKeyType { Trie = 0, Flat, TrieLog, } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct TrieDatabaseKey { pub r#type: TrieDatabaseKeyType, pub key: Vec, @@ -26,6 +56,7 @@ impl Encode for TrieDatabaseKey { fn encode(self) -> Self::Encoded { let mut encoded = Vec::new(); encoded.push(self.r#type as u8); + encoded.push(self.key.len() as u8); // Encode key length encoded.extend(self.key); encoded } @@ -34,7 +65,9 @@ impl Encode for TrieDatabaseKey { impl Decode for TrieDatabaseKey { fn decode>(bytes: B) -> Result { let bytes = bytes.as_ref(); - if bytes.is_empty() { + + if bytes.len() < 2 { + // Need at least type and length bytes panic!("emptyy buffer") } @@ -45,7 +78,13 @@ impl Decode for TrieDatabaseKey { _ => panic!("Invalid trie database key type"), }; - let key = bytes[1..].to_vec(); + let key_len = bytes[1] as usize; + + if bytes.len() < 2 + key_len { + panic!("Buffer too short for key length"); + } + + let key = bytes[2..2 + key_len].to_vec(); Ok(TrieDatabaseKey { r#type, key }) } diff --git a/crates/katana/storage/db/src/tables.rs b/crates/katana/storage/db/src/tables.rs index e4223d38cf..c3ca7c5f44 100644 --- a/crates/katana/storage/db/src/tables.rs +++ b/crates/katana/storage/db/src/tables.rs @@ -11,7 +11,7 @@ use crate::models::contract::{ContractClassChange, ContractInfoChangeList, Contr use crate::models::list::BlockList; use crate::models::stage::{StageCheckpoint, StageId}; use crate::models::storage::{ContractStorageEntry, ContractStorageKey, StorageEntry}; -use crate::models::trie::{TrieDatabaseKey, TrieDatabaseValue}; +use crate::models::trie::{TrieDatabaseKey, TrieDatabaseValue, TrieHistoryEntry}; pub trait Key: Encode + Decode + Clone + std::fmt::Debug {} pub trait Value: Compress + Decompress + std::fmt::Debug {} @@ -20,7 +20,7 @@ impl Key for T where T: Encode + Decode + Clone + std::fmt::Debug {} impl Value for T where T: Compress + Decompress + std::fmt::Debug {} /// An asbtraction for a table. -pub trait Table { +pub trait Table: 'static { /// The name of the table. const NAME: &'static str; /// The key type of the table. @@ -37,7 +37,12 @@ pub trait DupSort: Table { type SubKey: Key; } -pub trait Trie: Table {} +pub trait Trie: Table { + /// Table for storing the trie entries according to the block its was committed. + type History: DupSort; + /// Table for storing the trie change set. + type Changeset: Table; +} /// Enum for the types of tables present in libmdbx. #[derive(Debug, PartialEq, Copy, Clone)] @@ -48,7 +53,7 @@ pub enum TableType { DupSort, } -pub const NUM_TABLES: usize = 27; +pub const NUM_TABLES: usize = 33; /// Macro to declare `libmdbx` tables. #[macro_export] @@ -172,10 +177,16 @@ define_tables_enum! {[ (ClassChangeHistory, TableType::DupSort), (StorageChangeHistory, TableType::DupSort), (StorageChangeSet, TableType::Table), - (ClassTrie, TableType::Table), - (ContractTrie, TableType::Table), - (ContractStorageTrie, TableType::Table), - (StageCheckpoints, TableType::Table) + (StageCheckpoints, TableType::Table), + (ClassesTrie, TableType::Table), + (ContractsTrie, TableType::Table), + (StoragesTrie, TableType::Table), + (ClassesTrieHistory, TableType::DupSort), + (ContractsTrieHistory, TableType::DupSort), + (StoragesTrieHistory, TableType::DupSort), + (ClassesTrieChangeSet, TableType::Table), + (ContractsTrieChangeSet, TableType::Table), + (StoragesTrieChangeSet, TableType::Table) ]} tables! { @@ -236,16 +247,41 @@ tables! { StorageChangeHistory: (BlockNumber, ContractStorageKey) => ContractStorageEntry, /// Class trie - ClassTrie: (TrieDatabaseKey) => TrieDatabaseValue, + ClassesTrie: (TrieDatabaseKey) => TrieDatabaseValue, /// Contract trie - ContractTrie: (TrieDatabaseKey) => TrieDatabaseValue, + ContractsTrie: (TrieDatabaseKey) => TrieDatabaseValue, /// Contract storage trie - ContractStorageTrie: (TrieDatabaseKey) => TrieDatabaseValue + StoragesTrie: (TrieDatabaseKey) => TrieDatabaseValue, + + /// Class trie history + ClassesTrieHistory: (BlockNumber, TrieDatabaseKey) => TrieHistoryEntry, + /// Contract trie history + ContractsTrieHistory: (BlockNumber, TrieDatabaseKey) => TrieHistoryEntry, + /// Contract storage trie history + StoragesTrieHistory: (BlockNumber, TrieDatabaseKey) => TrieHistoryEntry, + + /// Class trie change set + ClassesTrieChangeSet: (TrieDatabaseKey) => BlockList, + /// contract trie change set + ContractsTrieChangeSet: (TrieDatabaseKey) => BlockList, + /// contract storage trie change set + StoragesTrieChangeSet: (TrieDatabaseKey) => BlockList +} + +impl Trie for ClassesTrie { + type History = ClassesTrieHistory; + type Changeset = ClassesTrieChangeSet; } -impl Trie for ClassTrie {} -impl Trie for ContractTrie {} -impl Trie for ContractStorageTrie {} +impl Trie for ContractsTrie { + type History = ContractsTrieHistory; + type Changeset = ContractsTrieChangeSet; +} + +impl Trie for StoragesTrie { + type History = StoragesTrieHistory; + type Changeset = StoragesTrieChangeSet; +} #[cfg(test)] mod tests { @@ -278,10 +314,16 @@ mod tests { assert_eq!(Tables::ALL[20].name(), ClassChangeHistory::NAME); assert_eq!(Tables::ALL[21].name(), StorageChangeHistory::NAME); assert_eq!(Tables::ALL[22].name(), StorageChangeSet::NAME); - assert_eq!(Tables::ALL[23].name(), ClassTrie::NAME); - assert_eq!(Tables::ALL[24].name(), ContractTrie::NAME); - assert_eq!(Tables::ALL[25].name(), ContractStorageTrie::NAME); - assert_eq!(Tables::ALL[26].name(), StageCheckpoints::NAME); + assert_eq!(Tables::ALL[23].name(), StageCheckpoints::NAME); + assert_eq!(Tables::ALL[24].name(), ClassesTrie::NAME); + assert_eq!(Tables::ALL[25].name(), ContractsTrie::NAME); + assert_eq!(Tables::ALL[26].name(), StoragesTrie::NAME); + assert_eq!(Tables::ALL[27].name(), ClassesTrieHistory::NAME); + assert_eq!(Tables::ALL[28].name(), ContractsTrieHistory::NAME); + assert_eq!(Tables::ALL[29].name(), StoragesTrieHistory::NAME); + assert_eq!(Tables::ALL[30].name(), ClassesTrieChangeSet::NAME); + assert_eq!(Tables::ALL[31].name(), ContractsTrieChangeSet::NAME); + assert_eq!(Tables::ALL[32].name(), StoragesTrieChangeSet::NAME); assert_eq!(Tables::Headers.table_type(), TableType::Table); assert_eq!(Tables::BlockHashes.table_type(), TableType::Table); @@ -306,10 +348,16 @@ mod tests { assert_eq!(Tables::ClassChangeHistory.table_type(), TableType::DupSort); assert_eq!(Tables::StorageChangeHistory.table_type(), TableType::DupSort); assert_eq!(Tables::StorageChangeSet.table_type(), TableType::Table); - assert_eq!(Tables::ClassTrie.table_type(), TableType::Table); - assert_eq!(Tables::ContractTrie.table_type(), TableType::Table); - assert_eq!(Tables::ContractStorageTrie.table_type(), TableType::Table); assert_eq!(Tables::StageCheckpoints.table_type(), TableType::Table); + assert_eq!(Tables::ClassesTrie.table_type(), TableType::Table); + assert_eq!(Tables::ContractsTrie.table_type(), TableType::Table); + assert_eq!(Tables::StoragesTrie.table_type(), TableType::Table); + assert_eq!(Tables::ClassesTrieHistory.table_type(), TableType::DupSort); + assert_eq!(Tables::ContractsTrieHistory.table_type(), TableType::DupSort); + assert_eq!(Tables::StoragesTrieHistory.table_type(), TableType::DupSort); + assert_eq!(Tables::ClassesTrieChangeSet.table_type(), TableType::Table); + assert_eq!(Tables::ContractsTrieChangeSet.table_type(), TableType::Table); + assert_eq!(Tables::StoragesTrieChangeSet.table_type(), TableType::Table); } use katana_primitives::address; @@ -329,6 +377,9 @@ mod tests { }; use crate::models::list::BlockList; use crate::models::storage::{ContractStorageEntry, ContractStorageKey, StorageEntry}; + use crate::models::trie::{ + TrieDatabaseKey, TrieDatabaseKeyType, TrieDatabaseValue, TrieHistoryEntry, + }; macro_rules! assert_key_encode_decode { { $( ($name:ty, $key:expr) ),* } => { @@ -396,12 +447,17 @@ mod tests { (BlockList, BlockList::default()), (ContractStorageEntry, ContractStorageEntry::default()), (Receipt, Receipt::Invoke(InvokeTxReceipt { - revert_error: None, - events: Vec::new(), - messages_sent: Vec::new(), - execution_resources: Default::default(), - fee: TxFeeInfo { gas_consumed: 0, gas_price: 0, overall_fee: 0, unit: PriceUnit::Wei }, - })) + revert_error: None, + events: Vec::new(), + messages_sent: Vec::new(), + execution_resources: Default::default(), + fee: TxFeeInfo { gas_consumed: 0, gas_price: 0, overall_fee: 0, unit: PriceUnit::Wei }, + })), + (TrieDatabaseValue, TrieDatabaseValue::default()), + (TrieHistoryEntry, TrieHistoryEntry { + value: TrieDatabaseValue::default(), + key: TrieDatabaseKey { key: Vec::default(), r#type: TrieDatabaseKeyType::Flat }, + }) } } } diff --git a/crates/katana/storage/db/src/trie/class.rs b/crates/katana/storage/db/src/trie/class.rs deleted file mode 100644 index 4e853829e9..0000000000 --- a/crates/katana/storage/db/src/trie/class.rs +++ /dev/null @@ -1,55 +0,0 @@ -use bitvec::order::Msb0; -use bitvec::vec::BitVec; -use bitvec::view::AsBits; -use katana_primitives::block::BlockNumber; -use katana_primitives::class::{ClassHash, CompiledClassHash}; -use katana_primitives::Felt; -use katana_trie::bonsai::id::BasicId; -use katana_trie::bonsai::{BonsaiStorage, BonsaiStorageConfig}; -use starknet::macros::short_string; -use starknet_types_core::hash::{Poseidon, StarkHash}; - -use crate::abstraction::DbTxMut; -use crate::tables; -use crate::trie::TrieDb; - -// https://docs.starknet.io/architecture-and-concepts/network-architecture/starknet-state/#classes_trie -const CONTRACT_CLASS_LEAF_V0: Felt = short_string!("CONTRACT_CLASS_LEAF_V0"); - -#[derive(Debug)] -pub struct ClassTrie { - inner: BonsaiStorage, Poseidon>, -} - -impl ClassTrie { - pub fn new(tx: Tx) -> Self { - let config = BonsaiStorageConfig { - max_saved_trie_logs: Some(0), - max_saved_snapshots: Some(0), - snapshot_interval: u64::MAX, - }; - - let db = TrieDb::::new(tx); - let inner = BonsaiStorage::new(db, config).unwrap(); - - Self { inner } - } - - pub fn insert(&mut self, hash: ClassHash, compiled_hash: CompiledClassHash) { - let value = Poseidon::hash(&CONTRACT_CLASS_LEAF_V0, &compiled_hash); - let key: BitVec = hash.to_bytes_be().as_bits()[5..].to_owned(); - self.inner.insert(self.bonsai_identifier(), &key, &value).unwrap(); - } - - pub fn commit(&mut self, block_number: BlockNumber) { - self.inner.commit(BasicId::new(block_number)).unwrap(); - } - - pub fn root(&self) -> Felt { - self.inner.root_hash(self.bonsai_identifier()).unwrap() - } - - fn bonsai_identifier(&self) -> &'static [u8] { - b"1" - } -} diff --git a/crates/katana/storage/db/src/trie/contract.rs b/crates/katana/storage/db/src/trie/contract.rs deleted file mode 100644 index 5e460739aa..0000000000 --- a/crates/katana/storage/db/src/trie/contract.rs +++ /dev/null @@ -1,83 +0,0 @@ -use bitvec::order::Msb0; -use bitvec::vec::BitVec; -use bitvec::view::AsBits; -use katana_primitives::block::BlockNumber; -use katana_primitives::contract::{StorageKey, StorageValue}; -use katana_primitives::{ContractAddress, Felt}; -use katana_trie::bonsai::id::BasicId; -use katana_trie::bonsai::{BonsaiStorage, BonsaiStorageConfig}; -use starknet_types_core::hash::Poseidon; - -use crate::abstraction::DbTxMut; -use crate::tables; -use crate::trie::TrieDb; - -#[derive(Debug)] -pub struct StorageTrie { - inner: BonsaiStorage, Poseidon>, -} - -impl StorageTrie { - pub fn new(tx: Tx) -> Self { - let config = BonsaiStorageConfig { - max_saved_trie_logs: Some(0), - max_saved_snapshots: Some(0), - snapshot_interval: u64::MAX, - }; - - let db = TrieDb::::new(tx); - let inner = BonsaiStorage::new(db, config).unwrap(); - - Self { inner } - } - - pub fn insert(&mut self, address: ContractAddress, key: StorageKey, value: StorageValue) { - let key: BitVec = key.to_bytes_be().as_bits()[5..].to_owned(); - self.inner.insert(&address.to_bytes_be(), &key, &value).unwrap(); - } - - pub fn commit(&mut self, block_number: BlockNumber) { - self.inner.commit(BasicId::new(block_number)).unwrap(); - } - - pub fn root(&self, address: &ContractAddress) -> Felt { - self.inner.root_hash(&address.to_bytes_be()).unwrap() - } -} - -#[derive(Debug)] -pub struct ContractTrie { - inner: BonsaiStorage, Poseidon>, -} - -impl ContractTrie { - pub fn new(tx: Tx) -> Self { - let config = BonsaiStorageConfig { - max_saved_trie_logs: Some(0), - max_saved_snapshots: Some(0), - snapshot_interval: u64::MAX, - }; - - let db = TrieDb::::new(tx); - let inner = BonsaiStorage::new(db, config).unwrap(); - - Self { inner } - } - - pub fn insert(&mut self, address: ContractAddress, state_hash: Felt) { - let key: BitVec = address.to_bytes_be().as_bits()[5..].to_owned(); - self.inner.insert(self.bonsai_identifier(), &key, &state_hash).unwrap(); - } - - pub fn commit(&mut self, block_number: BlockNumber) { - self.inner.commit(BasicId::new(block_number)).unwrap(); - } - - pub fn root(&self) -> Felt { - self.inner.root_hash(self.bonsai_identifier()).unwrap() - } - - fn bonsai_identifier(&self) -> &'static [u8] { - b"1" - } -} diff --git a/crates/katana/storage/db/src/trie/mod.rs b/crates/katana/storage/db/src/trie/mod.rs index 823c9f28ba..de5aaa12e2 100644 --- a/crates/katana/storage/db/src/trie/mod.rs +++ b/crates/katana/storage/db/src/trie/mod.rs @@ -1,20 +1,22 @@ +use core::fmt; +use std::collections::HashMap; +use std::fmt::Debug; use std::marker::PhantomData; use anyhow::Result; -use katana_trie::bonsai::id::BasicId; -use katana_trie::bonsai::{self, ByteVec, DatabaseKey}; +use katana_primitives::block::BlockNumber; +use katana_trie::bonsai::{BonsaiDatabase, BonsaiPersistentDatabase, ByteVec, DatabaseKey}; +use katana_trie::CommitId; use smallvec::ToSmallVec; -use crate::abstraction::{DbCursor, DbTxMut}; -use crate::models::trie::{TrieDatabaseKey, TrieDatabaseKeyType}; +use crate::abstraction::{DbCursor, DbTxMutRef, DbTxRef}; +use crate::models::trie::{TrieDatabaseKey, TrieDatabaseKeyType, TrieHistoryEntry}; use crate::models::{self}; -use crate::tables; +use crate::tables::{self, Trie}; -mod class; -mod contract; +mod snapshot; -pub use class::ClassTrie; -pub use contract::{ContractTrie, StorageTrie}; +pub use snapshot::SnapshotTrieDb; #[derive(Debug, thiserror::Error)] #[error(transparent)] @@ -23,25 +25,218 @@ pub struct Error(#[from] crate::error::DatabaseError); impl katana_trie::bonsai::DBError for Error {} #[derive(Debug)] -pub struct TrieDb { +pub struct TrieDbFactory<'a, Tx: DbTxRef<'a>> { tx: Tx, - _table: PhantomData, + _phantom: &'a PhantomData<()>, } -impl TrieDb +impl<'a, Tx: DbTxRef<'a>> TrieDbFactory<'a, Tx> { + pub fn new(tx: Tx) -> Self { + Self { tx, _phantom: &PhantomData } + } + + pub fn latest(&self) -> GlobalTrie<'a, Tx> { + GlobalTrie { tx: self.tx.clone(), _phantom: &PhantomData } + } + + // TODO: check that the snapshot for the block number is available + pub fn historical(&self, block: BlockNumber) -> Option> { + Some(HistoricalGlobalTrie { tx: self.tx.clone(), block, _phantom: &PhantomData }) + } +} + +/// Provides access to the latest tries. +#[derive(Debug)] +pub struct GlobalTrie<'a, Tx: DbTxRef<'a>> { + tx: Tx, + _phantom: &'a PhantomData<()>, +} + +impl<'a, Tx> GlobalTrie<'a, Tx> +where + Tx: DbTxRef<'a> + Debug, +{ + /// Returns the contracts trie. + pub fn contracts_trie( + &self, + ) -> katana_trie::ContractsTrie> { + katana_trie::ContractsTrie::new(TrieDb::new(self.tx.clone())) + } + + /// Returns the classes trie. + pub fn classes_trie(&self) -> katana_trie::ClassesTrie> { + katana_trie::ClassesTrie::new(TrieDb::new(self.tx.clone())) + } + + /// Returns the storages trie. + pub fn storages_trie(&self) -> katana_trie::StoragesTrie> { + katana_trie::StoragesTrie::new(TrieDb::new(self.tx.clone())) + } +} + +/// Historical tries, allowing access to the state tries at each block. +#[derive(Debug)] +pub struct HistoricalGlobalTrie<'a, Tx: DbTxRef<'a>> { + /// The database transaction. + tx: Tx, + /// The block number at which the trie was constructed. + block: BlockNumber, + _phantom: &'a PhantomData<()>, +} + +impl<'a, Tx> HistoricalGlobalTrie<'a, Tx> +where + Tx: DbTxRef<'a> + Debug, +{ + /// Returns the historical contracts trie. + pub fn contracts_trie( + &self, + ) -> katana_trie::ContractsTrie> { + let commit = CommitId::new(self.block); + katana_trie::ContractsTrie::new(SnapshotTrieDb::new(self.tx.clone(), commit)) + } + + /// Returns the historical classes trie. + pub fn classes_trie( + &self, + ) -> katana_trie::ClassesTrie> { + let commit = CommitId::new(self.block); + katana_trie::ClassesTrie::new(SnapshotTrieDb::new(self.tx.clone(), commit)) + } + + /// Returns the historical storages trie. + pub fn storages_trie( + &self, + ) -> katana_trie::StoragesTrie> { + let commit = CommitId::new(self.block); + katana_trie::StoragesTrie::new(SnapshotTrieDb::new(self.tx.clone(), commit)) + } +} + +// --- Trie's database implementations. These are implemented based on the Bonsai Trie +// functionalities and abstractions. + +pub struct TrieDb<'a, Tb, Tx> +where + Tb: Trie, + Tx: DbTxRef<'a>, +{ + tx: Tx, + _phantom: &'a PhantomData, +} + +impl<'a, Tb, Tx> fmt::Debug for TrieDb<'a, Tb, Tx> +where + Tb: Trie, + Tx: DbTxRef<'a> + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TrieDbMut").field("tx", &self.tx).finish() + } +} + +impl<'a, Tb, Tx> TrieDb<'a, Tb, Tx> +where + Tb: Trie, + Tx: DbTxRef<'a>, +{ + pub(crate) fn new(tx: Tx) -> Self { + Self { tx, _phantom: &PhantomData } + } +} + +impl<'a, Tb, Tx> BonsaiDatabase for TrieDb<'a, Tb, Tx> +where + Tb: Trie, + Tx: DbTxRef<'a> + fmt::Debug, +{ + type Batch = (); + type DatabaseError = Error; + + fn create_batch(&self) -> Self::Batch {} + + fn remove_by_prefix(&mut self, _: &DatabaseKey<'_>) -> Result<(), Self::DatabaseError> { + Ok(()) + } + + fn get(&self, key: &DatabaseKey<'_>) -> Result, Self::DatabaseError> { + let value = self.tx.get::(to_db_key(key))?; + Ok(value) + } + + fn get_by_prefix( + &self, + _: &DatabaseKey<'_>, + ) -> Result, Self::DatabaseError> { + todo!() + } + + fn insert( + &mut self, + _: &DatabaseKey<'_>, + _: &[u8], + _: Option<&mut Self::Batch>, + ) -> Result, Self::DatabaseError> { + unimplemented!("not supported in read-only transaction") + } + + fn remove( + &mut self, + _: &DatabaseKey<'_>, + _: Option<&mut Self::Batch>, + ) -> Result, Self::DatabaseError> { + unimplemented!("not supported in read-only transaction") + } + + fn contains(&self, key: &DatabaseKey<'_>) -> Result { + let key = to_db_key(key); + let value = self.tx.get::(key)?; + Ok(value.is_some()) + } + + fn write_batch(&mut self, _: Self::Batch) -> Result<(), Self::DatabaseError> { + unimplemented!("not supported in read-only transaction") + } +} + +pub struct TrieDbMut<'tx, Tb, Tx> +where + Tb: Trie, + Tx: DbTxMutRef<'tx>, +{ + tx: Tx, + /// List of key-value pairs that has been added throughout the duration of the trie + /// transaction. + /// + /// This will be used to create the trie snapshot. + write_cache: HashMap, + _phantom: &'tx PhantomData, +} + +impl<'tx, Tb, Tx> fmt::Debug for TrieDbMut<'tx, Tb, Tx> +where + Tb: Trie, + Tx: DbTxMutRef<'tx> + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TrieDbMut").field("tx", &self.tx).finish() + } +} + +impl<'tx, Tb, Tx> TrieDbMut<'tx, Tb, Tx> where - Tb: tables::Trie, - Tx: DbTxMut, + Tb: Trie, + Tx: DbTxMutRef<'tx>, { pub fn new(tx: Tx) -> Self { - Self { tx, _table: PhantomData } + Self { tx, write_cache: HashMap::new(), _phantom: &PhantomData } } } -impl bonsai::BonsaiDatabase for TrieDb +impl<'tx, Tb, Tx> BonsaiDatabase for TrieDbMut<'tx, Tb, Tx> where - Tb: tables::Trie, - Tx: DbTxMut, + Tb: Trie, + Tx: DbTxMutRef<'tx> + fmt::Debug, { type Batch = (); type DatabaseError = Error; @@ -85,23 +280,30 @@ where &mut self, key: &DatabaseKey<'_>, value: &[u8], - _batch: Option<&mut Self::Batch>, + batch: Option<&mut Self::Batch>, ) -> Result, Self::DatabaseError> { + let _ = batch; let key = to_db_key(key); let value: ByteVec = value.to_smallvec(); + let old_value = self.tx.get::(key.clone())?; - self.tx.put::(key, value)?; + self.tx.put::(key.clone(), value.clone())?; + + self.write_cache.insert(key, value); Ok(old_value) } fn remove( &mut self, key: &DatabaseKey<'_>, - _batch: Option<&mut Self::Batch>, + batch: Option<&mut Self::Batch>, ) -> Result, Self::DatabaseError> { + let _ = batch; let key = to_db_key(key); + let old_value = self.tx.get::(key.clone())?; self.tx.delete::(key, None)?; + Ok(old_value) } @@ -111,27 +313,56 @@ where Ok(value.is_some()) } - fn write_batch(&mut self, _batch: Self::Batch) -> Result<(), Self::DatabaseError> { + fn write_batch(&mut self, _: Self::Batch) -> Result<(), Self::DatabaseError> { Ok(()) } } -impl bonsai::BonsaiPersistentDatabase for TrieDb +impl<'tx, Tb, Tx> BonsaiPersistentDatabase for TrieDbMut<'tx, Tb, Tx> where - Tb: tables::Trie, - Tx: DbTxMut, + Tb: Trie, + Tx: DbTxMutRef<'tx> + fmt::Debug + 'tx, { type DatabaseError = Error; - type Transaction = TrieDb; + type Transaction<'a> = SnapshotTrieDb<'tx, Tb, Tx> where Self: 'a; + + fn snapshot(&mut self, id: CommitId) { + let block_number: BlockNumber = id.into(); + + let entries = std::mem::take(&mut self.write_cache); + let entries = entries.into_iter().map(|(key, value)| TrieHistoryEntry { key, value }); + + for entry in entries { + let mut set = self + .tx + .get::(entry.key.clone()) + .expect("failed to get trie change set") + .unwrap_or_default(); + set.insert(block_number); - fn snapshot(&mut self, _: BasicId) {} + self.tx + .put::(entry.key.clone(), set) + .expect("failed to put trie change set"); + + self.tx + .put::(block_number, entry) + .expect("failed to put trie history entry"); + } + } - fn merge(&mut self, _: Self::Transaction) -> Result<(), Self::DatabaseError> { - todo!(); + // merging should recompute the trie again + fn merge<'a>(&mut self, transaction: Self::Transaction<'a>) -> Result<(), Self::DatabaseError> + where + Self: 'a, + { + let _ = transaction; + unimplemented!(); } - fn transaction(&self, _: BasicId) -> Option { - todo!(); + // TODO: check if the snapshot exist + fn transaction(&self, id: CommitId) -> Option<(CommitId, Self::Transaction<'_>)> { + dbg!("getting snapshot", id); + Some((id, SnapshotTrieDb::new(self.tx.clone(), id))) } } diff --git a/crates/katana/storage/db/src/trie/snapshot.rs b/crates/katana/storage/db/src/trie/snapshot.rs new file mode 100644 index 0000000000..b9adff8d72 --- /dev/null +++ b/crates/katana/storage/db/src/trie/snapshot.rs @@ -0,0 +1,123 @@ +use core::fmt; +use std::marker::PhantomData; + +use anyhow::Result; +use katana_primitives::block::BlockNumber; +use katana_trie::bonsai::{BonsaiDatabase, ByteVec, DatabaseKey}; +use katana_trie::CommitId; + +use super::Error; +use crate::abstraction::{DbDupSortCursor, DbTxRef}; +use crate::models::list::BlockList; +use crate::tables::Trie; +use crate::trie::to_db_key; + +pub struct SnapshotTrieDb<'tx, Tb, Tx> +where + Tb: Trie, + Tx: DbTxRef<'tx>, +{ + tx: Tx, + snapshot_id: CommitId, + _table: &'tx PhantomData, +} + +impl<'a, Tb, Tx> fmt::Debug for SnapshotTrieDb<'a, Tb, Tx> +where + Tb: Trie, + Tx: DbTxRef<'a> + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SnapshotTrieDb").field("tx", &self.tx).finish() + } +} + +/// This is a helper function for getting the block number of the most +/// recent change that occurred relative to the given block number. +/// +/// ## Arguments +/// +/// * `block_list`: A list of block numbers where a change in value occur. +fn recent_change_from_block(target: BlockNumber, block_list: &BlockList) -> Option { + // if the rank is 0, then it's either; + // 1. the list is empty + // 2. there are no prior changes occured before/at `block_number` + let rank = block_list.rank(target); + if rank == 0 { None } else { block_list.select(rank - 1) } +} + +impl<'tx, Tb, Tx> SnapshotTrieDb<'tx, Tb, Tx> +where + Tb: Trie, + Tx: DbTxRef<'tx>, +{ + pub(crate) fn new(tx: Tx, id: CommitId) -> Self { + Self { tx, snapshot_id: id, _table: &PhantomData } + } +} + +impl<'tx, Tb, Tx> BonsaiDatabase for SnapshotTrieDb<'tx, Tb, Tx> +where + Tb: Trie, + Tx: DbTxRef<'tx> + fmt::Debug, +{ + type Batch = (); + type DatabaseError = Error; + + fn create_batch(&self) -> Self::Batch {} + + fn remove_by_prefix(&mut self, _: &DatabaseKey<'_>) -> Result<(), Self::DatabaseError> { + unimplemented!("modifying trie snapshot is not supported") + } + + fn get(&self, key: &DatabaseKey<'_>) -> Result, Self::DatabaseError> { + let key = to_db_key(key); + let block_number = self.snapshot_id.into(); + + let change_set = self.tx.get::(key.clone())?; + if let Some(num) = change_set.and_then(|set| recent_change_from_block(block_number, &set)) { + let mut cursor = self.tx.cursor_dup::()?; + let entry = cursor + .seek_by_key_subkey(num, key.clone())? + .expect("entry should exist if in change set"); + + if entry.key == key { + return Ok(Some(entry.value)); + } + } + + Ok(None) + } + + fn get_by_prefix( + &self, + _: &DatabaseKey<'_>, + ) -> Result, Self::DatabaseError> { + todo!() + } + + fn insert( + &mut self, + _: &DatabaseKey<'_>, + _: &[u8], + _: Option<&mut Self::Batch>, + ) -> Result, Self::DatabaseError> { + unimplemented!("modifying trie snapshot is not supported") + } + + fn remove( + &mut self, + _: &DatabaseKey<'_>, + _: Option<&mut Self::Batch>, + ) -> Result, Self::DatabaseError> { + unimplemented!("modifying trie snapshot is not supported") + } + + fn contains(&self, _: &DatabaseKey<'_>) -> Result { + todo!() + } + + fn write_batch(&mut self, _: Self::Batch) -> Result<(), Self::DatabaseError> { + unimplemented!("modifying trie snapshot is not supported") + } +} diff --git a/crates/katana/storage/db/src/version.rs b/crates/katana/storage/db/src/version.rs index c8542f5b26..c7797c39b7 100644 --- a/crates/katana/storage/db/src/version.rs +++ b/crates/katana/storage/db/src/version.rs @@ -5,7 +5,7 @@ use std::mem; use std::path::{Path, PathBuf}; /// Current version of the database. -pub const CURRENT_DB_VERSION: u32 = 5; +pub const CURRENT_DB_VERSION: u32 = 6; /// Name of the version file. const DB_VERSION_FILE_NAME: &str = "db.version"; @@ -81,6 +81,6 @@ mod tests { #[test] fn test_current_version() { use super::CURRENT_DB_VERSION; - assert_eq!(CURRENT_DB_VERSION, 5, "Invalid current database version") + assert_eq!(CURRENT_DB_VERSION, 6, "Invalid current database version") } } diff --git a/crates/katana/storage/provider/src/lib.rs b/crates/katana/storage/provider/src/lib.rs index dc156ce7f6..191af03cdd 100644 --- a/crates/katana/storage/provider/src/lib.rs +++ b/crates/katana/storage/provider/src/lib.rs @@ -16,12 +16,12 @@ use katana_primitives::trace::TxExecInfo; use katana_primitives::transaction::{TxHash, TxNumber, TxWithHash}; use katana_primitives::Felt; use traits::block::{BlockIdReader, BlockStatusProvider, BlockWriter}; -use traits::contract::{ContractClassProvider, ContractClassWriter, ContractClassWriterExt}; +use traits::contract::{ContractClassWriter, ContractClassWriterExt}; use traits::env::BlockEnvProvider; use traits::stage::StageCheckpointProvider; -use traits::state::{StateRootProvider, StateWriter}; +use traits::state::StateWriter; use traits::transaction::{TransactionStatusProvider, TransactionTraceProvider}; -use traits::trie::{ClassTrieWriter, ContractTrieWriter}; +use traits::trie::TrieWriter; pub mod error; pub mod providers; @@ -246,53 +246,6 @@ where } } -impl StateProvider for BlockchainProvider -where - Db: StateProvider, -{ - fn nonce( - &self, - address: ContractAddress, - ) -> ProviderResult> { - self.provider.nonce(address) - } - - fn storage( - &self, - address: ContractAddress, - storage_key: StorageKey, - ) -> ProviderResult> { - self.provider.storage(address, storage_key) - } - - fn class_hash_of_contract( - &self, - address: ContractAddress, - ) -> ProviderResult> { - self.provider.class_hash_of_contract(address) - } -} - -impl ContractClassProvider for BlockchainProvider -where - Db: ContractClassProvider, -{ - fn class(&self, hash: ClassHash) -> ProviderResult> { - self.provider.class(hash) - } - - fn compiled_class(&self, hash: ClassHash) -> ProviderResult> { - self.provider.compiled_class(hash) - } - - fn compiled_class_hash_of_class_hash( - &self, - hash: ClassHash, - ) -> ProviderResult> { - self.provider.compiled_class_hash_of_class_hash(hash) - } -} - impl StateFactoryProvider for BlockchainProvider where Db: StateFactoryProvider, @@ -332,15 +285,6 @@ where } } -impl StateRootProvider for BlockchainProvider -where - Db: StateRootProvider, -{ - fn state_root(&self, block_id: BlockHashOrNumber) -> ProviderResult> { - self.provider.state_root(block_id) - } -} - impl ContractClassWriter for BlockchainProvider where Db: ContractClassWriter, @@ -406,29 +350,24 @@ where } } -impl ClassTrieWriter for BlockchainProvider +impl TrieWriter for BlockchainProvider where - Db: ClassTrieWriter, + Db: TrieWriter, { - fn insert_updates( + fn trie_insert_declared_classes( &self, block_number: BlockNumber, updates: &BTreeMap, ) -> ProviderResult { - self.provider.insert_updates(block_number, updates) + self.provider.trie_insert_declared_classes(block_number, updates) } -} -impl ContractTrieWriter for BlockchainProvider -where - Db: ContractTrieWriter, -{ - fn insert_updates( + fn trie_insert_contract_updates( &self, block_number: BlockNumber, state_updates: &StateUpdates, ) -> ProviderResult { - self.provider.insert_updates(block_number, state_updates) + self.provider.trie_insert_contract_updates(block_number, state_updates) } } diff --git a/crates/katana/storage/provider/src/providers/db/mod.rs b/crates/katana/storage/provider/src/providers/db/mod.rs index f880dfc73c..17b028669b 100644 --- a/crates/katana/storage/provider/src/providers/db/mod.rs +++ b/crates/katana/storage/provider/src/providers/db/mod.rs @@ -31,7 +31,6 @@ use katana_primitives::receipt::Receipt; use katana_primitives::state::{StateUpdates, StateUpdatesWithClasses}; use katana_primitives::trace::TxExecInfo; use katana_primitives::transaction::{TxHash, TxNumber, TxWithHash}; -use katana_primitives::Felt; use crate::error::ProviderError; use crate::traits::block::{ @@ -40,7 +39,7 @@ use crate::traits::block::{ }; use crate::traits::env::BlockEnvProvider; use crate::traits::stage::StageCheckpointProvider; -use crate::traits::state::{StateFactoryProvider, StateProvider, StateRootProvider}; +use crate::traits::state::{StateFactoryProvider, StateProvider}; use crate::traits::state_update::StateUpdateProvider; use crate::traits::transaction::{ ReceiptProvider, TransactionProvider, TransactionStatusProvider, TransactionTraceProvider, @@ -256,25 +255,6 @@ impl BlockStatusProvider for DbProvider { } } -impl StateRootProvider for DbProvider { - fn state_root(&self, block_id: BlockHashOrNumber) -> ProviderResult> { - let db_tx = self.0.tx()?; - - let block_num = match block_id { - BlockHashOrNumber::Num(num) => Some(num), - BlockHashOrNumber::Hash(hash) => db_tx.get::(hash)?, - }; - - if let Some(block_num) = block_num { - let header = db_tx.get::(block_num)?; - db_tx.commit()?; - Ok(header.map(|h| h.state_root)) - } else { - Ok(None) - } - } -} - // A helper function that iterates over all entries in a dupsort table and collects the // results into `V`. If `key` is not found, `V::default()` is returned. fn dup_entries( diff --git a/crates/katana/storage/provider/src/providers/db/state.rs b/crates/katana/storage/provider/src/providers/db/state.rs index 0589ac5d30..fbf2498898 100644 --- a/crates/katana/storage/provider/src/providers/db/state.rs +++ b/crates/katana/storage/provider/src/providers/db/state.rs @@ -5,6 +5,7 @@ use katana_db::models::contract::ContractInfoChangeList; use katana_db::models::list::BlockList; use katana_db::models::storage::{ContractStorageKey, StorageEntry}; use katana_db::tables; +use katana_db::trie::TrieDbFactory; use katana_primitives::block::BlockNumber; use katana_primitives::class::{ClassHash, CompiledClass, CompiledClassHash, ContractClass}; use katana_primitives::contract::{ @@ -14,7 +15,7 @@ use katana_primitives::contract::{ use super::DbProvider; use crate::error::ProviderError; use crate::traits::contract::{ContractClassProvider, ContractClassWriter, ContractClassWriterExt}; -use crate::traits::state::{StateProvider, StateWriter}; +use crate::traits::state::{StateProofProvider, StateProvider, StateRootProvider, StateWriter}; use crate::ProviderResult; impl StateWriter for DbProvider { @@ -160,6 +161,51 @@ where } } +impl StateProofProvider for LatestStateProvider +where + Tx: DbTx + fmt::Debug + Send + Sync, +{ + fn class_multiproof(&self, classes: Vec) -> ProviderResult { + let mut trie = TrieDbFactory::new(&self.0).latest().classes_trie(); + let proofs = trie.multiproof(classes); + Ok(proofs) + } + + fn contract_multiproof( + &self, + addresses: Vec, + ) -> ProviderResult { + let mut trie = TrieDbFactory::new(&self.0).latest().contracts_trie(); + let proofs = trie.multiproof(addresses); + Ok(proofs) + } + + fn storage_multiproof( + &self, + address: ContractAddress, + storage_keys: Vec, + ) -> ProviderResult { + let mut trie = TrieDbFactory::new(&self.0).latest().storages_trie(); + let proofs = trie.multiproof(address, storage_keys); + Ok(proofs) + } +} + +impl StateRootProvider for LatestStateProvider +where + Tx: DbTx + fmt::Debug + Send + Sync, +{ + fn classes_root(&self) -> ProviderResult { + let trie = TrieDbFactory::new(&self.0).latest().classes_trie(); + Ok(trie.root()) + } + + fn contracts_root(&self) -> ProviderResult { + let trie = TrieDbFactory::new(&self.0).latest().contracts_trie(); + Ok(trie.root()) + } +} + /// A historical state provider. #[derive(Debug)] pub(super) struct HistoricalStateProvider { @@ -293,8 +339,79 @@ where } } +impl StateProofProvider for HistoricalStateProvider +where + Tx: DbTx + fmt::Debug + Send + Sync, +{ + fn class_multiproof(&self, classes: Vec) -> ProviderResult { + let proofs = TrieDbFactory::new(&self.tx) + .historical(self.block_number) + .expect("should exist") + .classes_trie() + .multiproof(classes); + Ok(proofs) + } + + fn contract_multiproof( + &self, + addresses: Vec, + ) -> ProviderResult { + let proofs = TrieDbFactory::new(&self.tx) + .historical(self.block_number) + .expect("should exist") + .contracts_trie() + .multiproof(addresses); + Ok(proofs) + } + + fn storage_multiproof( + &self, + address: ContractAddress, + storage_keys: Vec, + ) -> ProviderResult { + let proofs = TrieDbFactory::new(&self.tx) + .historical(self.block_number) + .expect("should exist") + .storages_trie() + .multiproof(address, storage_keys); + Ok(proofs) + } +} + +impl StateRootProvider for HistoricalStateProvider +where + Tx: DbTx + fmt::Debug + Send + Sync, +{ + fn classes_root(&self) -> ProviderResult { + let root = TrieDbFactory::new(&self.tx) + .historical(self.block_number) + .expect("should exist") + .classes_trie() + .root(); + Ok(root) + } + + fn contracts_root(&self) -> ProviderResult { + let root = TrieDbFactory::new(&self.tx) + .historical(self.block_number) + .expect("should exist") + .contracts_trie() + .root(); + Ok(root) + } + + fn state_root(&self) -> ProviderResult { + let header = self.tx.get::(self.block_number)?.expect("should exist"); + Ok(header.state_root) + } +} + /// This is a helper function for getting the block number of the most /// recent change that occurred relative to the given block number. +/// +/// ## Arguments +/// +/// * `block_list`: A list of block numbers where a change in value occur. fn recent_change_from_block( block_number: BlockNumber, block_list: &BlockList, diff --git a/crates/katana/storage/provider/src/providers/db/trie.rs b/crates/katana/storage/provider/src/providers/db/trie.rs index 65b5b96984..cb98362d4c 100644 --- a/crates/katana/storage/provider/src/providers/db/trie.rs +++ b/crates/katana/storage/provider/src/providers/db/trie.rs @@ -2,17 +2,18 @@ use std::collections::{BTreeMap, HashMap}; use std::fmt::Debug; use katana_db::abstraction::Database; -use katana_db::trie; -use katana_db::trie::{ContractTrie, StorageTrie}; +use katana_db::tables; +use katana_db::trie::TrieDbMut; use katana_primitives::block::BlockNumber; use katana_primitives::class::{ClassHash, CompiledClassHash}; use katana_primitives::state::StateUpdates; use katana_primitives::{ContractAddress, Felt}; -use katana_trie::compute_contract_state_hash; +use katana_trie::{compute_contract_state_hash, ClassesTrie, ContractsTrie, StoragesTrie}; use crate::providers::db::DbProvider; use crate::traits::state::{StateFactoryProvider, StateProvider}; -use crate::traits::trie::{ClassTrieWriter, ContractTrieWriter}; +use crate::traits::trie::TrieWriter; +use crate::ProviderResult; #[derive(Debug, Default)] struct ContractLeaf { @@ -21,80 +22,84 @@ struct ContractLeaf { pub nonce: Option, } -impl ClassTrieWriter for DbProvider { - fn insert_updates( +impl TrieWriter for DbProvider { + fn trie_insert_declared_classes( &self, block_number: BlockNumber, updates: &BTreeMap, - ) -> crate::ProviderResult { - let mut trie = trie::ClassTrie::new(self.0.tx_mut()?); + ) -> ProviderResult { + self.0.update(|tx| { + let mut trie = ClassesTrie::new(TrieDbMut::::new(tx)); - for (class_hash, compiled_hash) in updates { - trie.insert(*class_hash, *compiled_hash); - } + for (class_hash, compiled_hash) in updates { + trie.insert(*class_hash, *compiled_hash); + } - trie.commit(block_number); - Ok(trie.root()) + trie.commit(block_number); + Ok(trie.root()) + })? } -} -impl ContractTrieWriter for DbProvider { - fn insert_updates( + fn trie_insert_contract_updates( &self, block_number: BlockNumber, state_updates: &StateUpdates, - ) -> crate::ProviderResult { - let mut contract_leafs: HashMap = HashMap::new(); - - let leaf_hashes: Vec<_> = { - let mut storage_trie_db = StorageTrie::new(self.0.tx_mut()?); - - // First we insert the contract storage changes - for (address, storage_entries) in &state_updates.storage_updates { - for (key, value) in storage_entries { - storage_trie_db.insert(*address, *key, *value); + ) -> ProviderResult { + self.0.update(|tx| { + let mut contract_trie_db = + ContractsTrie::new(TrieDbMut::::new(tx)); + let mut storage_trie_db = + StoragesTrie::new(TrieDbMut::::new(tx)); + + let mut contract_leafs: HashMap = HashMap::new(); + + let leaf_hashes: Vec<_> = { + // First we insert the contract storage changes + for (address, storage_entries) in &state_updates.storage_updates { + for (key, value) in storage_entries { + storage_trie_db.insert(*address, *key, *value); + } + // insert the contract address in the contract_leafs to put the storage root + // later + contract_leafs.insert(*address, Default::default()); } - // insert the contract address in the contract_leafs to put the storage root later - contract_leafs.insert(*address, Default::default()); - } - - // Then we commit them - storage_trie_db.commit(block_number); - for (address, nonce) in &state_updates.nonce_updates { - contract_leafs.entry(*address).or_default().nonce = Some(*nonce); - } + // Then we commit them + storage_trie_db.commit(block_number); - for (address, class_hash) in &state_updates.deployed_contracts { - contract_leafs.entry(*address).or_default().class_hash = Some(*class_hash); - } + for (address, nonce) in &state_updates.nonce_updates { + contract_leafs.entry(*address).or_default().nonce = Some(*nonce); + } - for (address, class_hash) in &state_updates.replaced_classes { - contract_leafs.entry(*address).or_default().class_hash = Some(*class_hash); - } + for (address, class_hash) in &state_updates.deployed_contracts { + contract_leafs.entry(*address).or_default().class_hash = Some(*class_hash); + } - contract_leafs - .into_iter() - .map(|(address, mut leaf)| { - let storage_root = storage_trie_db.root(&address); - leaf.storage_root = Some(storage_root); + for (address, class_hash) in &state_updates.replaced_classes { + contract_leafs.entry(*address).or_default().class_hash = Some(*class_hash); + } - let latest_state = self.latest().unwrap(); - let leaf_hash = contract_state_leaf_hash(latest_state, &address, &leaf); + contract_leafs + .into_iter() + .map(|(address, mut leaf)| { + let storage_root = storage_trie_db.root(address); + leaf.storage_root = Some(storage_root); - (address, leaf_hash) - }) - .collect::>() - }; + let latest_state = self.latest().unwrap(); + let leaf_hash = contract_state_leaf_hash(latest_state, &address, &leaf); - let mut contract_trie_db = ContractTrie::new(self.0.tx_mut()?); + (address, leaf_hash) + }) + .collect::>() + }; - for (k, v) in leaf_hashes { - contract_trie_db.insert(k, v); - } + for (k, v) in leaf_hashes { + contract_trie_db.insert(k, v); + } - contract_trie_db.commit(block_number); - Ok(contract_trie_db.root()) + contract_trie_db.commit(block_number); + Ok(contract_trie_db.root()) + })? } } diff --git a/crates/katana/storage/provider/src/providers/fork/backend.rs b/crates/katana/storage/provider/src/providers/fork/backend.rs index 4c5637be26..21169855cd 100644 --- a/crates/katana/storage/provider/src/providers/fork/backend.rs +++ b/crates/katana/storage/provider/src/providers/fork/backend.rs @@ -26,7 +26,7 @@ use tracing::{error, trace}; use crate::error::ProviderError; use crate::providers::in_memory::cache::CacheStateDb; use crate::traits::contract::ContractClassProvider; -use crate::traits::state::StateProvider; +use crate::traits::state::{StateProofProvider, StateProvider, StateRootProvider}; use crate::ProviderResult; const LOG_TARGET: &str = "forking::backend"; @@ -567,6 +567,41 @@ impl ContractClassProvider for SharedStateProvider { } } +impl StateProofProvider for SharedStateProvider { + fn class_multiproof(&self, classes: Vec) -> ProviderResult { + let _ = classes; + unimplemented!("not supported in forked mode") + } + + fn contract_multiproof( + &self, + addresses: Vec, + ) -> ProviderResult { + let _ = addresses; + unimplemented!("not supported in forked mode") + } + + fn storage_multiproof( + &self, + address: ContractAddress, + key: Vec, + ) -> ProviderResult { + let _ = address; + let _ = key; + unimplemented!("not supported in forked mode") + } +} + +impl StateRootProvider for SharedStateProvider { + fn classes_root(&self) -> ProviderResult { + unimplemented!("not supported in forked mode") + } + + fn contracts_root(&self) -> ProviderResult { + unimplemented!("not supported in forked mode") + } +} + /// A helper function to convert a contract/class not found error returned by the RPC provider into /// a `Option::None`. /// diff --git a/crates/katana/storage/provider/src/providers/fork/mod.rs b/crates/katana/storage/provider/src/providers/fork/mod.rs index 922b1ada91..09342cc860 100644 --- a/crates/katana/storage/provider/src/providers/fork/mod.rs +++ b/crates/katana/storage/provider/src/providers/fork/mod.rs @@ -33,13 +33,13 @@ use crate::traits::block::{ use crate::traits::contract::{ContractClassWriter, ContractClassWriterExt}; use crate::traits::env::BlockEnvProvider; use crate::traits::stage::StageCheckpointProvider; -use crate::traits::state::{StateFactoryProvider, StateProvider, StateRootProvider, StateWriter}; +use crate::traits::state::{StateFactoryProvider, StateProvider, StateWriter}; use crate::traits::state_update::StateUpdateProvider; use crate::traits::transaction::{ ReceiptProvider, TransactionProvider, TransactionStatusProvider, TransactionTraceProvider, TransactionsProviderExt, }; -use crate::traits::trie::{ClassTrieWriter, ContractTrieWriter}; +use crate::traits::trie::TrieWriter; use crate::ProviderResult; #[derive(Debug)] @@ -410,17 +410,17 @@ impl ReceiptProvider for ForkedProvider { } } -impl StateRootProvider for ForkedProvider { - fn state_root( - &self, - block_id: BlockHashOrNumber, - ) -> ProviderResult> { - let state_root = self.block_number_by_id(block_id)?.and_then(|num| { - self.storage.read().block_headers.get(&num).map(|header| header.state_root) - }); - Ok(state_root) - } -} +// impl StateRootProvider for ForkedProvider { +// fn state_root( +// &self, +// block_id: BlockHashOrNumber, +// ) -> ProviderResult> { +// let state_root = self.block_number_by_id(block_id)?.and_then(|num| { +// self.storage.read().block_headers.get(&num).map(|header| header.state_root) +// }); +// Ok(state_root) +// } +// } impl StateUpdateProvider for ForkedProvider { fn state_update(&self, block_id: BlockHashOrNumber) -> ProviderResult> { @@ -599,8 +599,8 @@ impl BlockEnvProvider for ForkedProvider { } } -impl ClassTrieWriter for ForkedProvider { - fn insert_updates( +impl TrieWriter for ForkedProvider { + fn trie_insert_declared_classes( &self, block_number: BlockNumber, updates: &BTreeMap, @@ -609,10 +609,8 @@ impl ClassTrieWriter for ForkedProvider { let _ = updates; Ok(Felt::ZERO) } -} -impl ContractTrieWriter for ForkedProvider { - fn insert_updates( + fn trie_insert_contract_updates( &self, block_number: BlockNumber, state_updates: &StateUpdates, diff --git a/crates/katana/storage/provider/src/providers/fork/state.rs b/crates/katana/storage/provider/src/providers/fork/state.rs index b1377743cc..3c6fe5debd 100644 --- a/crates/katana/storage/provider/src/providers/fork/state.rs +++ b/crates/katana/storage/provider/src/providers/fork/state.rs @@ -7,7 +7,7 @@ use super::backend::SharedStateProvider; use crate::providers::in_memory::cache::CacheStateDb; use crate::providers::in_memory::state::StateSnapshot; use crate::traits::contract::ContractClassProvider; -use crate::traits::state::StateProvider; +use crate::traits::state::{StateProofProvider, StateProvider, StateRootProvider}; use crate::ProviderResult; pub type ForkedStateDb = CacheStateDb; @@ -76,7 +76,7 @@ impl StateProvider for ForkedStateDb { } } -impl ContractClassProvider for CacheStateDb { +impl ContractClassProvider for ForkedStateDb { fn class(&self, hash: ClassHash) -> ProviderResult> { if let class @ Some(_) = self.shared_contract_classes.classes.read().get(&hash) { return Ok(class.cloned()); @@ -102,6 +102,37 @@ impl ContractClassProvider for CacheStateDb { } } +impl StateProofProvider for ForkedStateDb { + fn class_multiproof(&self, _: Vec) -> ProviderResult { + Ok(katana_trie::MultiProof(Default::default())) + } + + fn contract_multiproof( + &self, + _: Vec, + ) -> ProviderResult { + Ok(katana_trie::MultiProof(Default::default())) + } + + fn storage_multiproof( + &self, + _: ContractAddress, + _: Vec, + ) -> ProviderResult { + Ok(katana_trie::MultiProof(Default::default())) + } +} + +impl StateRootProvider for ForkedStateDb { + fn classes_root(&self) -> ProviderResult { + Ok(katana_primitives::Felt::ZERO) + } + + fn contracts_root(&self) -> ProviderResult { + Ok(katana_primitives::Felt::ZERO) + } +} + #[derive(Debug)] pub(super) struct LatestStateProvider(pub(super) Arc); @@ -143,6 +174,37 @@ impl ContractClassProvider for LatestStateProvider { } } +impl StateProofProvider for LatestStateProvider { + fn class_multiproof(&self, _: Vec) -> ProviderResult { + Ok(katana_trie::MultiProof(Default::default())) + } + + fn contract_multiproof( + &self, + _: Vec, + ) -> ProviderResult { + Ok(katana_trie::MultiProof(Default::default())) + } + + fn storage_multiproof( + &self, + _: ContractAddress, + _: Vec, + ) -> ProviderResult { + Ok(katana_trie::MultiProof(Default::default())) + } +} + +impl StateRootProvider for LatestStateProvider { + fn classes_root(&self) -> ProviderResult { + Ok(katana_primitives::Felt::ZERO) + } + + fn contracts_root(&self) -> ProviderResult { + Ok(katana_primitives::Felt::ZERO) + } +} + impl StateProvider for ForkedSnapshot { fn nonce(&self, address: ContractAddress) -> ProviderResult> { if let nonce @ Some(_) = self @@ -215,6 +277,37 @@ impl ContractClassProvider for ForkedSnapshot { } } +impl StateProofProvider for ForkedSnapshot { + fn class_multiproof(&self, _: Vec) -> ProviderResult { + Ok(katana_trie::MultiProof(Default::default())) + } + + fn contract_multiproof( + &self, + _: Vec, + ) -> ProviderResult { + Ok(katana_trie::MultiProof(Default::default())) + } + + fn storage_multiproof( + &self, + _: ContractAddress, + _: Vec, + ) -> ProviderResult { + Ok(katana_trie::MultiProof(Default::default())) + } +} + +impl StateRootProvider for ForkedSnapshot { + fn classes_root(&self) -> ProviderResult { + Ok(katana_primitives::Felt::ZERO) + } + + fn contracts_root(&self) -> ProviderResult { + Ok(katana_primitives::Felt::ZERO) + } +} + #[cfg(test)] mod tests { use std::collections::BTreeMap; diff --git a/crates/katana/storage/provider/src/traits/state.rs b/crates/katana/storage/provider/src/traits/state.rs index 38046c2b5b..2059933bf4 100644 --- a/crates/katana/storage/provider/src/traits/state.rs +++ b/crates/katana/storage/provider/src/traits/state.rs @@ -2,18 +2,35 @@ use katana_primitives::block::BlockHashOrNumber; use katana_primitives::class::ClassHash; use katana_primitives::contract::{ContractAddress, Nonce, StorageKey, StorageValue}; use katana_primitives::Felt; +use katana_trie::MultiProof; +use starknet::macros::short_string; +use starknet_types_core::hash::StarkHash; use super::contract::ContractClassProvider; use crate::ProviderResult; #[auto_impl::auto_impl(&, Box, Arc)] pub trait StateRootProvider: Send + Sync { - /// Retrieves the state root of a block. - fn state_root(&self, block_id: BlockHashOrNumber) -> ProviderResult>; + /// Retrieves the root of the global state trie. + fn state_root(&self) -> ProviderResult { + Ok(starknet_types_core::hash::Poseidon::hash_array(&[ + short_string!("STARKNET_STATE_V0"), + self.contracts_root()?, + self.classes_root()?, + ])) + } + + /// Retrieves the root of the classes trie. + fn classes_root(&self) -> ProviderResult; + + /// Retrieves the root of the contracts trie. + fn contracts_root(&self) -> ProviderResult; } #[auto_impl::auto_impl(&, Box, Arc)] -pub trait StateProvider: ContractClassProvider + Send + Sync + std::fmt::Debug { +pub trait StateProvider: + ContractClassProvider + StateProofProvider + StateRootProvider + Send + Sync + std::fmt::Debug +{ /// Returns the nonce of a contract. fn nonce(&self, address: ContractAddress) -> ProviderResult>; @@ -63,3 +80,16 @@ pub trait StateWriter: Send + Sync { class_hash: ClassHash, ) -> ProviderResult<()>; } + +#[auto_impl::auto_impl(&, Box, Arc)] +pub trait StateProofProvider: Send + Sync { + fn storage_multiproof( + &self, + address: ContractAddress, + key: Vec, + ) -> ProviderResult; + + fn contract_multiproof(&self, addresses: Vec) -> ProviderResult; + + fn class_multiproof(&self, classes: Vec) -> ProviderResult; +} diff --git a/crates/katana/storage/provider/src/traits/trie.rs b/crates/katana/storage/provider/src/traits/trie.rs index 8570a30b88..6a63ec3c40 100644 --- a/crates/katana/storage/provider/src/traits/trie.rs +++ b/crates/katana/storage/provider/src/traits/trie.rs @@ -8,17 +8,14 @@ use katana_primitives::Felt; use crate::ProviderResult; #[auto_impl::auto_impl(&, Box, Arc)] -pub trait ClassTrieWriter: Send + Sync { - fn insert_updates( +pub trait TrieWriter: Send + Sync { + fn trie_insert_declared_classes( &self, block_number: BlockNumber, updates: &BTreeMap, ) -> ProviderResult; -} -#[auto_impl::auto_impl(&, Box, Arc)] -pub trait ContractTrieWriter: Send + Sync { - fn insert_updates( + fn trie_insert_contract_updates( &self, block_number: BlockNumber, state_updates: &StateUpdates, diff --git a/crates/katana/storage/provider/tests/block.rs b/crates/katana/storage/provider/tests/block.rs index 3b6f686804..1be22a5e92 100644 --- a/crates/katana/storage/provider/tests/block.rs +++ b/crates/katana/storage/provider/tests/block.rs @@ -11,7 +11,7 @@ use katana_provider::traits::block::{ BlockHashProvider, BlockNumberProvider, BlockProvider, BlockStatusProvider, BlockWriter, }; use katana_provider::traits::env::BlockEnvProvider; -use katana_provider::traits::state::StateRootProvider; +use katana_provider::traits::state::{StateFactoryProvider, StateRootProvider}; use katana_provider::traits::state_update::StateUpdateProvider; use katana_provider::traits::transaction::{ ReceiptProvider, TransactionProvider, TransactionStatusProvider, TransactionTraceProvider, @@ -29,6 +29,7 @@ use fixtures::{ use katana_primitives::Felt; #[apply(insert_block_cases)] +#[ignore = "trie computation not supported yet for forked mode yet"] fn insert_block_with_fork_provider( #[from(fork_provider)] provider: BlockchainProvider, #[case] block_count: u64, @@ -45,6 +46,7 @@ fn insert_block_with_db_provider( } #[apply(insert_block_cases)] +#[ignore = "trie computation not supported yet for forked mode yet"] fn insert_block_empty_with_fork_provider( #[from(fork_provider)] provider: BlockchainProvider, #[case] block_count: u64, @@ -65,7 +67,7 @@ where Db: BlockProvider + BlockWriter + ReceiptProvider - + StateRootProvider + + StateFactoryProvider + TransactionStatusProvider + TransactionTraceProvider + BlockEnvProvider, @@ -119,7 +121,8 @@ where let actual_block = provider.block(block_id)?; let actual_block_txs = provider.transactions_by_block(block_id)?; let actual_status = provider.block_status(block_id)?; - let actual_state_root = provider.state_root(block_id)?; + let actual_state_root = + provider.historical(block_id)?.map(|s| s.state_root()).transpose()?; let actual_block_tx_count = provider.transaction_count_by_block(block_id)?; let actual_receipts = provider.receipts_by_block(block_id)?; @@ -174,7 +177,7 @@ where Db: BlockProvider + BlockWriter + ReceiptProvider - + StateRootProvider + + StateFactoryProvider + TransactionStatusProvider + TransactionTraceProvider + BlockEnvProvider, @@ -225,7 +228,8 @@ where let actual_block = provider.block(block_id)?; let actual_block_txs = provider.transactions_by_block(block_id)?; let actual_status = provider.block_status(block_id)?; - let actual_state_root = provider.state_root(block_id)?; + let actual_state_root = + provider.historical(block_id)?.map(|s| s.state_root()).transpose()?; let actual_block_tx_count = provider.transaction_count_by_block(block_id)?; let actual_receipts = provider.receipts_by_block(block_id)?; diff --git a/crates/katana/trie/Cargo.toml b/crates/katana/trie/Cargo.toml index 759dab5347..871009cf7f 100644 --- a/crates/katana/trie/Cargo.toml +++ b/crates/katana/trie/Cargo.toml @@ -17,7 +17,7 @@ starknet-types-core.workspace = true thiserror.workspace = true [dependencies.bonsai-trie] +branch = "kariy/public-path" default-features = false features = [ "std" ] -git = "https://github.com/madara-alliance/bonsai-trie/" -rev = "56d7d62" +git = "https://github.com/dojoengine/bonsai-trie/" diff --git a/crates/katana/trie/src/classes.rs b/crates/katana/trie/src/classes.rs new file mode 100644 index 0000000000..f996445ed0 --- /dev/null +++ b/crates/katana/trie/src/classes.rs @@ -0,0 +1,45 @@ +use bonsai_trie::{BonsaiDatabase, BonsaiPersistentDatabase, MultiProof}; +use katana_primitives::block::BlockNumber; +use katana_primitives::class::{ClassHash, CompiledClassHash}; +use katana_primitives::Felt; +use starknet::macros::short_string; +use starknet_types_core::hash::{Poseidon, StarkHash}; + +use crate::id::CommitId; + +#[derive(Debug)] +pub struct ClassesTrie { + trie: crate::BonsaiTrie, +} + +impl ClassesTrie { + const BONSAI_IDENTIFIER: &'static [u8] = b"classes"; + + pub fn new(db: DB) -> Self { + Self { trie: crate::BonsaiTrie::new(db) } + } + + pub fn root(&self) -> Felt { + self.trie.root(Self::BONSAI_IDENTIFIER) + } + + pub fn multiproof(&mut self, class_hashes: Vec) -> MultiProof { + self.trie.multiproof(Self::BONSAI_IDENTIFIER, class_hashes) + } +} + +impl ClassesTrie +where + DB: BonsaiDatabase + BonsaiPersistentDatabase, +{ + pub fn insert(&mut self, hash: ClassHash, compiled_hash: CompiledClassHash) { + // https://docs.starknet.io/architecture-and-concepts/network-architecture/starknet-state/#classes_trie + const CONTRACT_CLASS_LEAF_V0: Felt = short_string!("CONTRACT_CLASS_LEAF_V0"); + let value = Poseidon::hash(&CONTRACT_CLASS_LEAF_V0, &compiled_hash); + self.trie.insert(Self::BONSAI_IDENTIFIER, hash, value) + } + + pub fn commit(&mut self, block: BlockNumber) { + self.trie.commit(block.into()) + } +} diff --git a/crates/katana/trie/src/contracts.rs b/crates/katana/trie/src/contracts.rs new file mode 100644 index 0000000000..3576a89916 --- /dev/null +++ b/crates/katana/trie/src/contracts.rs @@ -0,0 +1,43 @@ +use bonsai_trie::{BonsaiDatabase, BonsaiPersistentDatabase, MultiProof}; +use katana_primitives::block::BlockNumber; +use katana_primitives::{ContractAddress, Felt}; + +use crate::id::CommitId; + +#[derive(Debug)] +pub struct ContractsTrie { + trie: crate::BonsaiTrie, +} + +impl ContractsTrie { + /// NOTE: The identifier value is only relevant if the underlying [`BonsaiDatabase`] + /// implementation is shared across other tries. + const BONSAI_IDENTIFIER: &'static [u8] = b"contracts"; + + pub fn new(db: DB) -> Self { + Self { trie: crate::BonsaiTrie::new(db) } + } + + pub fn root(&self) -> Felt { + self.trie.root(Self::BONSAI_IDENTIFIER) + } + + pub fn multiproof(&mut self, addresses: Vec) -> MultiProof { + let keys = addresses.into_iter().map(Felt::from).collect::>(); + dbg!(&keys); + self.trie.multiproof(Self::BONSAI_IDENTIFIER, keys) + } +} + +impl ContractsTrie +where + DB: BonsaiDatabase + BonsaiPersistentDatabase, +{ + pub fn insert(&mut self, address: ContractAddress, state_hash: Felt) { + self.trie.insert(Self::BONSAI_IDENTIFIER, *address, state_hash) + } + + pub fn commit(&mut self, block: BlockNumber) { + self.trie.commit(block.into()) + } +} diff --git a/crates/katana/trie/src/id.rs b/crates/katana/trie/src/id.rs new file mode 100644 index 0000000000..d7a81aa8c1 --- /dev/null +++ b/crates/katana/trie/src/id.rs @@ -0,0 +1,38 @@ +use bonsai_trie::id::Id; +use bonsai_trie::ByteVec; +use katana_primitives::block::BlockNumber; + +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Default)] +pub struct CommitId(BlockNumber); + +impl CommitId { + pub fn new(block_number: BlockNumber) -> Self { + Self(block_number) + } +} + +impl Id for CommitId { + fn as_u64(self) -> u64 { + self.0 + } + + fn from_u64(v: u64) -> Self { + Self(v) + } + + fn to_bytes(&self) -> ByteVec { + ByteVec::from(&self.0.to_be_bytes() as &[_]) + } +} + +impl From for CommitId { + fn from(value: BlockNumber) -> Self { + Self(value) + } +} + +impl From for BlockNumber { + fn from(value: CommitId) -> Self { + value.0 + } +} diff --git a/crates/katana/trie/src/lib.rs b/crates/katana/trie/src/lib.rs index 1a3e858bd6..49e34ef26d 100644 --- a/crates/katana/trie/src/lib.rs +++ b/crates/katana/trie/src/lib.rs @@ -1,19 +1,79 @@ -use anyhow::Result; +use bitvec::array::BitArray; +use bitvec::order::Msb0; use bitvec::vec::BitVec; -pub use bonsai_trie as bonsai; -use bonsai_trie::id::BasicId; -use bonsai_trie::{BonsaiDatabase, BonsaiPersistentDatabase}; +use bitvec::view::AsBits; +pub use bonsai::{MultiProof, Path, ProofNode}; +pub use bonsai_trie::{BonsaiDatabase, BonsaiPersistentDatabase}; +use bonsai_trie::{BonsaiStorage, BonsaiStorageConfig}; use katana_primitives::class::ClassHash; use katana_primitives::Felt; -use starknet_types_core::hash::{Pedersen, StarkHash}; +use starknet_types_core::hash::{Pedersen, Poseidon, StarkHash}; +pub use {bitvec, bonsai_trie as bonsai}; -/// A helper trait to define a database that can be used as a Bonsai Trie. +mod classes; +mod contracts; +mod id; +mod storages; + +pub use classes::ClassesTrie; +pub use contracts::ContractsTrie; +pub use id::CommitId; +pub use storages::StoragesTrie; + +/// A lightweight shim for [`BonsaiStorage`]. /// -/// Basically a short hand for `BonsaiDatabase + BonsaiPersistentDatabase`. -pub trait BonsaiTrieDb: BonsaiDatabase + BonsaiPersistentDatabase {} -impl BonsaiTrieDb for T where T: BonsaiDatabase + BonsaiPersistentDatabase {} +/// This abstract the Bonsai Trie operations - providing a simplified interface without +/// having to handle how to transform the keys into the internal keys used by the trie. +/// This struct is not meant to be used directly, and instead use the specific tries that have +/// been derived from it, [`ClassesTrie`], [`ContractsTrie`], or [`StoragesTrie`]. +#[derive(Debug)] +pub(crate) struct BonsaiTrie { + storage: BonsaiStorage, +} + +impl BonsaiTrie { + pub fn new(db: DB) -> Self { + let config = BonsaiStorageConfig { + max_saved_trie_logs: Some(usize::MAX), + max_saved_snapshots: Some(usize::MAX), + snapshot_interval: 1, + }; + + Self { storage: BonsaiStorage::new(db, config, 251) } + } +} + +impl BonsaiTrie { + pub fn root(&self, id: &[u8]) -> Felt { + self.storage.root_hash(id).expect("failed to get trie root") + } + + pub fn multiproof(&mut self, id: &[u8], mut keys: Vec) -> MultiProof { + keys.sort(); + let keys = keys + .into_iter() + .map(|key| BitArray::new(key.to_bytes_be())) + .map(|hash| hash.as_bitslice()[5..].to_owned()); + + self.storage.get_multi_proof(id, keys).expect("failed to get multiproof") + } +} + +impl BonsaiTrie +where + DB: BonsaiDatabase + BonsaiPersistentDatabase, +{ + pub fn insert(&mut self, id: &[u8], key: Felt, value: Felt) { + let key: BitVec = key.to_bytes_be().as_bits()[5..].to_owned(); + self.storage.insert(id, &key, &value).unwrap(); + } + + pub fn commit(&mut self, id: CommitId) { + self.storage.commit(id).expect("failed to commit trie"); + } +} -pub fn compute_merkle_root(values: &[Felt]) -> Result +pub fn compute_merkle_root(values: &[Felt]) -> anyhow::Result where H: StarkHash + Send + Sync, { @@ -25,7 +85,7 @@ where let config = BonsaiStorageConfig::default(); let bonsai_db = databases::HashMapDb::::default(); - let mut bs = BonsaiStorage::<_, _, H>::new(bonsai_db, config).unwrap(); + let mut bs = BonsaiStorage::<_, _, H>::new(bonsai_db, config, 64); for (id, value) in values.iter().enumerate() { let key = BitVec::from_iter(id.to_be_bytes()); diff --git a/crates/katana/trie/src/storages.rs b/crates/katana/trie/src/storages.rs new file mode 100644 index 0000000000..20231ba369 --- /dev/null +++ b/crates/katana/trie/src/storages.rs @@ -0,0 +1,47 @@ +use bonsai_trie::{BonsaiDatabase, BonsaiPersistentDatabase, MultiProof}; +use katana_primitives::block::BlockNumber; +use katana_primitives::contract::{StorageKey, StorageValue}; +use katana_primitives::{ContractAddress, Felt}; + +use crate::id::CommitId; + +#[derive(Debug)] +pub struct StoragesTrie { + trie: crate::BonsaiTrie, +} + +impl StoragesTrie { + pub fn new(db: DB) -> Self { + Self { trie: crate::BonsaiTrie::new(db) } + } + + pub fn root(&self, address: ContractAddress) -> Felt { + self.trie.root(&address.to_bytes_be()) + } + + pub fn multiproof( + &mut self, + address: ContractAddress, + storage_keys: Vec, + ) -> MultiProof { + self.trie.multiproof(&address.to_bytes_be(), storage_keys) + } +} + +impl StoragesTrie +where + DB: BonsaiDatabase + BonsaiPersistentDatabase, +{ + pub fn insert( + &mut self, + address: ContractAddress, + storage_key: StorageKey, + storage_value: StorageValue, + ) { + self.trie.insert(&address.to_bytes_be(), storage_key, storage_value) + } + + pub fn commit(&mut self, block: BlockNumber) { + self.trie.commit(block.into()) + } +} diff --git a/crates/saya/core/src/blockchain/mod.rs b/crates/saya/core/src/blockchain/mod.rs index f019b4b617..206f8c181c 100644 --- a/crates/saya/core/src/blockchain/mod.rs +++ b/crates/saya/core/src/blockchain/mod.rs @@ -6,9 +6,7 @@ use katana_provider::providers::db::DbProvider; use katana_provider::traits::block::{BlockProvider, BlockWriter}; use katana_provider::traits::contract::ContractClassWriter; use katana_provider::traits::env::BlockEnvProvider; -use katana_provider::traits::state::{ - StateFactoryProvider, StateProvider, StateRootProvider, StateWriter, -}; +use katana_provider::traits::state::{StateFactoryProvider, StateProvider, StateWriter}; use katana_provider::traits::state_update::StateUpdateProvider; use katana_provider::traits::transaction::{ ReceiptProvider, TransactionProvider, TransactionStatusProvider, TransactionsProviderExt, @@ -25,7 +23,6 @@ pub trait Database: + TransactionsProviderExt + ReceiptProvider + StateUpdateProvider - + StateRootProvider + StateWriter + ContractClassWriter + StateFactoryProvider @@ -44,7 +41,6 @@ impl Database for T where + TransactionsProviderExt + ReceiptProvider + StateUpdateProvider - + StateRootProvider + StateWriter + ContractClassWriter + StateFactoryProvider diff --git a/spawn-and-move-db.tar.gz b/spawn-and-move-db.tar.gz index e8c46c8aa7..8f02dc10d4 100644 Binary files a/spawn-and-move-db.tar.gz and b/spawn-and-move-db.tar.gz differ diff --git a/types-test-db.tar.gz b/types-test-db.tar.gz index 84700bbb69..a6b2f3cd82 100644 Binary files a/types-test-db.tar.gz and b/types-test-db.tar.gz differ