diff --git a/Cargo.lock b/Cargo.lock index e83725c408d..d50ca811c79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,15 @@ dependencies = [ "gimli 0.32.3", ] +[[package]] +name = "addr2line" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59317f77929f0e679d39364702289274de2f0f0b22cbf50b2b8cff2169a0b27a" +dependencies = [ + "gimli 0.33.0", +] + [[package]] name = "adler2" version = "2.0.1" @@ -1985,7 +1994,7 @@ dependencies = [ "bitflags 2.10.0", "cexpr", "clang-sys", - "itertools 0.11.0", + "itertools 0.13.0", "log", "prettyplease 0.2.37", "proc-macro2", @@ -2002,7 +2011,7 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90dbd31c98227229239363921e60fcf5e558e43ec69094d46fc4996f08d1d5bc" dependencies = [ - "bitcoin_hashes 0.13.0", + "bitcoin_hashes 0.14.1", ] [[package]] @@ -2064,6 +2073,15 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + [[package]] name = "bitvec" version = "1.0.1" @@ -2316,9 +2334,12 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +dependencies = [ + "allocator-api2", +] [[package]] name = "byte-slice-cast" @@ -2912,7 +2933,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -3152,6 +3173,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "cpp_demangle" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" +dependencies = [ + "cfg-if", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -3161,13 +3191,52 @@ dependencies = [ "libc", ] +[[package]] +name = "cranelift-assembler-x64" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc822414b18d1f5b1b33ce1441534e311e62fef86ebb5b9d382af857d0272c9" +dependencies = [ + "cranelift-assembler-x64-meta", +] + +[[package]] +name = "cranelift-assembler-x64-meta" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c646808b06f4532478d8d6057d74f15c3322f10d995d9486e7dcea405bf521a" +dependencies = [ + "cranelift-srcgen", +] + [[package]] name = "cranelift-bforest" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1277fbfa94bc82c8ec4af2ded3e639d49ca5f7f3c7eeab2c66accd135ece4e70" dependencies = [ - "cranelift-entity", + "cranelift-entity 0.95.1", +] + +[[package]] +name = "cranelift-bforest" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5996f01a686b2349cdb379083ec5ad3e8cb8767fb2d495d3a4f2ee4163a18d" +dependencies = [ + "cranelift-entity 0.130.2", + "wasmtime-internal-core", +] + +[[package]] +name = "cranelift-bitset" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523fea83273f6a985520f57788809a4de2165794d9ab00fb1254fceb4f5aa00c" +dependencies = [ + "serde", + "serde_derive", + "wasmtime-internal-core", ] [[package]] @@ -3177,17 +3246,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6e8c31ad3b2270e9aeec38723888fe1b0ace3bea2b06b3f749ccf46661d3220" dependencies = [ "bumpalo", - "cranelift-bforest", - "cranelift-codegen-meta", - "cranelift-codegen-shared", - "cranelift-entity", - "cranelift-isle", + "cranelift-bforest 0.95.1", + "cranelift-codegen-meta 0.95.1", + "cranelift-codegen-shared 0.95.1", + "cranelift-entity 0.95.1", + "cranelift-isle 0.95.1", "gimli 0.27.3", "hashbrown 0.13.2", "log", "regalloc2 0.6.1", "smallvec", - "target-lexicon", + "target-lexicon 0.12.16", +] + +[[package]] +name = "cranelift-codegen" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d73d1e372730b5f64ed1a2bd9f01fe4686c8ec14a28034e3084e530c8d951878" +dependencies = [ + "bumpalo", + "cranelift-assembler-x64", + "cranelift-bforest 0.130.2", + "cranelift-bitset", + "cranelift-codegen-meta 0.130.2", + "cranelift-codegen-shared 0.130.2", + "cranelift-control", + "cranelift-entity 0.130.2", + "cranelift-isle 0.130.2", + "gimli 0.33.0", + "hashbrown 0.16.1", + "libm", + "log", + "pulley-interpreter", + "regalloc2 0.15.1", + "rustc-hash 2.1.1", + "serde", + "smallvec", + "target-lexicon 0.13.5", + "wasmtime-internal-core", ] [[package]] @@ -3196,7 +3293,20 @@ version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ac5ac30d62b2d66f12651f6b606dbdfd9c2cfd0908de6b387560a277c5c9da" dependencies = [ - "cranelift-codegen-shared", + "cranelift-codegen-shared 0.95.1", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0319c18165e93dc1ebf78946a8da0b1c341c95b4a39729a69574671639bdb5f" +dependencies = [ + "cranelift-assembler-x64-meta", + "cranelift-codegen-shared 0.130.2", + "cranelift-srcgen", + "heck 0.5.0", + "pulley-interpreter", ] [[package]] @@ -3205,6 +3315,21 @@ version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd82b8b376247834b59ed9bdc0ddeb50f517452827d4a11bccf5937b213748b8" +[[package]] +name = "cranelift-codegen-shared" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9195cd8aeecb55e401aa96b2eaa55921636e8246c127ed7908f7ef7e0d40f270" + +[[package]] +name = "cranelift-control" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8976c2154b74136322befc74222ab5c7249edd7e2604f8cbef2b94975541ffb9" +dependencies = [ + "arbitrary", +] + [[package]] name = "cranelift-entity" version = "0.95.1" @@ -3214,16 +3339,40 @@ dependencies = [ "serde", ] +[[package]] +name = "cranelift-entity" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6038b3147c7982f4951150d5f96c7c06c1e7214b99d4b4a98607aadf8ded89d1" +dependencies = [ + "cranelift-bitset", + "serde", + "serde_derive", + "wasmtime-internal-core", +] + [[package]] name = "cranelift-frontend" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a25d9d0a0ae3079c463c34115ec59507b4707175454f0eee0891e83e30e82d" dependencies = [ - "cranelift-codegen", + "cranelift-codegen 0.95.1", + "log", + "smallvec", + "target-lexicon 0.12.16", +] + +[[package]] +name = "cranelift-frontend" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbd294abe236e23cc3d907b0936226b6a8342db7636daa9c7c72be1e323420e" +dependencies = [ + "cranelift-codegen 0.130.2", "log", "smallvec", - "target-lexicon", + "target-lexicon 0.13.5", ] [[package]] @@ -3232,26 +3381,49 @@ version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80de6a7d0486e4acbd5f9f87ec49912bf4c8fb6aea00087b989685460d4469ba" +[[package]] +name = "cranelift-isle" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a90b6ed3aba84189352a87badeb93b2126d3724225a42dc67fdce53d1b139c" + [[package]] name = "cranelift-native" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb6b03e0e03801c4b3fd8ce0758a94750c07a44e7944cc0ffbf0d3f2e7c79b00" dependencies = [ - "cranelift-codegen", + "cranelift-codegen 0.95.1", + "libc", + "target-lexicon 0.12.16", +] + +[[package]] +name = "cranelift-native" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ec0cc1a54e22925eacf4fc3dc815f907734d3b377899d19d52bec04863e853" +dependencies = [ + "cranelift-codegen 0.130.2", "libc", - "target-lexicon", + "target-lexicon 0.13.5", ] +[[package]] +name = "cranelift-srcgen" +version = "0.130.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "948865622f87f30907bb46fbb081b235ae63c1896a99a83c26a003305c1fa82d" + [[package]] name = "cranelift-wasm" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff3220489a3d928ad91e59dd7aeaa8b3de18afb554a6211213673a71c90737ac" dependencies = [ - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", + "cranelift-codegen 0.95.1", + "cranelift-entity 0.95.1", + "cranelift-frontend 0.95.1", "itertools 0.10.5", "log", "smallvec", @@ -3663,7 +3835,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.114", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", ] [[package]] @@ -4376,7 +4557,7 @@ dependencies = [ "gear-workspace-hack", "hex", "wasmparser 0.230.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmprinter", + "wasmprinter 0.230.0", "wat", ] @@ -4904,6 +5085,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "enum-as-inner" version = "0.5.1" @@ -5095,7 +5285,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5425,6 +5615,7 @@ dependencies = [ "gear-core-processor", "gear-lazy-pages", "gear-runtime-interface", + "gear-sandbox-host", "gear-wasm-instrument", "gear-workspace-hack", "gprimitives", @@ -5432,13 +5623,11 @@ dependencies = [ "log", "parity-scale-codec", "rand 0.8.5", - "scopeguard", "sp-allocator", - "sp-wasm-interface", "thiserror 2.0.17", "tokio", "tracing-subscriber", - "wasmtime", + "wasmtime 43.0.2", "wat", ] @@ -6537,6 +6726,20 @@ dependencies = [ "byteorder", ] +[[package]] +name = "fxprof-processed-profile" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25234f20a3ec0a962a61770cfe39ecf03cb529a6e474ad8cff025ed497eda557" +dependencies = [ + "bitflags 2.10.0", + "debugid", + "rustc-hash 2.1.1", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "galloc" version = "1.10.0" @@ -7141,7 +7344,6 @@ dependencies = [ "gear-sandbox-host", "gear-workspace-hack", "log", - "parity-scale-codec", "sp-runtime-interface", "sp-wasm-interface", ] @@ -7318,7 +7520,7 @@ dependencies = [ "thiserror 2.0.17", "wasm-smith", "wasmparser 0.230.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmprinter", + "wasmprinter 0.230.0", "wat", ] @@ -7336,7 +7538,7 @@ dependencies = [ "wasm-encoder 0.230.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-smith", "wasmparser 0.230.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmprinter", + "wasmprinter 0.230.0", "wat", ] @@ -7417,6 +7619,7 @@ dependencies = [ "alloy-sol-type-parser", "alloy-sol-types", "anyhow", + "arbitrary", "ark-bls12-381", "ark-bls12-381-ext", "ark-ec", @@ -7437,6 +7640,7 @@ dependencies = [ "bp-header-chain", "bp-runtime", "bs58 0.5.1", + "bumpalo", "byte-slice-cast", "bytemuck", "byteorder", @@ -7448,6 +7652,7 @@ dependencies = [ "concurrent-queue", "const-hex", "constant_time_eq 0.4.2", + "cranelift-bitset", "crc32fast", "crossbeam-channel", "crossbeam-epoch", @@ -7479,6 +7684,7 @@ dependencies = [ "event-listener-strategy", "finality-grandpa", "fixed-hash", + "foldhash 0.2.0", "form_urlencoded", "frame-executive", "frame-metadata 16.0.0", @@ -7521,7 +7727,8 @@ dependencies = [ "indexmap 2.13.0", "ipnet", "itertools 0.10.5", - "itertools 0.11.0", + "itertools 0.13.0", + "itertools 0.14.0", "js-sys", "jsonrpsee", "jsonrpsee-client-transport", @@ -7533,6 +7740,7 @@ dependencies = [ "libp2p-identity", "libsecp256k1", "libsecp256k1-core", + "linux-raw-sys 0.11.0", "log", "macro_magic", "memchr", @@ -7590,9 +7798,11 @@ dependencies = [ "parity-wasm", "pbkdf2", "percent-encoding", + "petgraph", "pkcs8", "polkavm-common", "portable-atomic", + "postcard", "ppv-lite86", "predicates 3.1.3", "prettyplease 0.2.37", @@ -7600,6 +7810,7 @@ dependencies = [ "primitive-types 0.13.1", "proc-macro2", "prost 0.12.6", + "pulley-interpreter", "quanta", "quote", "rand 0.8.5", @@ -7700,7 +7911,7 @@ dependencies = [ "subxt-metadata", "syn 1.0.109", "syn 2.0.114", - "target-lexicon", + "target-lexicon 0.12.16", "thiserror 2.0.17", "time", "tiny-keccak", @@ -7725,13 +7936,16 @@ dependencies = [ "unsigned-varint 0.7.2", "unsigned-varint 0.8.0", "url", + "uuid", "wasm-bindgen", "wasm-encoder 0.230.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.13.2", "wasmi 0.38.0", "wasmi_core 0.2.1", "wasmparser 0.230.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmtime", + "wasmparser 0.245.1", + "wasmtime 8.0.1", + "wasmtime-internal-core", "wasmtime-jit", "wasmtime-jit-debug", "wasmtime-runtime", @@ -7873,6 +8087,18 @@ version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" +[[package]] +name = "gimli" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7f043f89559805f8c7cacc432749b2fa0d0a0a9ee46ce47164ed5ba7f126c" +dependencies = [ + "fnv", + "hashbrown 0.16.1", + "indexmap 2.13.0", + "stable_deref_trait", +] + [[package]] name = "git2" version = "0.20.3" @@ -8289,6 +8515,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + [[package]] name = "hashlink" version = "0.8.4" @@ -8703,7 +8935,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2 0.6.1", "tokio", "tower-service", "tracing", @@ -8816,9 +9048,9 @@ dependencies = [ [[package]] name = "id-arena" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "ident_case" @@ -8941,6 +9173,20 @@ dependencies = [ "xmltree", ] +[[package]] +name = "im-rc" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro 0.6.0", + "sized-chunks", + "typenum", + "version_check", +] + [[package]] name = "impl-codec" version = "0.6.0" @@ -9170,7 +9416,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi 0.5.2", "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -9232,9 +9478,9 @@ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "ittapi" -version = "0.3.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a5c0b993601cad796222ea076565c5d9f337d35592f8622c753724f06d7271" +checksum = "6b996fe614c41395cdaedf3cf408a9534851090959d90d54a535f675550b64b1" dependencies = [ "anyhow", "ittapi-sys", @@ -9243,9 +9489,9 @@ dependencies = [ [[package]] name = "ittapi-sys" -version = "0.3.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7b5e473765060536a660eed127f758cf1a810c73e49063264959c60d1727d9" +checksum = "52f5385394064fa2c886205dba02598013ce83d3e92d33dbdc0c52fe0e7bf4fc" dependencies = [ "cc", ] @@ -9594,7 +9840,7 @@ dependencies = [ "region", "wasmer", "wasmi 0.38.0", - "wasmprinter", + "wasmprinter 0.230.0", "wat", ] @@ -9690,9 +9936,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libmimalloc-sys" @@ -11153,7 +11399,7 @@ dependencies = [ "metrics", "quanta", "rand 0.9.2", - "rand_xoshiro", + "rand_xoshiro 0.7.0", "sketches-ddsketch", ] @@ -11697,7 +11943,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9224be3459a0c1d6e9b0f42ab0e76e98b29aef5aba33c0487dfcf47ea08b5150" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 1.0.109", @@ -11709,7 +11955,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -11895,6 +12141,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "object" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271638cd5fa9cca89c4c304675ca658efc4e64a66c716b7cfe1afb4b9611dbbc" +dependencies = [ + "crc32fast", + "hashbrown 0.16.1", + "indexmap 2.13.0", + "memchr", +] + [[package]] name = "oid-registry" version = "0.6.1" @@ -13985,7 +14243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", - "heck 0.4.1", + "heck 0.5.0", "itertools 0.12.1", "log", "multimap 0.10.1", @@ -14094,14 +14352,26 @@ dependencies = [ ] [[package]] -name = "pulldown-cmark" -version = "0.8.0" +name = "pulley-interpreter" +version = "43.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" +checksum = "7ec12fe19a9588315a49fe5704502a9c02d6a198303314b0c7c86123b06d29e5" dependencies = [ - "bitflags 1.3.2", - "memchr", - "unicase", + "cranelift-bitset", + "log", + "pulley-macros", + "wasmtime-internal-core", +] + +[[package]] +name = "pulley-macros" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f7d5ef31ebf1b46cd7e722ffef934e670d7e462f49aa01cde07b9b76dca580" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", ] [[package]] @@ -14220,7 +14490,7 @@ dependencies = [ "quinn-udp 0.5.14", "rustc-hash 2.1.1", "rustls 0.23.36", - "socket2 0.5.10", + "socket2 0.6.1", "thiserror 2.0.17", "tokio", "tracing", @@ -14319,9 +14589,9 @@ dependencies = [ "cfg_aliases 0.2.1", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.1", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -14444,6 +14714,15 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "rand_xoshiro" version = "0.7.0" @@ -14605,6 +14884,20 @@ dependencies = [ "smallvec", ] +[[package]] +name = "regalloc2" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de2c52737737f8609e94f975dee22854a2d5c125772d4b1cf292120f4d45c186" +dependencies = [ + "allocator-api2", + "bumpalo", + "hashbrown 0.17.0", + "log", + "rustc-hash 2.1.1", + "smallvec", +] + [[package]] name = "regex" version = "1.12.2" @@ -15082,7 +15375,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -15095,7 +15388,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -15198,7 +15491,7 @@ dependencies = [ "security-framework 3.5.1", "security-framework-sys", "webpki-root-certs 0.26.11", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -15219,7 +15512,7 @@ dependencies = [ "security-framework 3.5.1", "security-framework-sys", "webpki-root-certs 1.0.5", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -15742,7 +16035,7 @@ dependencies = [ "sp-allocator", "sp-runtime-interface", "sp-wasm-interface", - "wasmtime", + "wasmtime 8.0.1", ] [[package]] @@ -16952,10 +17245,23 @@ dependencies = [ ] [[package]] -name = "serdect" -version = "0.2.0" +name = "serde_yaml" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.13.0", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ "base16ct", "serde", @@ -17140,6 +17446,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + [[package]] name = "sketches-ddsketch" version = "0.3.0" @@ -18071,7 +18387,7 @@ dependencies = [ "parity-scale-codec", "sp-allocator", "sp-wasm-interface-common", - "wasmtime", + "wasmtime 8.0.1", ] [[package]] @@ -18799,6 +19115,12 @@ version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + [[package]] name = "target-triple" version = "1.0.0" @@ -18815,7 +19137,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix 1.1.3", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -19711,6 +20033,12 @@ dependencies = [ "subtle 2.6.1", ] +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "unsigned-varint" version = "0.7.2" @@ -20087,6 +20415,27 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-compose" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd23d12cc95c451c1306db5bc63075fbebb612bb70c53b4237b1ce5bc178343" +dependencies = [ + "anyhow", + "heck 0.5.0", + "im-rc", + "indexmap 2.13.0", + "log", + "petgraph", + "serde", + "serde_derive", + "serde_yaml", + "smallvec", + "wasm-encoder 0.245.1", + "wasmparser 0.245.1", + "wat", +] + [[package]] name = "wasm-encoder" version = "0.230.0" @@ -20108,12 +20457,22 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.244.0" +version = "0.245.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +checksum = "3f9dca005e69bf015e45577e415b9af8c67e8ee3c0e38b5b0add5aa92581ed5c" dependencies = [ "leb128fmt", - "wasmparser 0.244.0", + "wasmparser 0.245.1", +] + +[[package]] +name = "wasm-encoder" +version = "0.246.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61fb705ce81adde29d2a8e99d87995e39a6e927358c91398f374474746070ef7" +dependencies = [ + "leb128fmt", + "wasmparser 0.246.2", ] [[package]] @@ -20223,7 +20582,7 @@ dependencies = [ "serde-wasm-bindgen", "shared-buffer", "tar", - "target-lexicon", + "target-lexicon 0.12.16", "thiserror 1.0.69", "tracing", "wasm-bindgen", @@ -20269,7 +20628,7 @@ dependencies = [ "self_cell", "shared-buffer", "smallvec", - "target-lexicon", + "target-lexicon 0.12.16", "thiserror 1.0.69", "wasmer-types", "wasmer-vm", @@ -20323,7 +20682,7 @@ dependencies = [ "more-asserts", "rkyv", "sha2 0.10.9", - "target-lexicon", + "target-lexicon 0.12.16", "thiserror 1.0.69", "xxhash-rust", ] @@ -20526,9 +20885,22 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.244.0" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" +dependencies = [ + "bitflags 2.10.0", + "hashbrown 0.16.1", + "indexmap 2.13.0", + "semver 1.0.27", + "serde", +] + +[[package]] +name = "wasmparser" +version = "0.246.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +checksum = "71cde4757396defafd25417cfb36aa3161027d06d865b0c24baaae229aac005d" dependencies = [ "bitflags 2.10.0", "indexmap 2.13.0", @@ -20555,6 +20927,17 @@ dependencies = [ "wasmparser 0.230.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wasmprinter" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41517a3716fbb8ccf46daa9c1325f760fcbff5168e75c7392288e410b91ac8" +dependencies = [ + "anyhow", + "termcolor", + "wasmparser 0.245.1", +] + [[package]] name = "wasmtime" version = "8.0.1" @@ -20562,7 +20945,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f907fdead3153cb9bfb7a93bbd5b62629472dc06dee83605358c64c52ed3dda9" dependencies = [ "anyhow", - "async-trait", "bincode", "cfg-if", "indexmap 1.9.3", @@ -20574,19 +20956,69 @@ dependencies = [ "psm", "rayon", "serde", - "target-lexicon", + "target-lexicon 0.12.16", "wasmparser 0.102.0", "wasmtime-cache", - "wasmtime-component-macro", "wasmtime-cranelift", - "wasmtime-environ", - "wasmtime-fiber", + "wasmtime-environ 8.0.1", "wasmtime-jit", "wasmtime-runtime", - "wat", "windows-sys 0.45.0", ] +[[package]] +name = "wasmtime" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb1ed5899dde98357cfdcf647a4614498798719793898245b4b34e663addabf" +dependencies = [ + "addr2line 0.26.1", + "async-trait", + "bitflags 2.10.0", + "bumpalo", + "cc", + "cfg-if", + "encoding_rs", + "futures", + "fxprof-processed-profile", + "gimli 0.33.0", + "ittapi", + "libc", + "log", + "mach2", + "memfd", + "object 0.38.1", + "once_cell", + "postcard", + "pulley-interpreter", + "rayon", + "rustix 1.1.3", + "semver 1.0.27", + "serde", + "serde_derive", + "serde_json", + "smallvec", + "target-lexicon 0.13.5", + "tempfile", + "wasm-compose", + "wasm-encoder 0.245.1", + "wasmparser 0.245.1", + "wasmtime-environ 43.0.2", + "wasmtime-internal-cache", + "wasmtime-internal-component-macro", + "wasmtime-internal-component-util", + "wasmtime-internal-core", + "wasmtime-internal-cranelift", + "wasmtime-internal-fiber", + "wasmtime-internal-jit-debug", + "wasmtime-internal-jit-icache-coherence", + "wasmtime-internal-unwinder", + "wasmtime-internal-versioned-export-macros", + "wasmtime-internal-winch", + "wat", + "windows-sys 0.61.2", +] + [[package]] name = "wasmtime-asm-macros" version = "8.0.1" @@ -20616,27 +21048,6 @@ dependencies = [ "zstd 0.11.2+zstd.1.5.2", ] -[[package]] -name = "wasmtime-component-macro" -version = "8.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267096ed7cc93b4ab15d3daa4f195e04dbb7e71c7e5c6457ae7d52e9dd9c3607" -dependencies = [ - "anyhow", - "proc-macro2", - "quote", - "syn 1.0.109", - "wasmtime-component-util", - "wasmtime-wit-bindgen", - "wit-parser", -] - -[[package]] -name = "wasmtime-component-util" -version = "8.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e02ca7a4a3c69d72b88f26f0192e333958df6892415ac9ab84dcc42c9000c2" - [[package]] name = "wasmtime-cranelift" version = "8.0.1" @@ -20644,19 +21055,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1cefde0cce8cb700b1b21b6298a3837dba46521affd7b8c38a9ee2c869eee04" dependencies = [ "anyhow", - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", - "cranelift-native", + "cranelift-codegen 0.95.1", + "cranelift-entity 0.95.1", + "cranelift-frontend 0.95.1", + "cranelift-native 0.95.1", "cranelift-wasm", "gimli 0.27.3", "log", "object 0.30.4", - "target-lexicon", + "target-lexicon 0.12.16", "thiserror 1.0.69", "wasmparser 0.102.0", "wasmtime-cranelift-shared", - "wasmtime-environ", + "wasmtime-environ 8.0.1", ] [[package]] @@ -20666,12 +21077,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd041e382ef5aea1b9fc78442394f1a4f6d676ce457e7076ca4cb3f397882f8b" dependencies = [ "anyhow", - "cranelift-codegen", - "cranelift-native", + "cranelift-codegen 0.95.1", + "cranelift-native 0.95.1", "gimli 0.27.3", "object 0.30.4", - "target-lexicon", - "wasmtime-environ", + "target-lexicon 0.12.16", + "wasmtime-environ 8.0.1", ] [[package]] @@ -20681,29 +21092,220 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a990198cee4197423045235bf89d3359e69bd2ea031005f4c2d901125955c949" dependencies = [ "anyhow", - "cranelift-entity", + "cranelift-entity 0.95.1", "gimli 0.27.3", "indexmap 1.9.3", "log", "object 0.30.4", "serde", - "target-lexicon", + "target-lexicon 0.12.16", "thiserror 1.0.69", "wasmparser 0.102.0", "wasmtime-types", ] [[package]] -name = "wasmtime-fiber" -version = "8.0.1" +name = "wasmtime-environ" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4172382dcc785c31d0e862c6780a18f5dd437914d22c4691351f965ef751c821" +dependencies = [ + "anyhow", + "cpp_demangle 0.4.5", + "cranelift-bforest 0.130.2", + "cranelift-bitset", + "cranelift-entity 0.130.2", + "gimli 0.33.0", + "hashbrown 0.16.1", + "indexmap 2.13.0", + "log", + "object 0.38.1", + "postcard", + "rustc-demangle", + "semver 1.0.27", + "serde", + "serde_derive", + "sha2 0.10.9", + "smallvec", + "target-lexicon 0.13.5", + "wasm-encoder 0.245.1", + "wasmparser 0.245.1", + "wasmprinter 0.245.1", + "wasmtime-internal-component-util", + "wasmtime-internal-core", +] + +[[package]] +name = "wasmtime-internal-cache" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ed398988226d7aa0505ac6bb576e09532ad722d702ec4e66365d78ed695c95f" +dependencies = [ + "base64 0.22.1", + "directories-next", + "log", + "postcard", + "rustix 1.1.3", + "serde", + "serde_derive", + "sha2 0.10.9", + "toml 0.9.11+spec-1.1.0", + "wasmtime-environ 43.0.2", + "windows-sys 0.61.2", + "zstd 0.13.3", +] + +[[package]] +name = "wasmtime-internal-component-macro" +version = "43.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab182d5ab6273a133ab88db94d8ca86dc3e57e43d70baaa4d98f94ddbd7d10a" +checksum = "ae5ec9fff073ff13b81732d56a9515d761c245750bcda09093827f84130ebc25" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn 2.0.114", + "wasmtime-internal-component-util", + "wasmtime-internal-wit-bindgen", + "wit-parser", +] + +[[package]] +name = "wasmtime-internal-component-util" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "935d9ab293ba27d1ec9aa7bc1b3a43993dbe961af2a8f23f90a11e1331b4c13f" + +[[package]] +name = "wasmtime-internal-core" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3820b174f477d2a7083209d1ad5353fcdb11eaea434b2137b8681029460dd3" +dependencies = [ + "anyhow", + "hashbrown 0.16.1", + "libm", + "serde", +] + +[[package]] +name = "wasmtime-internal-cranelift" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1679d205caf9766c6aa309d45bb3e7c634d7725e3164404df33824b9f7c4fb7" +dependencies = [ + "cfg-if", + "cranelift-codegen 0.130.2", + "cranelift-control", + "cranelift-entity 0.130.2", + "cranelift-frontend 0.130.2", + "cranelift-native 0.130.2", + "gimli 0.33.0", + "itertools 0.14.0", + "log", + "object 0.38.1", + "pulley-interpreter", + "smallvec", + "target-lexicon 0.13.5", + "thiserror 2.0.17", + "wasmparser 0.245.1", + "wasmtime-environ 43.0.2", + "wasmtime-internal-core", + "wasmtime-internal-unwinder", + "wasmtime-internal-versioned-export-macros", +] + +[[package]] +name = "wasmtime-internal-fiber" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e505254058be5b0df458d670ee42d9eafe2349d04c1296e9dc01071dc20a85" dependencies = [ "cc", "cfg-if", - "rustix 0.36.17", - "wasmtime-asm-macros", - "windows-sys 0.45.0", + "libc", + "rustix 1.1.3", + "wasmtime-environ 43.0.2", + "wasmtime-internal-versioned-export-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "wasmtime-internal-jit-debug" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c2e05b345f1773e59c20e6ad7298fd6857cdea245023d88bb659c96d8f0ea72" +dependencies = [ + "cc", + "object 0.38.1", + "rustix 1.1.3", + "wasmtime-internal-versioned-export-macros", +] + +[[package]] +name = "wasmtime-internal-jit-icache-coherence" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b86701b234a4643e3f111869aa792b3a05a06e02d486ee9cb6c04dae16b52dab" +dependencies = [ + "cfg-if", + "libc", + "wasmtime-internal-core", + "windows-sys 0.61.2", +] + +[[package]] +name = "wasmtime-internal-unwinder" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63558d801beb83dde9b336eb4ae049019aee26627926edb32cd119d7e4c83cd" +dependencies = [ + "cfg-if", + "cranelift-codegen 0.130.2", + "log", + "object 0.38.1", + "wasmtime-environ 43.0.2", +] + +[[package]] +name = "wasmtime-internal-versioned-export-macros" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "737c4d956fc3a848541a064afb683dd2771132a6b125be5baaf95c4379aa47df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "wasmtime-internal-winch" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f599b79545e3bba0b7913406055ebede5bb0dabee9ba2015ef25a9f4c9f47807" +dependencies = [ + "cranelift-codegen 0.130.2", + "gimli 0.33.0", + "log", + "object 0.38.1", + "target-lexicon 0.13.5", + "wasmparser 0.245.1", + "wasmtime-environ 43.0.2", + "wasmtime-internal-cranelift", + "winch-codegen", +] + +[[package]] +name = "wasmtime-internal-wit-bindgen" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2192a77a00b9a67800c2b4e1c70fb6abca79d6b529e53a2ef9dcdcc36090330d" +dependencies = [ + "anyhow", + "bitflags 2.10.0", + "heck 0.5.0", + "indexmap 2.13.0", + "wit-parser", ] [[package]] @@ -20716,15 +21318,14 @@ dependencies = [ "anyhow", "bincode", "cfg-if", - "cpp_demangle", + "cpp_demangle 0.3.5", "gimli 0.27.3", - "ittapi", "log", "object 0.30.4", "rustc-demangle", "serde", - "target-lexicon", - "wasmtime-environ", + "target-lexicon 0.12.16", + "wasmtime-environ 8.0.1", "wasmtime-jit-debug", "wasmtime-jit-icache-coherence", "wasmtime-runtime", @@ -20772,8 +21373,7 @@ dependencies = [ "rand 0.8.5", "rustix 0.36.17", "wasmtime-asm-macros", - "wasmtime-environ", - "wasmtime-fiber", + "wasmtime-environ 8.0.1", "wasmtime-jit-debug", "windows-sys 0.45.0", ] @@ -20784,23 +21384,12 @@ version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4f6fffd2a1011887d57f07654dd112791e872e3ff4a2e626aee8059ee17f06f" dependencies = [ - "cranelift-entity", + "cranelift-entity 0.95.1", "serde", "thiserror 1.0.69", "wasmparser 0.102.0", ] -[[package]] -name = "wasmtime-wit-bindgen" -version = "8.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "983db9cc294d1adaa892a53ff6a0dc6605fc0ab1a4da5d8a2d2d4bde871ff7dd" -dependencies = [ - "anyhow", - "heck 0.4.1", - "wit-parser", -] - [[package]] name = "wasmtimer" version = "0.4.3" @@ -20817,22 +21406,22 @@ dependencies = [ [[package]] name = "wast" -version = "244.0.0" +version = "246.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e7b9f9e23311275920e3d6b56d64137c160cf8af4f84a7283b36cfecbf4acb" +checksum = "fe3fe8e3bf88ad96d031b4181ddbd64634b17cb0d06dfc3de589ef43591a9a62" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width 0.2.2", - "wasm-encoder 0.244.0", + "wasm-encoder 0.246.2", ] [[package]] name = "wat" -version = "1.244.0" +version = "1.246.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf35b87ed352f9ab6cd0732abde5a67dd6153dfd02c493e61459218b19456fa" +checksum = "4bd7fda1199b94fff395c2d19a153f05dbe7807630316fa9673367666fd2ad8c" dependencies = [ "wast", ] @@ -20959,7 +21548,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -20968,6 +21557,25 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winch-codegen" +version = "43.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52dbb0cf07b0dfe7b7a1ca8efb8f94ba98bd0fb144c411ea1665c78f0449e958" +dependencies = [ + "cranelift-assembler-x64", + "cranelift-codegen 0.130.2", + "gimli 0.33.0", + "regalloc2 0.15.1", + "smallvec", + "target-lexicon 0.13.5", + "thiserror 2.0.17", + "wasmparser 0.245.1", + "wasmtime-environ 43.0.2", + "wasmtime-internal-core", + "wasmtime-internal-cranelift", +] + [[package]] name = "windows" version = "0.53.0" @@ -21415,17 +22023,21 @@ checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "wit-parser" -version = "0.6.4" +version = "0.245.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f887c3da527a51b321076ebe6a7513026a4757b6d4d144259946552d6fc728b3" +checksum = "330698718e82983499419494dd1e3d7811a457a9bf9f69734e8c5f07a2547929" dependencies = [ "anyhow", + "hashbrown 0.16.1", "id-arena", - "indexmap 1.9.3", + "indexmap 2.13.0", "log", - "pulldown-cmark", + "semver 1.0.27", + "serde", + "serde_derive", + "serde_json", "unicode-xid", - "url", + "wasmparser 0.245.1", ] [[package]] @@ -21749,6 +22361,15 @@ dependencies = [ "zstd-safe 6.0.6", ] +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe 7.2.4", +] + [[package]] name = "zstd-safe" version = "5.0.2+zstd.1.5.2" @@ -21769,6 +22390,15 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.0.16+zstd.1.5.7" diff --git a/ethexe/processor/Cargo.toml b/ethexe/processor/Cargo.toml index 7977476ddc6..ac31a236db6 100644 --- a/ethexe/processor/Cargo.toml +++ b/ethexe/processor/Cargo.toml @@ -14,25 +14,24 @@ ethexe-runtime-common = { workspace = true, features = ["std"] } ethexe-runtime = { workspace = true, features = ["std"] } gear-core.workspace = true gprimitives = { workspace = true, features = ["std"] } -gear-runtime-interface = { workspace = true, features = ["std"] } +gear-runtime-interface = { workspace = true, default-features = false, features = ["std"] } +gear-sandbox-host.workspace = true gear-lazy-pages.workspace = true gear-wasm-instrument = { workspace = true, features = ["std"] } core-processor.workspace = true futures.workspace = true thiserror.workspace = true -wasmtime.workspace = true +wasmtime = "43.0.1" log.workspace = true parity-scale-codec = { workspace = true, features = ["std", "derive"] } sp-allocator = { workspace = true, features = ["std"] } -sp-wasm-interface = { workspace = true, features = ["std", "wasmtime"] } tokio = { workspace = true, features = ["full"] } crossbeam = { workspace = true, features = ["crossbeam-channel"] } itertools = { workspace = true, features = ["use_std"] } gear-workspace-hack.workspace = true anyhow.workspace = true derive_more.workspace = true -scopeguard.workspace = true [dev-dependencies] anyhow.workspace = true diff --git a/ethexe/processor/src/handling/run/chunk_execution_spawn.rs b/ethexe/processor/src/handling/run/chunk_execution_spawn.rs index eaa3d671141..0ab110cacca 100644 --- a/ethexe/processor/src/handling/run/chunk_execution_spawn.rs +++ b/ethexe/processor/src/handling/run/chunk_execution_spawn.rs @@ -58,11 +58,9 @@ pub async fn spawn_chunk_execution( .map(|(program_id, state_hash)| { let (instrumented_code, code_metadata) = ctx.program_code(program_id)?; let mut executor = ctx.inner().instance_creator.instantiate()?; - let db = ctx.inner().db.cas().clone_boxed(); let promise_out_tx = ctx.inner().promise_out_tx.clone(); Ok(thread_pool::spawn(move || { let (jn, new_state_hash, gas_spent) = executor.run( - db, ProcessQueueContext { program_id, state_root: state_hash, diff --git a/ethexe/processor/src/handling/run/mod.rs b/ethexe/processor/src/handling/run/mod.rs index d80c8300c75..d7babdcf3ce 100644 --- a/ethexe/processor/src/handling/run/mod.rs +++ b/ethexe/processor/src/handling/run/mod.rs @@ -498,10 +498,10 @@ mod tests { .collect(); let transitions = InBlockTransitions::new(0, states, Default::default()); - + let db = Database::memory(); let mut ctx = CommonRunContext::new( - Database::memory(), - InstanceCreator::new(host::runtime()).unwrap(), + db.clone(), + InstanceCreator::new(db.clone(), host::runtime()).unwrap(), transitions, 1_000_000, CHUNK_PROCESSING_THREADS, @@ -662,7 +662,7 @@ mod tests { in_block_transitions, 100, 16, - InstanceCreator::new(host::runtime()).unwrap(), + InstanceCreator::new(db.clone(), host::runtime()).unwrap(), BlockHeader::dummy(3), ); access_state( diff --git a/ethexe/processor/src/host/api/allocator.rs b/ethexe/processor/src/host/api/allocator.rs index fb351919a64..51a24befe00 100644 --- a/ethexe/processor/src/host/api/allocator.rs +++ b/ethexe/processor/src/host/api/allocator.rs @@ -16,8 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::host::context::HostContext; -use sp_wasm_interface::{FunctionContext, IntoValue, Pointer, StoreData}; +use crate::host::{StoreData, context}; use wasmtime::{Caller, Linker}; pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { @@ -27,21 +26,10 @@ pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { Ok(()) } -fn free(caller: Caller<'_, StoreData>, ptr: i32) { - let mut host_context = HostContext { caller }; - - host_context - .deallocate_memory(Pointer::::new(ptr as _)) - .unwrap(); +fn free(caller: Caller<'_, StoreData>, ptr: u32) { + context::allocator(caller).deallocate(ptr).unwrap() } -fn malloc(caller: Caller<'_, StoreData>, size: i32) -> i32 { - let mut host_context = HostContext { caller }; - - host_context - .allocate_memory(size as _) - .unwrap() - .into_value() - .as_i32() - .unwrap() +fn malloc(caller: Caller<'_, StoreData>, size: u32) -> u32 { + context::allocator(caller).allocate(size).unwrap() } diff --git a/ethexe/processor/src/host/api/database.rs b/ethexe/processor/src/host/api/database.rs index 3a364dda76b..55a704462c3 100644 --- a/ethexe/processor/src/host/api/database.rs +++ b/ethexe/processor/src/host/api/database.rs @@ -16,9 +16,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::host::{api::MemoryWrap, threads}; +use crate::host::{StoreData, context, threads}; use gprimitives::H256; -use sp_wasm_interface::StoreData; use wasmtime::{Caller, Linker}; pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { @@ -32,26 +31,21 @@ pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { fn update_state_hash(caller: Caller<'_, StoreData>, program_state_hash_ptr: i32) { log::trace!(target: "host_call", "update_state_hash(program_state_hash={program_state_hash_ptr:?})"); - let memory = MemoryWrap(caller.data().memory()); - - let hash_slice = memory.slice(&caller, program_state_hash_ptr as usize, size_of::()); - let program_state_hash = H256::from_slice(hash_slice); + let program_state_hash = + context::memory(caller).decode(program_state_hash_ptr as usize, size_of::()); threads::update_state_hash(program_state_hash); } -fn read_by_hash(caller: Caller<'_, StoreData>, hash_ptr: i32) -> i64 { +fn read_by_hash(mut caller: Caller<'_, StoreData>, hash_ptr: i32) -> i64 { log::trace!(target: "host_call", "read_by_hash(hash_ptr={hash_ptr:?})"); - let memory = MemoryWrap(caller.data().memory()); - - let hash_slice = memory.slice(&caller, hash_ptr as usize, size_of::()); - let hash = H256::from_slice(hash_slice); + let hash = context::memory(&mut caller).decode(hash_ptr as usize, size_of::()); - let maybe_data = threads::with_db(|db| db.read(hash)); + let maybe_data = caller.data().db.read(hash); let res = maybe_data - .map(|data| super::allocate_and_write_raw(caller, data).1) + .map(|data| super::allocate_and_write_raw(caller, data)) .unwrap_or(0); log::trace!(target: "host_call", "read_by_hash(..) -> {res:?}"); @@ -59,16 +53,15 @@ fn read_by_hash(caller: Caller<'_, StoreData>, hash_ptr: i32) -> i64 { res } -fn write(caller: Caller<'_, StoreData>, ptr: i32, len: i32) -> i32 { +fn write(mut caller: Caller<'_, StoreData>, ptr: i32, len: i32) -> i32 { log::trace!(target: "host_call", "write(ptr={ptr:?}, len={len:?})"); - let memory = MemoryWrap(caller.data().memory()); - - let data = memory.slice(&caller, ptr as usize, len as usize); - - let hash = threads::with_db(|db| db.write(data)); + let db = caller.data().db.clone_boxed(); + let memory = context::memory(&mut caller); + let data = memory.slice(ptr as usize, len as usize); + let hash = db.write(data); - let (_caller, res) = super::allocate_and_write(caller, hash); + let res = super::allocate_and_write(caller, hash); // This extracts first bytes (ptr). let res = res as i32; diff --git a/ethexe/processor/src/host/api/lazy_pages.rs b/ethexe/processor/src/host/api/lazy_pages.rs index 2593fd318f5..fc7ee767ea4 100644 --- a/ethexe/processor/src/host/api/lazy_pages.rs +++ b/ethexe/processor/src/host/api/lazy_pages.rs @@ -18,10 +18,9 @@ // TODO (breathx): remove cloning of slices from wasm memory (unsafe casts). -use crate::host::{api::MemoryWrap, threads::EthexeHostLazyPages}; +use crate::host::{StoreData, context, threads::EthexeHostLazyPages}; use gear_lazy_pages::LazyPagesVersion; use gear_runtime_interface::{LazyPagesInitContext, lazy_pages_detail}; -use sp_wasm_interface::StoreData; use wasmtime::{Caller, Linker}; pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { @@ -67,11 +66,9 @@ pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { fn change_wasm_memory_addr_and_size(caller: Caller<'_, StoreData>, addr: i64, size: i64) { log::trace!(target: "host_call", "change_wasm_memory_addr_and_size(addr={addr:?}, size={size:?})"); - let memory = MemoryWrap(caller.data().memory()); - - let addr = memory.decode_by_val(&caller, addr); - - let size = memory.decode_by_val(&caller, size); + let memory = context::memory(caller); + let addr = memory.decode_by_val(addr); + let size = memory.decode_by_val(size); lazy_pages_detail::change_wasm_memory_addr_and_size(addr, size); } @@ -79,9 +76,7 @@ fn change_wasm_memory_addr_and_size(caller: Caller<'_, StoreData>, addr: i64, si fn init_lazy_pages(caller: Caller<'_, StoreData>, ctx: i64) -> i32 { log::trace!(target: "host_call", "init_lazy_pages(ctx={ctx:?})"); - let memory = MemoryWrap(caller.data().memory()); - - let ctx: LazyPagesInitContext = memory.decode_by_val(&caller, ctx); + let ctx: LazyPagesInitContext = context::memory(caller).decode_by_val(ctx); gear_lazy_pages::init(LazyPagesVersion::Version1, ctx.into(), EthexeHostLazyPages) .map_err(|err| log::error!("Cannot initialize lazy-pages: {err}")) @@ -91,9 +86,7 @@ fn init_lazy_pages(caller: Caller<'_, StoreData>, ctx: i64) -> i32 { fn init_lazy_pages_for_program(caller: Caller<'_, StoreData>, ctx: i64) { log::trace!(target: "host_call", "init_lazy_pages_for_program(ctx={ctx:?})"); - let memory = MemoryWrap(caller.data().memory()); - - let ctx = memory.decode_by_val(&caller, ctx); + let ctx = context::memory(caller).decode_by_val(ctx); lazy_pages_detail::init_lazy_pages_for_program(ctx); } @@ -103,7 +96,7 @@ fn lazy_pages_status(caller: Caller<'_, StoreData>) -> i64 { let status = lazy_pages_detail::lazy_pages_status(); - let (_caller, res) = super::allocate_and_write(caller, status); + let res = super::allocate_and_write(caller, status); log::trace!(target: "host_call", "lazy_pages_status(..) -> {res:?}"); @@ -124,28 +117,21 @@ fn pre_process_memory_accesses( ) -> i32 { log::trace!(target: "host_call", "pre_process_memory_accesses(reads={reads:?}, writes={writes:?}, gas_bytes={gas_bytes:?})"); - let memory = MemoryWrap(caller.data().memory()); - - let reads = memory.slice_by_val(&caller, reads); - - let writes = memory.slice_by_val(&caller, writes); + let mut memory = context::memory(&mut caller); + let reads = memory.slice_by_val(reads); + let writes = memory.slice_by_val(writes); // 8 len bytes of u64 counter. // read gas_bytes into `mut` variable because `pre_process_memory_accesses` updates // it, then write updated slice to memory. Can't use `slice_mut` here without using `.to_vec()` // on `writes` and `reads`. - let mut gas_counter: u64 = u64::from_le_bytes( - memory - .slice(&caller, gas_bytes as usize, 8) - .try_into() - .unwrap(), - ); + let mut gas_counter: u64 = u64::from_le_bytes(memory.array::<8>(gas_bytes as usize)); let res = lazy_pages_detail::pre_process_memory_accesses(reads, writes, &mut gas_counter) as i32; memory - .slice_mut(&mut caller, gas_bytes as usize, 8) + .slice_mut(gas_bytes as usize, 8) .copy_from_slice(&gas_counter.to_le_bytes()); log::trace!(target: "host_call", "pre_process_memory_accesses(..) -> {res:?}"); @@ -157,7 +143,7 @@ fn write_accessed_pages(caller: Caller<'_, StoreData>) -> i64 { let pages = lazy_pages_detail::write_accessed_pages(); - let (_caller, res) = super::allocate_and_write(caller, pages); + let res = super::allocate_and_write(caller, pages); log::trace!(target: "host_call", "write_accessed_pages(..) -> {res:?}"); diff --git a/ethexe/processor/src/host/api/logging.rs b/ethexe/processor/src/host/api/logging.rs index f2be56262b7..65e4207af7f 100644 --- a/ethexe/processor/src/host/api/logging.rs +++ b/ethexe/processor/src/host/api/logging.rs @@ -16,9 +16,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use super::MemoryWrap; +use crate::host::{StoreData, context}; use log::Level; -use sp_wasm_interface::StoreData; use wasmtime::{Caller, Linker}; pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { @@ -39,12 +38,12 @@ fn log(caller: Caller<'_, StoreData>, level: i32, target: i64, message: i64) { _ => Level::Trace, }; - let memory = MemoryWrap(caller.data().memory()); + let memory = context::memory(caller); - let target = memory.slice_by_val(&caller, target); + let target = memory.slice_by_val(target); let target = core::str::from_utf8(target).unwrap_or_default(); - let message = memory.slice_by_val(&caller, message); + let message = memory.slice_by_val(message); let message = core::str::from_utf8(message).unwrap_or_default(); log::log!(target: target, level, "{message}"); diff --git a/ethexe/processor/src/host/api/mod.rs b/ethexe/processor/src/host/api/mod.rs index 793f2e8b9e5..3534dbe1475 100644 --- a/ethexe/processor/src/host/api/mod.rs +++ b/ethexe/processor/src/host/api/mod.rs @@ -16,11 +16,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use super::context::HostContext; -use ethexe_runtime_common::{pack_u32_to_i64, unpack_i64_to_u32}; -use parity_scale_codec::{Decode, Encode}; -use sp_wasm_interface::{FunctionContext as _, IntoValue as _, StoreData}; -use wasmtime::{Caller, Memory, StoreContext, StoreContextMut}; +use crate::host::{StoreData, context}; +use ethexe_runtime_common::pack_u32_to_i64; +use parity_scale_codec::Encode; +use wasmtime::StoreContextMut; pub mod allocator; pub mod database; @@ -29,99 +28,26 @@ pub mod logging; pub mod promise; pub mod sandbox; -pub struct MemoryWrap(Memory); - -// TODO: return results for mem accesses. -impl MemoryWrap { - pub fn decode_by_val<'a, T: 'a, D: Decode>( - &self, - store: impl Into>, - ptr_len: i64, - ) -> D { - let mut slice = self.slice_by_val(store, ptr_len); - - D::decode(&mut slice).unwrap() - } - - #[allow(unused)] - pub fn decode<'a, T: 'a, D: Decode>( - &self, - store: impl Into>, - ptr: usize, - len: usize, - ) -> D { - let mut slice = self.slice(store, ptr, len); - - D::decode(&mut slice).unwrap() - } - - pub fn slice_by_val<'a, T: 'a>( - &self, - store: impl Into>, - ptr_len: i64, - ) -> &'a [u8] { - let (ptr, len) = unpack_i64_to_u32(ptr_len); - - self.slice(store, ptr as usize, len as usize) - } - - pub fn slice<'a, T: 'a>( - &self, - store: impl Into>, - ptr: usize, - len: usize, - ) -> &'a [u8] { - self.0 - .data(store) - .get(ptr..) - .and_then(|s| s.get(..len)) - .unwrap() - } - - pub fn slice_mut<'a, T: 'a>( - &self, - store: impl Into>, - ptr: usize, - len: usize, - ) -> &'a mut [u8] { - self.0 - .data_mut(store) - .get_mut(ptr..) - .and_then(|s| s.get_mut(..len)) - .unwrap() - } -} - -pub fn allocate_and_write( - caller: Caller<'_, StoreData>, +pub fn allocate_and_write<'a>( + caller: impl Into>, data: impl Encode, -) -> (Caller<'_, StoreData>, i64) { +) -> i64 { allocate_and_write_raw(caller, data.encode()) } -pub fn allocate_and_write_raw( - caller: Caller<'_, StoreData>, +pub fn allocate_and_write_raw<'a>( + caller: impl Into>, data: impl AsRef<[u8]>, -) -> (Caller<'_, StoreData>, i64) { +) -> i64 { + let mut caller = caller.into(); let data = data.as_ref(); let len = data.len(); - let mut host_context = HostContext { caller }; - - let ptr = host_context - .allocate_memory(len as u32) - .unwrap() - .into_value() - .as_i32() - .expect("always i32"); - - let mut caller = host_context.caller; - + let ptr: u32 = context::allocator(&mut caller) + .allocate(len as u32) + .unwrap(); let memory = caller.data().memory(); - memory.write(&mut caller, ptr as usize, data).unwrap(); - let res = pack_u32_to_i64(ptr as u32, len as u32); - - (caller, res) + pack_u32_to_i64(ptr, len as u32) } diff --git a/ethexe/processor/src/host/api/promise.rs b/ethexe/processor/src/host/api/promise.rs index 58578772a43..fb304018ca0 100644 --- a/ethexe/processor/src/host/api/promise.rs +++ b/ethexe/processor/src/host/api/promise.rs @@ -16,35 +16,30 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use sp_wasm_interface::StoreData; +use crate::host::{StoreData, context}; use wasmtime::{Caller, Linker}; -use crate::host::{api::MemoryWrap, threads}; - pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { linker.func_wrap("env", "ext_publish_promise", publish_promise)?; Ok(()) } -fn publish_promise(caller: Caller<'_, StoreData>, promise_ptr_len: i64) { - threads::with_params(|params| { - if let Some(ref sender) = params.promise_out_tx { - let memory = MemoryWrap(caller.data().memory()); - let promise = memory.decode_by_val(&caller, promise_ptr_len); +fn publish_promise(mut caller: Caller<'_, StoreData>, promise_ptr_len: i64) { + if let Some(sender) = caller.data().promise_out_tx.clone() { + let promise = context::memory(&mut caller).decode_by_val(promise_ptr_len); - match sender.send(promise) { - Ok(()) => { - log::trace!( - "successfully send promise to outer service: promise_ptr_len={promise_ptr_len}" - ); - } - Err(err) => { - log::trace!( - "`publish_promise`: failed to send promise to receiver because of error={err}" - ); - } + match sender.send(promise) { + Ok(()) => { + log::trace!( + "successfully send promise to outer service: promise_ptr_len={promise_ptr_len}" + ); + } + Err(err) => { + log::trace!( + "`publish_promise`: failed to send promise to receiver because of error={err}" + ); } } - }); + } } diff --git a/ethexe/processor/src/host/api/sandbox.rs b/ethexe/processor/src/host/api/sandbox.rs index fec10e9e0ec..c9b40961329 100644 --- a/ethexe/processor/src/host/api/sandbox.rs +++ b/ethexe/processor/src/host/api/sandbox.rs @@ -16,14 +16,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -// TODO (breathx): remove cloning of slices from wasm memory. - -use crate::host::{api::MemoryWrap, context::HostContext}; +use crate::host::{StoreData, context}; use ethexe_runtime_common::pack_u32_to_i64; -use gear_runtime_interface::{Instantiate, sandbox_detail}; +use gear_sandbox_host::host::{ + self as sandbox_detail, HostResult, Instantiate, Pointer, SupervisorFuncIndex, Value, WordSize, +}; use parity_scale_codec::Encode; -use sp_wasm_interface::{FunctionContext as _, IntoValue as _, Pointer, StoreData}; -use wasmtime::{Caller, Linker}; +use std::ops::Range; +use wasmtime::{AsContext, AsContextMut, Caller, Linker, Val}; pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { linker.func_wrap("env", "ext_sandbox_get_buff_version_1", get_buff)?; @@ -63,105 +63,186 @@ pub fn link(linker: &mut Linker) -> Result<(), wasmtime::Error> { Ok(()) } -fn get_buff(caller: Caller<'_, StoreData>, memory_idx: i32) -> i64 { - log::trace!(target: "host_call", "get_buff(memory_idx={memory_idx:?})"); +struct ProcessorOps; + +impl sandbox_detail::ContextOps for ProcessorOps { + type Caller<'a> = Caller<'a, StoreData>; + + fn trace(func: &str, caller: &Self::Caller<'_>) { + let data_ptr: *const _ = caller.data(); + let caller_ptr: *const _ = caller; + let thread_id = std::thread::current().id(); + + log::trace!( + "{func}; data_ptr = {:#x?}, caller_ptr = {:#x?}, thread_id = {:?}", + data_ptr as usize, + caller_ptr as usize, + thread_id, + ); + } + + fn store_data_key(caller: &Self::Caller<'_>) -> usize { + caller.data() as *const _ as usize + } + + fn invoke_dispatch_thunk( + caller: &mut Self::Caller<'_>, + dispatch_thunk_id: u32, + invoke_args_ptr: Pointer, + invoke_args_len: WordSize, + state: u32, + func_idx: SupervisorFuncIndex, + ) -> HostResult { + let table = caller + .data() + .table + .expect("Runtime doesn't have a table; sandbox is unavailable"); + let table_item = table + .get(caller.as_context_mut(), dispatch_thunk_id as u64) + .expect("dispatch_thunk_id is out of bounds"); + let dispatch_thunk = *table_item + .unwrap_func() + .expect("dispatch_thunk_idx should be a funcref"); + + let mut ret_vals = [Val::I64(0)]; + let result = dispatch_thunk.call( + &mut *caller, + &[ + Val::I32(u32::from(invoke_args_ptr) as i32), + Val::I32(invoke_args_len as i32), + Val::I32(state as i32), + Val::I32(usize::from(func_idx) as i32), + ], + &mut ret_vals, + ); + + match result { + Ok(()) => ret_vals[0] + .i64() + .ok_or_else(|| "Supervisor function returned unexpected result!".into()), + Err(err) => Err(err.to_string().into()), + } + } + + fn read_memory_into( + caller: &Self::Caller<'_>, + address: Pointer, + dest: &mut [u8], + ) -> Result<(), String> { + let memory = caller.as_context().data().memory().data(caller); + let range = checked_range(u32::from(address) as usize, dest.len(), memory.len()) + .ok_or_else(|| String::from("memory read is out of bounds"))?; + dest.copy_from_slice(&memory[range]); + Ok(()) + } + + fn write_memory( + caller: &mut Self::Caller<'_>, + address: Pointer, + data: &[u8], + ) -> Result<(), String> { + context::write_memory_from(caller, u32::from(address), data) + } + + fn allocate_memory( + caller: &mut Self::Caller<'_>, + size: WordSize, + ) -> Result, String> { + context::allocator(caller) + .allocate(size) + .map(Pointer::new) + .map_err(|err| err.to_string()) + } + + fn deallocate_memory(caller: &mut Self::Caller<'_>, ptr: Pointer) -> Result<(), String> { + context::allocator(caller) + .deallocate(ptr.into()) + .map_err(|err| err.to_string()) + } +} - let mut host_context = HostContext { caller }; - let res = sandbox_detail::get_buff(&mut host_context, memory_idx as u32) as i64; +fn checked_range(offset: usize, len: usize, max: usize) -> Option> { + let end = offset.checked_add(len)?; + (end <= max).then(|| offset..end) +} +fn get_buff(mut caller: Caller<'_, StoreData>, memory_idx: i32) -> i64 { + log::trace!(target: "host_call", "get_buff(memory_idx={memory_idx:?})"); + let res = sandbox_detail::get_buff::(&mut caller, memory_idx as u32) as i64; log::trace!(target: "host_call", "get_buff(..) -> {res:?}"); - res } -fn get_global_val(caller: Caller<'_, StoreData>, instance_idx: i32, name: i64) -> i64 { - log::trace!(target: "host_call", "get_global_val(instance_idx={instance_idx:?}, name={name:?})"); +fn get_global_val(mut caller: Caller<'_, StoreData>, instance_idx: i32, name: i64) -> i64 { + log::trace!( + target: "host_call", + "get_global_val(instance_idx={instance_idx:?}, name={name:?})" + ); - let memory = MemoryWrap(caller.data().memory()); - - let name = memory.slice_by_val(&caller, name).to_vec(); + let name = context::memory(&mut caller).slice_by_val(name).to_vec(); let name = core::str::from_utf8(&name).unwrap_or_default(); - let mut host_context = HostContext { caller }; - - let res = sandbox_detail::get_global_val(&mut host_context, instance_idx as u32, name); + let res = + sandbox_detail::get_global_val::(&mut caller, instance_idx as u32, name); let res = res.encode(); let res_len = res.len() as u32; - let ptr = host_context - .allocate_memory(res_len as u32) - .unwrap() - .into_value() - .as_i32() - .expect("always i32"); - - let mut caller = host_context.caller; - - let memory = caller.data().memory(); - - memory.write(&mut caller, ptr as usize, &res).unwrap(); - - let res = pack_u32_to_i64(ptr as u32, res_len); + let ptr = context::allocator(&mut caller).allocate(res_len).unwrap(); + caller + .data() + .memory() + .write(&mut caller, ptr as usize, &res) + .unwrap(); + let res = pack_u32_to_i64(ptr, res_len); log::trace!(target: "host_call", "get_global_val(..) -> {res:?}"); - res } -fn get_instance_ptr(caller: Caller<'_, StoreData>, instance_idx: i32) -> i64 { +fn get_instance_ptr(mut caller: Caller<'_, StoreData>, instance_idx: i32) -> i64 { log::trace!(target: "host_call", "get_instance_ptr(instance_idx={instance_idx:?})"); - - let mut host_context = HostContext { caller }; - let res = sandbox_detail::get_instance_ptr(&mut host_context, instance_idx as u32) as i64; - + let res = + sandbox_detail::get_instance_ptr::(&mut caller, instance_idx as u32) as i64; log::trace!(target: "host_call", "get_instance_ptr(..) -> {res:?}"); - res } -fn instance_teardown(caller: Caller<'_, StoreData>, instance_idx: i32) { +fn instance_teardown(mut caller: Caller<'_, StoreData>, instance_idx: i32) { log::trace!(target: "host_call", "instance_teardown(instance_idx={instance_idx:?})"); - - let mut host_context = HostContext { caller }; - sandbox_detail::instance_teardown(&mut host_context, instance_idx as u32) + sandbox_detail::instance_teardown::(&mut caller, instance_idx as u32); } fn instantiate( - caller: Caller<'_, StoreData>, + mut caller: Caller<'_, StoreData>, dispatch_thunk_id: i32, wasm_code: i64, raw_env_def: i64, state_ptr: i32, ) -> i32 { - log::trace!(target: "host_call", "instantiate(dispatch_thunk_id={dispatch_thunk_id:?}, wasm_code={wasm_code:?}, raw_env_def={raw_env_def:?}, state_ptr={state_ptr:?})"); - - let dispatch_thunk_id = dispatch_thunk_id as u32; - - let memory = MemoryWrap(caller.data().memory()); - - let wasm_code = memory.slice_by_val(&caller, wasm_code).to_vec(); - - let raw_env_def = memory.slice_by_val(&caller, raw_env_def).to_vec(); - - let state_ptr = Pointer::::new(state_ptr as u32); - - let mut host_context = HostContext { caller }; - let res = sandbox_detail::instantiate( - &mut host_context, - dispatch_thunk_id, + log::trace!( + target: "host_call", + "instantiate(dispatch_thunk_id={dispatch_thunk_id:?}, wasm_code={wasm_code:?}, raw_env_def={raw_env_def:?}, state_ptr={state_ptr:?})" + ); + + let memory = context::memory(&mut caller); + let wasm_code = memory.slice_by_val(wasm_code).to_vec(); + let raw_env_def = memory.slice_by_val(raw_env_def).to_vec(); + + let res = sandbox_detail::instantiate::( + &mut caller, + dispatch_thunk_id as u32, &wasm_code, &raw_env_def, - state_ptr, + Pointer::new(state_ptr as u32), Instantiate::Version2, ) as i32; log::trace!(target: "host_call", "instantiate(..) -> {res:?}"); - res } fn invoke( - caller: Caller<'_, StoreData>, + mut caller: Caller<'_, StoreData>, instance_idx: i32, function: i64, args: i64, @@ -169,144 +250,130 @@ fn invoke( return_val_len: i32, state_ptr: i32, ) -> i32 { - log::trace!(target: "host_call", "invoke(instance_idx={instance_idx:?}, function={function:?}, args={args:?}, return_val_ptr={return_val_ptr:?}, return_val_len={return_val_len:?}, state_ptr={state_ptr:?})"); + log::trace!( + target: "host_call", + "invoke(instance_idx={instance_idx:?}, function={function:?}, args={args:?}, return_val_ptr={return_val_ptr:?}, return_val_len={return_val_len:?}, state_ptr={state_ptr:?})" + ); - let instance_idx = instance_idx as u32; - - let memory = MemoryWrap(caller.data().memory()); - - let function = memory.slice_by_val(&caller, function).to_vec(); + let memory = context::memory(&mut caller); + let function = memory.slice_by_val(function).to_vec(); let function = core::str::from_utf8(&function).unwrap_or_default(); + let args = memory.slice_by_val(args).to_vec(); - let args = memory.slice_by_val(&caller, args).to_vec(); - - let return_val_ptr = Pointer::::new(return_val_ptr as u32); - - let return_val_len = return_val_len as u32; - - let state_ptr = Pointer::::new(state_ptr as u32); - - let mut host_context = HostContext { caller }; - let res = sandbox_detail::invoke( - &mut host_context, - instance_idx, + let res = sandbox_detail::invoke::( + &mut caller, + instance_idx as u32, function, &args, - return_val_ptr, - return_val_len, - state_ptr, + Pointer::new(return_val_ptr as u32), + return_val_len as u32, + Pointer::new(state_ptr as u32), ) as i32; log::trace!(target: "host_call", "invoke(..) -> {res:?}"); - res } fn memory_get( - caller: Caller<'_, StoreData>, + mut caller: Caller<'_, StoreData>, memory_idx: i32, offset: i32, buff_ptr: i32, buff_len: i32, ) -> i32 { - log::trace!(target: "host_call", "memory_get(memory_idx={memory_idx:?}, offset={offset:?}, buff_ptr={buff_ptr:?}, buff_len={buff_len:?})"); + log::trace!( + target: "host_call", + "memory_get(memory_idx={memory_idx:?}, offset={offset:?}, buff_ptr={buff_ptr:?}, buff_len={buff_len:?})" + ); - let buff_ptr = Pointer::new(buff_ptr as u32); - - let mut host_context = HostContext { caller }; - let res = sandbox_detail::memory_get( - &mut host_context, + let res = sandbox_detail::memory_get::( + &mut caller, memory_idx as u32, offset as u32, - buff_ptr, + Pointer::new(buff_ptr as u32), buff_len as u32, ) as i32; log::trace!(target: "host_call", "memory_get(..) -> {res:?}"); - res } -fn memory_grow(caller: Caller<'_, StoreData>, memory_idx: i32, size: i32) -> i32 { +fn memory_grow(mut caller: Caller<'_, StoreData>, memory_idx: i32, size: i32) -> i32 { log::trace!(target: "host_call", "memory_grow(memory_idx={memory_idx:?}, size={size:?})"); - - let mut host_context = HostContext { caller }; - let res = sandbox_detail::memory_grow(&mut host_context, memory_idx as u32, size as u32) as i32; - + let res = + sandbox_detail::memory_grow::(&mut caller, memory_idx as u32, size as u32) + as i32; log::trace!(target: "host_call", "memory_grow(..) -> {res:?}"); - res } -fn memory_new(caller: Caller<'_, StoreData>, initial: i32, maximum: i32) -> i32 { +fn memory_new(mut caller: Caller<'_, StoreData>, initial: i32, maximum: i32) -> i32 { log::trace!(target: "host_call", "memory_new(initial={initial:?}, maximum={maximum:?})"); - - let mut host_context = HostContext { caller }; - let res = sandbox_detail::memory_new(&mut host_context, initial as u32, maximum as u32) as i32; - + let res = + sandbox_detail::memory_new::(&mut caller, initial as u32, maximum as u32) + as i32; log::trace!(target: "host_call", "memory_new(..) -> {res:?}"); - res } fn memory_set( - caller: Caller<'_, StoreData>, + mut caller: Caller<'_, StoreData>, memory_idx: i32, offset: i32, val_ptr: i32, val_len: i32, ) -> i32 { - log::trace!(target: "host_call", "memory_set(memory_idx={memory_idx:?}, offset={offset:?}, val_ptr={val_ptr:?}, val_len={val_len:?})"); + log::trace!( + target: "host_call", + "memory_set(memory_idx={memory_idx:?}, offset={offset:?}, val_ptr={val_ptr:?}, val_len={val_len:?})" + ); - let val_ptr = Pointer::new(val_ptr as u32); - - let mut host_context = HostContext { caller }; - let res = sandbox_detail::memory_set( - &mut host_context, + let res = sandbox_detail::memory_set::( + &mut caller, memory_idx as u32, offset as u32, - val_ptr, + Pointer::new(val_ptr as u32), val_len as u32, ) as i32; log::trace!(target: "host_call", "memory_set(..) -> {res:?}"); - res } -fn memory_size(caller: Caller<'_, StoreData>, memory_idx: i32) -> i32 { +fn memory_size(mut caller: Caller<'_, StoreData>, memory_idx: i32) -> i32 { log::trace!(target: "host_call", "memory_size(memory_idx={memory_idx:?})"); - - let mut host_context = HostContext { caller }; - let res = sandbox_detail::memory_size(&mut host_context, memory_idx as u32) as i32; - + let res = sandbox_detail::memory_size::(&mut caller, memory_idx as u32) as i32; log::trace!(target: "host_call", "memory_size(..) -> {res:?}"); - res } -fn memory_teardown(caller: Caller<'_, StoreData>, memory_idx: i32) { +fn memory_teardown(mut caller: Caller<'_, StoreData>, memory_idx: i32) { log::trace!(target: "host_call", "memory_teardown(memory_idx={memory_idx:?})"); - - let mut host_context = HostContext { caller }; - sandbox_detail::memory_teardown(&mut host_context, memory_idx as u32) + sandbox_detail::memory_teardown::(&mut caller, memory_idx as u32); } -fn set_global_val(caller: Caller<'_, StoreData>, instance_idx: i32, name: i64, value: i64) -> i32 { - log::trace!(target: "host_call", "set_global_val(instance_idx={instance_idx:?}, name={name:?}, value={value:?})"); - - let memory = MemoryWrap(caller.data().memory()); +fn set_global_val( + mut caller: Caller<'_, StoreData>, + instance_idx: i32, + name: i64, + value: i64, +) -> i32 { + log::trace!( + target: "host_call", + "set_global_val(instance_idx={instance_idx:?}, name={name:?}, value={value:?})" + ); - let name = memory.slice_by_val(&caller, name).to_vec(); + let memory = context::memory(&mut caller); + let name = memory.slice_by_val(name).to_vec(); let name = core::str::from_utf8(&name).unwrap_or_default(); + let value: Value = memory.decode_by_val(value); - let value = memory.decode_by_val(&caller, value); - - let mut host_context = HostContext { caller }; - let res = - sandbox_detail::set_global_val(&mut host_context, instance_idx as u32, name, value) as i32; - + let res = sandbox_detail::set_global_val::( + &mut caller, + instance_idx as u32, + name, + value, + ) as i32; log::trace!(target: "host_call", "set_global_val(..) -> {res:?}"); - res } diff --git a/ethexe/processor/src/host/context.rs b/ethexe/processor/src/host/context.rs index 67fdbfdc5a6..91209b625d4 100644 --- a/ethexe/processor/src/host/context.rs +++ b/ethexe/processor/src/host/context.rs @@ -2,64 +2,168 @@ // // Copyright (C) 2024-2025 Gear Technologies Inc. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -use sp_wasm_interface::{FunctionContextToken, Pointer, StoreData, WordSize}; -use wasmtime::Caller; +use core::ops::Range; +use ethexe_common::injected::Promise; +use ethexe_db::CASDatabase; +use ethexe_runtime_common::unpack_i64_to_u32; +use parity_scale_codec::Decode; +use sp_allocator::FreeingBumpHeapAllocator; +use tokio::sync::mpsc; +use wasmtime::{AsContextMut, Memory, StoreContextMut, Table}; + +fn checked_range(offset: usize, len: usize, max: usize) -> Option> { + let end = offset.checked_add(len)?; + (end <= max).then(|| offset..end) +} + +pub(crate) fn write_memory_from( + mut ctx: impl AsContextMut, + address: u32, + data: &[u8], +) -> Result<(), String> { + let memory = ctx.as_context().data().memory(); + let memory = memory.data_mut(&mut ctx); + + let range = checked_range(address as usize, data.len(), memory.len()) + .ok_or_else(|| String::from("memory write is out of bounds"))?; + memory[range].copy_from_slice(data); + Ok(()) +} + +pub(crate) struct StoreData { + pub(crate) memory: Option, + pub(crate) table: Option, + pub(crate) allocator: Option, + pub(crate) db: Box, + pub(crate) promise_out_tx: Option>, +} + +impl StoreData { + pub(crate) fn memory(&self) -> Memory { + self.memory + .expect("memory is initialized before host calls; qed") + } +} + +pub(crate) struct MemoryWrapper<'a> { + caller: StoreContextMut<'a, StoreData>, + memory: Memory, +} + +// TODO: return results for mem accesses. +impl MemoryWrapper<'_> { + pub fn decode_by_val(&self, ptr_len: i64) -> D { + let mut slice = self.slice_by_val(ptr_len); + D::decode(&mut slice).unwrap() + } + + pub fn decode(&self, ptr: usize, len: usize) -> D { + let mut slice = self.slice(ptr, len); + D::decode(&mut slice).unwrap() + } + + pub fn slice_by_val(&self, ptr_len: i64) -> &[u8] { + let (ptr, len) = unpack_i64_to_u32(ptr_len); + self.slice(ptr as usize, len as usize) + } + + pub fn array(&self, ptr: usize) -> [u8; N] { + let slice = self.slice(ptr, N); + slice.try_into().expect("infallible") + } + + pub fn slice(&self, ptr: usize, len: usize) -> &[u8] { + self.memory + .data(&self.caller) + .get(ptr..) + .and_then(|s| s.get(..len)) + .unwrap() + } -pub(crate) struct HostContext<'a> { - pub(crate) caller: Caller<'a, StoreData>, + pub fn slice_mut(&mut self, ptr: usize, len: usize) -> &mut [u8] { + self.memory + .data_mut(&mut self.caller) + .get_mut(ptr..) + .and_then(|s| s.get_mut(..len)) + .unwrap() + } } -impl sp_wasm_interface::FunctionContext for HostContext<'_> { - fn read_memory_into( - &self, - address: Pointer, - dest: &mut [u8], - ) -> sp_wasm_interface::Result<()> { - sp_wasm_interface::util::read_memory_into(&self.caller, address, dest) - .map_err(|e| e.to_string()) +impl sp_allocator::Memory for MemoryWrapper<'_> { + fn with_access_mut(&mut self, run: impl FnOnce(&mut [u8]) -> R) -> R { + run(self.memory.data_mut(&mut self.caller)) + } + + fn with_access(&self, run: impl FnOnce(&[u8]) -> R) -> R { + run(self.memory.data(&self.caller)) + } + + fn grow(&mut self, additional: u32) -> Result<(), ()> { + self.memory + .grow(&mut self.caller, additional as u64) + .map_err(|err| { + log::error!("Failed to grow memory by {additional} pages: {err}"); + }) + .map(drop) } - fn write_memory(&mut self, address: Pointer, data: &[u8]) -> sp_wasm_interface::Result<()> { - sp_wasm_interface::util::write_memory_from(&mut self.caller, address, data) - .map_err(|e| e.to_string()) + fn pages(&self) -> u32 { + self.memory.size(&self.caller) as u32 } - fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result> { - sp_wasm_interface::util::allocate_memory(&mut self.caller, size) + fn max_pages(&self) -> Option { + self.memory + .ty(&self.caller) + .maximum() + .map(|pages| pages as u32) } +} + +pub(crate) fn memory<'a>(caller: impl Into>) -> MemoryWrapper<'a> { + let caller = caller.into(); + let memory = caller.data().memory(); + MemoryWrapper { caller, memory } +} + +pub(crate) struct Allocator<'a> { + memory: MemoryWrapper<'a>, + allocator: Option, +} - fn deallocate_memory(&mut self, ptr: Pointer) -> sp_wasm_interface::Result<()> { - sp_wasm_interface::util::deallocate_memory(&mut self.caller, ptr) +impl Allocator<'_> { + pub fn allocate(&mut self, size: u32) -> Result { + self.allocator + .as_mut() + .unwrap() + .allocate(&mut self.memory, size) + .map(Into::into) } - fn register_panic_error_message(&mut self, message: &str) { - self.caller - .data_mut() - .host_state_mut() - .expect("host state is not empty when calling a function in wasm; qed") - .panic_message = Some(message.to_owned()); + pub fn deallocate(&mut self, ptr: u32) -> Result<(), sp_allocator::Error> { + self.allocator + .as_mut() + .unwrap() + .deallocate(&mut self.memory, ptr.into()) } +} + +impl Drop for Allocator<'_> { + fn drop(&mut self) { + self.memory.caller.data_mut().allocator = self.allocator.take(); + } +} + +pub(crate) fn allocator<'a>(caller: impl Into>) -> Allocator<'a> { + let mut caller = caller.into(); + let allocator = caller + .data_mut() + .allocator + .take() + .expect("allocator is available during wasm calls; qed"); - fn with_caller_mut_impl( - &mut self, - _: FunctionContextToken, - context: *mut (), - callback: fn(*mut (), &mut Caller), - ) { - callback(context, &mut self.caller) + Allocator { + memory: memory(caller), + allocator: Some(allocator), } } diff --git a/ethexe/processor/src/host/mod.rs b/ethexe/processor/src/host/mod.rs index 153d712cdd2..7de6de76da4 100644 --- a/ethexe/processor/src/host/mod.rs +++ b/ethexe/processor/src/host/mod.rs @@ -18,13 +18,12 @@ use core_processor::common::JournalNote; use ethexe_common::{gear::MessageType, injected::Promise}; -use ethexe_db::CASDatabase; +use ethexe_db::Database; use ethexe_runtime_common::{ProcessQueueContext, ProgramJournals, unpack_i64_to_u32}; use gear_core::code::{CodeMetadata, InstrumentedCode}; use gprimitives::H256; use parity_scale_codec::{Decode, Encode}; use sp_allocator::{AllocationStats, FreeingBumpHeapAllocator}; -use sp_wasm_interface::{HostState, IntoValue, MemoryWrapper, StoreData}; use std::sync::Arc; use tokio::sync::mpsc; @@ -34,12 +33,12 @@ pub mod runtime; mod context; mod threads; +pub(crate) use context::{StoreData, write_memory_from}; + #[derive(thiserror::Error, Debug)] pub enum InstanceError { #[error("failed to write call input: {0}")] CallInputWrite(String), - #[error("host state should be set before call and reset after")] - HostStateNotSet, #[error("couldn't find 'memory' export")] MemoryExportNotFound, #[error("'memory' export is not a wasm memory")] @@ -83,6 +82,7 @@ pub type Store = wasmtime::Store; #[derive(Clone)] pub(crate) struct InstanceCreator { + db: Database, engine: wasmtime::Engine, instance_pre: Arc>, } @@ -98,9 +98,10 @@ impl InstanceCreator { /// /// A wasm runtime modules is expected to use some runtime interface, /// which calls linked host functions. - pub fn new(runtime: Vec) -> Result { + pub fn new(db: Database, runtime: Vec) -> Result { let mut config = wasmtime::Config::new(); - config.cache_config_load_default()?; + let cache = wasmtime::Cache::new(Default::default())?; + config.cache(Some(cache)); let engine = wasmtime::Engine::new(&config)?; let module = wasmtime::Module::new(&engine, runtime)?; @@ -117,13 +118,21 @@ impl InstanceCreator { let instance_pre = Arc::new(instance_pre); Ok(Self { + db, engine, instance_pre, }) } pub fn instantiate(&self) -> Result { - let mut store = Store::new(&self.engine, Default::default()); + let store = StoreData { + memory: None, + table: None, + allocator: None, + db: self.db.cas().clone_boxed(), + promise_out_tx: None, + }; + let mut store = Store::new(&self.engine, store); let instance = self.instance_pre.instantiate(&mut store)?; @@ -145,7 +154,6 @@ pub(crate) struct InstanceWrapper { } impl InstanceWrapper { - #[allow(unused)] pub fn data(&self) -> &StoreData { self.store.data() } @@ -169,31 +177,28 @@ impl InstanceWrapper { /// processed out of the wasm module. pub fn run( &mut self, - db: Box, ctx: ProcessQueueContext, promise_out_tx: Option>, ) -> Result<(ProgramJournals, H256, u64)> { - threads::set(db, ctx.state_root, promise_out_tx.clone()); - - // Cleanup the `promise_out_tx` from thread-local to signal receiver that channel is closed. - let _cleanup = scopeguard::guard((), |()| { - threads::clear_promise_out_tx(); - }); + threads::set(self.data().db.clone_boxed(), ctx.state_root); - // Pieces of resulting journal. Hack to avoid single allocation limit. - let (ptr_lens, gas_spent): (Vec, i64) = self.call("run", ctx.encode())?; + self.with_promise_out_tx(promise_out_tx, |instance_wrapper| { + // Pieces of resulting journal. Hack to avoid single allocation limit. + let (ptr_lens, gas_spent): (Vec, i64) = + instance_wrapper.call("run", ctx.encode())?; - let mut mega_journal = Vec::with_capacity(ptr_lens.len()); + let mut mega_journal = Vec::with_capacity(ptr_lens.len()); - for ptr_len in ptr_lens { - let journal_and_message_type: (Vec, MessageType, bool) = - self.get_call_output(ptr_len)?; - mega_journal.push(journal_and_message_type); - } + for ptr_len in ptr_lens { + let journal_and_message_type: (Vec, MessageType, bool) = + instance_wrapper.get_call_output(ptr_len)?; + mega_journal.push(journal_and_message_type); + } - let new_state_hash = threads::with_params(|params| params.state_hash); + let new_state_hash = threads::state_hash(); - Ok((mega_journal, new_state_hash, gas_spent as u64)) + Ok((mega_journal, new_state_hash, gas_spent as u64)) + }) } /// Low-level call to exported from the wasm module `name` function. @@ -214,32 +219,31 @@ impl InstanceWrapper { } fn with_host_state(&mut self, f: impl FnOnce(&mut Self) -> Result) -> Result { - self.set_host_state()?; + self.set_allocator()?; let res = f(self); - let _allocation_stats = self.reset_host_state()?; + let _allocation_stats = self.unset_allocator()?; res } - fn set_call_input(&mut self, bytes: &[u8]) -> Result<(i32, i32)> { - let memory = self.memory()?; + fn with_promise_out_tx( + &mut self, + promise_out_tx: Option>, + f: impl FnOnce(&mut Self) -> Result, + ) -> Result { + self.data_mut().promise_out_tx = promise_out_tx; + let res = f(self); + let _ = self.data_mut().promise_out_tx.take(); + res + } + fn set_call_input(&mut self, bytes: &[u8]) -> Result<(i32, i32)> { let len = bytes.len() as u32; // TODO: check len. - let ptr = self.with_allocator(|instance_wrapper, allocator| { - allocator - .allocate( - &mut MemoryWrapper::from((&memory, &mut instance_wrapper.store)), - len, - ) - .map_err(Into::into) - })?; - - sp_wasm_interface::util::write_memory_from(&mut self.store, ptr, bytes) - .map_err(InstanceError::CallInputWrite)?; + let ptr = context::allocator(&mut self.store).allocate(len)?; - let ptr = ptr.into_value().as_i32().expect("must be i32"); + write_memory_from(&mut self.store, ptr, bytes).map_err(InstanceError::CallInputWrite)?; - Ok((ptr, len as i32)) + Ok((ptr as i32, len as i32)) } fn get_call_output(&mut self, ptr_len: i64) -> Result { @@ -254,48 +258,22 @@ impl InstanceWrapper { Ok(res) } - fn set_host_state(&mut self) -> Result<()> { + fn set_allocator(&mut self) -> Result<()> { let heap_base = self.heap_base()?; - let allocator = FreeingBumpHeapAllocator::new(heap_base); - - let host_state = HostState::new(allocator); - - self.data_mut().host_state = Some(host_state); + self.data_mut().allocator = Some(allocator); Ok(()) } - fn reset_host_state(&mut self) -> Result { - let host_state = self + fn unset_allocator(&mut self) -> Result { + let allocator = self .data_mut() - .host_state + .allocator .take() - .ok_or(InstanceError::HostStateNotSet)?; - - Ok(host_state.allocation_stats()) - } - - fn with_allocator( - &mut self, - f: impl FnOnce(&mut Self, &mut FreeingBumpHeapAllocator) -> Result, - ) -> Result { - let mut allocator = self - .data_mut() - .host_state - .as_mut() - .and_then(|s| s.allocator.take()) .ok_or(InstanceError::AllocatorNotSet)?; - let res = f(self, &mut allocator); - - self.data_mut() - .host_state - .as_mut() - .expect("checked above") - .allocator = Some(allocator); - - res + Ok(allocator.stats()) } fn memory(&mut self) -> Result { diff --git a/ethexe/processor/src/host/threads.rs b/ethexe/processor/src/host/threads.rs index fdf70e9f68e..8fb706fac75 100644 --- a/ethexe/processor/src/host/threads.rs +++ b/ethexe/processor/src/host/threads.rs @@ -18,8 +18,7 @@ // TODO: for each panic here place log::error, otherwise it won't be printed. -use core::fmt; -use ethexe_common::{HashOf, injected::Promise}; +use ethexe_common::HashOf; use ethexe_db::CASDatabase; use ethexe_runtime_common::state::{ ActiveProgram, MemoryPages, MemoryPagesRegionInner, Program, ProgramState, QueryableStorage, @@ -30,7 +29,6 @@ use gear_lazy_pages::LazyPagesStorage; use gprimitives::H256; use parity_scale_codec::{Decode, DecodeAll}; use std::{cell::RefCell, collections::BTreeMap}; -use tokio::sync::mpsc; const UNSET_PANIC: &str = "params should be set before query"; const UNKNOWN_STATE: &str = "state should always be valid (must exist)"; @@ -39,20 +37,13 @@ thread_local! { static PARAMS: RefCell> = const { RefCell::new(None) }; } -pub struct ThreadParams { - pub db: Box, - pub state_hash: H256, - pub promise_out_tx: Option>, +struct ThreadParams { + state_hash: H256, + db: Box, pages_registry_cache: Option, pages_regions_cache: Option>, } -impl fmt::Debug for ThreadParams { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ThreadParams") - } -} - impl ThreadParams { pub fn get_page_region( &mut self, @@ -104,57 +95,50 @@ impl PageKey { } } -pub fn set( - db: Box, - state_hash: H256, - promise_out_tx: Option>, -) { +pub fn set(db: Box, state_hash: H256) { PARAMS.set(Some(ThreadParams { db, state_hash, - promise_out_tx, pages_registry_cache: None, pages_regions_cache: None, })) } -pub fn update_state_hash(state_hash: H256) { +fn with_params(f: impl FnOnce(&mut ThreadParams) -> T) -> T { PARAMS.with_borrow_mut(|v| { let params = v.as_mut().expect(UNSET_PANIC); - params.state_hash = state_hash; - params.pages_registry_cache = None; - params.pages_regions_cache = None; + f(params) }) } -pub fn with_db(f: impl FnOnce(&dyn CASDatabase) -> T) -> T { - PARAMS.with_borrow(|v| { - let params = v.as_ref().expect(UNSET_PANIC); - - f(params.db.as_ref()) +pub fn update_state_hash(state_hash: H256) { + with_params(|params| { + params.state_hash = state_hash; + params.pages_registry_cache = None; + params.pages_regions_cache = None; }) } -pub fn with_params(f: impl FnOnce(&mut ThreadParams) -> T) -> T { - PARAMS.with_borrow_mut(|v| { - let params = v.as_mut().expect(UNSET_PANIC); - - f(params) - }) -} - -pub fn clear_promise_out_tx() { - PARAMS.with_borrow_mut(|maybe_params| { - let params = maybe_params.as_mut().expect(UNSET_PANIC); - let _ = params.promise_out_tx.take(); - }) +pub fn state_hash() -> H256 { + with_params(|params| params.state_hash) } #[derive(Debug)] pub struct EthexeHostLazyPages; impl LazyPagesStorage for EthexeHostLazyPages { + fn page_exists(&self, key: &[u8]) -> bool { + with_params(|params| { + let page = PageKey::page_from_buf(key); + + params + .get_page_region(page) + .map(|region| region.contains_key(&page)) + .unwrap_or(false) + }) + } + fn load_page(&mut self, key: &[u8], buffer: &mut [u8]) -> Option { with_params(|params| { let page = PageKey::page_from_buf(key); @@ -168,15 +152,4 @@ impl LazyPagesStorage for EthexeHostLazyPages { Some(data.len() as u32) }) } - - fn page_exists(&self, key: &[u8]) -> bool { - with_params(|params| { - let page = PageKey::page_from_buf(key); - - params - .get_page_region(page) - .map(|region| region.contains_key(&page)) - .unwrap_or(false) - }) - } } diff --git a/ethexe/processor/src/lib.rs b/ethexe/processor/src/lib.rs index b0d5b2a2206..c7cbc9ecb83 100644 --- a/ethexe/processor/src/lib.rs +++ b/ethexe/processor/src/lib.rs @@ -253,7 +253,7 @@ impl Processor { } pub fn with_config(config: ProcessorConfig, db: Database) -> Result { - let creator = InstanceCreator::new(host::runtime())?; + let creator = InstanceCreator::new(db.clone(), host::runtime())?; Ok(Self { config, db, diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 7ebcc56b806..39c66f83a49 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -27,7 +27,7 @@ derive_more.workspace = true # Gear runtime-primitives.workspace = true -gear-runtime-interface = { workspace = true, features = ["std"] } +gear-runtime-interface = { workspace = true, features = ["std", "sandbox"] } service.workspace = true pallet-gear-payment = { workspace = true, features = ["std"] } pallet-gear-staking-rewards = { workspace = true, optional = true, features = ["std"] } diff --git a/node/service/Cargo.toml b/node/service/Cargo.toml index 321c04fbf40..34e04b56c30 100644 --- a/node/service/Cargo.toml +++ b/node/service/Cargo.toml @@ -31,7 +31,7 @@ pallet-gear-eth-bridge-rpc.workspace = true pallet-gear-eth-bridge-rpc-runtime-api = { workspace = true, features = ["std"] } pallet-gear = { workspace = true, features = ["std"] } runtime-primitives = { workspace = true, features = ["std"] } -gear-runtime-interface = { workspace = true, features = ["std"] } +gear-runtime-interface = { workspace = true, features = ["std", "sandbox"] } authorship.workspace = true # Gear Runtimes diff --git a/runtime-interface/Cargo.toml b/runtime-interface/Cargo.toml index 12c6c7db6cb..0337ed8a3fc 100644 --- a/runtime-interface/Cargo.toml +++ b/runtime-interface/Cargo.toml @@ -14,7 +14,7 @@ builtins-common = { workspace = true, optional = true } gear-core.workspace = true gear-lazy-pages-common.workspace = true gear-lazy-pages = { workspace = true, optional = true } -gear-sandbox-interface.workspace = true +gear-sandbox-interface = { workspace = true, optional = true } sp-io.workspace = true sp-runtime-interface = { workspace = true, default-features = false } @@ -24,11 +24,10 @@ log = { workspace = true, optional = true } gear-workspace-hack.workspace = true [features] -default = ["std"] +default = ["std", "sandbox"] std = [ "gear-core/std", "gear-lazy-pages", - "gear-sandbox-interface/std", "sp-io/std", "sp-std/std", @@ -38,3 +37,4 @@ std = [ "builtins-common/bls12-381-std", ] +sandbox = ["std", "gear-sandbox-interface/std"] diff --git a/runtime-interface/sandbox/Cargo.toml b/runtime-interface/sandbox/Cargo.toml index 2ce241d27c1..281f068bc41 100644 --- a/runtime-interface/sandbox/Cargo.toml +++ b/runtime-interface/sandbox/Cargo.toml @@ -17,17 +17,15 @@ workspace = true sp-runtime-interface.workspace = true sp-wasm-interface.workspace = true -parity-scale-codec.workspace = true gear-sandbox-host = { workspace = true, optional = true } log = { workspace = true, optional = true } + gear-workspace-hack.workspace = true [features] default = ["std"] std = [ "gear-sandbox-host", - - "parity-scale-codec/std", "log", "sp-runtime-interface/std", diff --git a/runtime-interface/sandbox/src/detail.rs b/runtime-interface/sandbox/src/detail.rs index c2618f7c0b9..ac2abcf04ac 100644 --- a/runtime-interface/sandbox/src/detail.rs +++ b/runtime-interface/sandbox/src/detail.rs @@ -1,110 +1,83 @@ // This file is part of Gear. - +// // Copyright (C) Gear Technologies Inc. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - +// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. - +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. - +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use core::{ - cell::RefCell, - sync::atomic::{AtomicU32, Ordering}, -}; - -use gear_sandbox_host::sandbox::{self as sandbox_env, env::Instantiate}; -use parity_scale_codec::{Decode, Encode}; +use gear_sandbox_host::host::{self, HostPointer, Instantiate, Pointer, Value, WordSize}; use sp_wasm_interface::{ - Caller, FunctionContext, HostPointer, Pointer, StoreData, Value, WordSize, util, - wasmtime::{AsContext, AsContextMut, Func, Val}, + Caller, FunctionContext, StoreData, util, + wasmtime::{AsContext, AsContextMut, Val}, }; -struct Sandboxes { - store_data_key: usize, - store: sandbox_env::SandboxComponents, +pub fn init( + sandbox_backend: gear_sandbox_host::sandbox::SandboxBackend, + store_clear_counter_limit: Option, +) { + host::init(sandbox_backend, store_clear_counter_limit); } -impl Sandboxes { - pub fn new(sandbox_backend: sandbox_env::SandboxBackend) -> Self { - Self { - store_data_key: 0, - store: sandbox_env::SandboxComponents::new(sandbox_backend), - } - } - - pub fn get(&mut self, store_data_key: usize) -> &mut sandbox_env::SandboxComponents { - if self.store_data_key != store_data_key { - self.store_data_key = store_data_key; - self.store.clear(); - } +struct RuntimeInterfaceOps; - &mut self.store - } +impl host::ContextOps for RuntimeInterfaceOps { + type Caller<'a> = Caller<'a, StoreData>; - // Clears the underlying store if the counter exceeds the limit. - pub fn clear(&mut self) { - SANDBOX_STORE_CLEAR_COUNTER.with_borrow_mut(|c| { - if *c >= SANDBOX_STORE_CLEAR_COUNTER_LIMIT.load(Ordering::SeqCst) { - *c = 0; - self.store.clear(); - } - *c += 1; - }); + fn trace(func: &str, caller: &Self::Caller<'_>) { + let data_ptr: *const _ = caller.data(); + let caller_ptr: *const _ = caller; + let thread_id = std::thread::current().id(); + + log::trace!( + "{func}; data_ptr = {:#x?}, caller_ptr = {:#x?}, thread_id = {:?}", + data_ptr as usize, + caller_ptr as usize, + thread_id, + ); } -} -// Global sandbox backend type selector -static SANDBOX_BACKEND_TYPE: sandbox_env::AtomicSandboxBackend = - sandbox_env::AtomicSandboxBackend::new(sandbox_env::SandboxBackend::Wasmer); - -thread_local! { - static SANDBOXES: RefCell = { - let sandbox_backend = SANDBOX_BACKEND_TYPE.load(Ordering::SeqCst); - RefCell::new(Sandboxes::new(sandbox_backend)) + fn store_data_key(caller: &Self::Caller<'_>) -> usize { + caller.data() as *const _ as usize } -} - -/// Sets the global sandbox backend type. -/// Buy default, it's set to `Wasmer`, so in case of `Wasmer` it's not necessary to call this function. -/// Also sets the store clear counter limit, which is used to clear the store after reaching a certain limit. -pub fn init(sandbox_backend: sandbox_env::SandboxBackend, store_clear_counter_limit: Option) { - SANDBOX_BACKEND_TYPE.store(sandbox_backend, Ordering::SeqCst); - SANDBOX_STORE_CLEAR_COUNTER_LIMIT.store( - store_clear_counter_limit.unwrap_or(DEFAULT_SANDBOX_STORE_CLEAR_COUNTER_LIMIT), - Ordering::SeqCst, - ); -} - -struct SupervisorContext<'a, 'b> { - caller: &'a mut Caller<'b, StoreData>, - dispatch_thunk: Func, - /// Custom data to propagate it in supervisor export functions - state: u32, -} -impl sandbox_env::SupervisorContext for SupervisorContext<'_, '_> { - fn invoke( - &mut self, + fn invoke_dispatch_thunk( + caller: &mut Self::Caller<'_>, + dispatch_thunk_id: u32, invoke_args_ptr: Pointer, invoke_args_len: WordSize, - func_idx: sandbox_env::SupervisorFuncIndex, + state: u32, + func_idx: gear_sandbox_host::sandbox::SupervisorFuncIndex, ) -> gear_sandbox_host::error::Result { + let table = caller + .data() + .table + .expect("Runtime doesn't have a table; sandbox is unavailable"); + let table_item = table + .get(caller.as_context_mut(), dispatch_thunk_id) + .expect("dispatch_thunk_id is out of bounds"); + let dispatch_thunk = *table_item + .funcref() + .expect("dispatch_thunk_idx should be a funcref") + .expect("dispatch_thunk_idx should point to actual func"); + let mut ret_vals = [Val::null()]; - let result = self.dispatch_thunk.call( - &mut *self.caller, + let result = dispatch_thunk.call( + &mut *caller, &[ Val::I32(u32::from(invoke_args_ptr) as i32), Val::I32(invoke_args_len as i32), - Val::I32(self.state as i32), + Val::I32(state as i32), Val::I32(usize::from(func_idx) as i32), ], &mut ret_vals, @@ -123,67 +96,39 @@ impl sandbox_env::SupervisorContext for SupervisorContext<'_, '_> { } fn read_memory_into( - &self, + caller: &Self::Caller<'_>, address: Pointer, dest: &mut [u8], - ) -> sp_wasm_interface::Result<()> { - util::read_memory_into(self.caller.as_context(), address, dest) + ) -> Result<(), String> { + util::read_memory_into(caller.as_context(), address, dest).map_err(|err| err.to_string()) } - fn write_memory(&mut self, address: Pointer, data: &[u8]) -> sp_wasm_interface::Result<()> { - util::write_memory_from(self.caller.as_context_mut(), address, data) + fn write_memory( + caller: &mut Self::Caller<'_>, + address: Pointer, + data: &[u8], + ) -> Result<(), String> { + util::write_memory_from(caller.as_context_mut(), address, data) + .map_err(|err| err.to_string()) } - fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result> { - util::allocate_memory(self.caller, size) + fn allocate_memory( + caller: &mut Self::Caller<'_>, + size: WordSize, + ) -> Result, String> { + util::allocate_memory(caller, size).map_err(|err| err.to_string()) } - fn deallocate_memory(&mut self, ptr: Pointer) -> sp_wasm_interface::Result<()> { - util::deallocate_memory(self.caller, ptr) + fn deallocate_memory(caller: &mut Self::Caller<'_>, ptr: Pointer) -> Result<(), String> { + util::deallocate_memory(caller, ptr).map_err(|err| err.to_string()) } } -fn read_memory( - ctx: impl AsContext, - address: Pointer, - size: WordSize, -) -> sp_wasm_interface::Result> { - let mut vec = vec![0; size as usize]; - util::read_memory_into(ctx, address, &mut vec)?; - Ok(vec) -} - -fn trace(func: &str, caller: &Caller<'_, StoreData>) { - let data_ptr: *const _ = caller.data(); - let caller_ptr: *const _ = caller; - let thread_id = std::thread::current().id(); - - log::trace!( - "{func}; data_ptr = {:#x?}, caller_ptr = {:#x?}, thread_id = {:?}", - data_ptr as usize, - caller_ptr as usize, - thread_id, - ); -} - pub fn get_buff(context: &mut dyn FunctionContext, memory_idx: u32) -> HostPointer { - use gear_sandbox_host::util::MemoryTransfer; - let mut method_result: HostPointer = u32::MAX.into(); sp_wasm_interface::with_caller_mut(context, |caller| { - trace("get_buff", caller); - - let data_ptr: *const _ = caller.data(); - method_result = SANDBOXES.with(|sandboxes| { - let mut memory = sandboxes - .borrow_mut() - .get(data_ptr as usize) - .memory(memory_idx) - .expect("Failed to get memory buffer pointer: cannot get backend memory"); - - memory.get_buff() as HostPointer - }); + method_result = host::get_buff::(caller, memory_idx); }); method_result @@ -197,18 +142,7 @@ pub fn get_global_val( let mut method_result = None::; sp_wasm_interface::with_caller_mut(context, |caller| { - trace("get_global_val", caller); - - let data_ptr: *const _ = caller.data(); - method_result = SANDBOXES.with(|sandboxes| { - sandboxes - .borrow_mut() - .get(data_ptr as usize) - .instance(instance_idx) - .map(|i| i.get_global_val(name)) - .map_err(|e| e.to_string()) - .expect("Failed to get global from sandbox") - }); + method_result = host::get_global_val::(caller, instance_idx, name); }); method_result @@ -218,19 +152,7 @@ pub fn get_instance_ptr(context: &mut dyn FunctionContext, instance_id: u32) -> let mut method_result: HostPointer = u32::MAX.into(); sp_wasm_interface::with_caller_mut(context, |caller| { - trace("get_instance_ptr", caller); - - let data_ptr: *const _ = caller.data(); - method_result = SANDBOXES.with(|sandboxes| { - let instance = sandboxes - .borrow_mut() - .get(data_ptr as usize) - .instance(instance_id) - .expect("Failed to get sandboxed instance"); - - instance.as_ref().get_ref() as *const gear_sandbox_host::sandbox::SandboxInstance - as HostPointer - }); + method_result = host::get_instance_ptr::(caller, instance_id); }); method_result @@ -238,16 +160,7 @@ pub fn get_instance_ptr(context: &mut dyn FunctionContext, instance_id: u32) -> pub fn instance_teardown(context: &mut dyn FunctionContext, instance_idx: u32) { sp_wasm_interface::with_caller_mut(context, |caller| { - trace("instance_teardown", caller); - - let data_ptr: *const _ = caller.data(); - SANDBOXES.with(|sandboxes| { - sandboxes - .borrow_mut() - .get(data_ptr as usize) - .instance_teardown(instance_idx) - .expect("Failed to teardown sandbox instance") - }) + host::instance_teardown::(caller, instance_idx); }); } @@ -262,70 +175,14 @@ pub fn instantiate( let mut method_result = u32::MAX; sp_wasm_interface::with_caller_mut(context, |caller| { - trace("instantiate", caller); - - // Extract a dispatch thunk from the instance's table by the specified index. - let dispatch_thunk = { - let table = caller - .data() - .table - .expect("Runtime doesn't have a table; sandbox is unavailable"); - let table_item = table.get(caller.as_context_mut(), dispatch_thunk_id); - - *table_item - .expect("dispatch_thunk_id is out of bounds") - .funcref() - .expect("dispatch_thunk_idx should be a funcref") - .expect("dispatch_thunk_idx should point to actual func") - }; - - let data_ptr: *const _ = caller.data(); - let store_data_key = data_ptr as usize; - let guest_env = SANDBOXES.with(|sandboxes| { - let mut store_ref = sandboxes.borrow_mut(); - let store = store_ref.get(store_data_key); - - sandbox_env::GuestEnvironment::decode(store, raw_env_def) - }); - let Ok(guest_env) = guest_env else { - method_result = sandbox_env::env::ERR_MODULE; - return; - }; - - // Catch any potential panics so that we can properly restore the sandbox store - // which we've destructively borrowed. - let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { - SANDBOXES.with(|sandboxes| { - sandboxes.borrow_mut().get(store_data_key).instantiate( - version, - wasm_code, - guest_env, - &mut SupervisorContext { - caller, - dispatch_thunk, - state: state_ptr.into(), - }, - ) - }) - })); - - let result = match result { - Ok(result) => result, - Err(error) => std::panic::resume_unwind(error), - }; - - let instance_idx_or_err_code = match result { - Ok(instance) => SANDBOXES.with(|sandboxes| { - let mut store_ref = sandboxes.borrow_mut(); - let store = store_ref.get(store_data_key); - - instance.register(store, dispatch_thunk) - }), - Err(sandbox_env::InstantiationError::StartTrapped) => sandbox_env::env::ERR_EXECUTION, - Err(_) => sandbox_env::env::ERR_MODULE, - }; - - method_result = instance_idx_or_err_code; + method_result = host::instantiate::( + caller, + dispatch_thunk_id, + wasm_code, + raw_env_def, + state_ptr, + version, + ); }); method_result @@ -335,70 +192,23 @@ pub fn invoke( context: &mut dyn FunctionContext, instance_idx: u32, function: &str, - mut args: &[u8], + args: &[u8], return_val_ptr: Pointer, return_val_len: u32, state_ptr: Pointer, ) -> u32 { - use sandbox_env::SupervisorContext as _; - let mut method_result = u32::MAX; sp_wasm_interface::with_caller_mut(context, |caller| { - trace("invoke", caller); - log::trace!("invoke, instance_idx={instance_idx}"); - - // Deserialize arguments and convert them into wasmi types. - let args = Vec::::decode(&mut args) - .expect("Can't decode serialized arguments for the invocation") - .into_iter() - .collect::>(); - - let data_ptr: *const _ = caller.data(); - let (instance, dispatch_thunk) = SANDBOXES.with(|sandboxes| { - let mut store_ref = sandboxes.borrow_mut(); - let store = store_ref.get(data_ptr as usize); - - let instance = store - .instance(instance_idx) - .expect("backend instance not found"); - - let dispatch_thunk = store - .dispatch_thunk(instance_idx) - .expect("dispatch_thunk not found"); - - (instance, dispatch_thunk) - }); - - let mut sandbox_context = SupervisorContext { + method_result = host::invoke::( caller, - dispatch_thunk, - state: state_ptr.into(), - }; - let result = instance.invoke(function, &args, &mut sandbox_context); - - method_result = match result { - Ok(None) => sandbox_env::env::ERR_OK, - Ok(Some(val)) => { - // Serialize return value and write it back into the memory. - sp_wasm_interface::ReturnValue::Value(val).using_encoded(|val| { - if val.len() > return_val_len as usize { - panic!("Return value buffer is too small"); - } - - sandbox_context - .write_memory(return_val_ptr, val) - .expect("can't write return value"); - - sandbox_env::env::ERR_OK - }) - } - Err(e) => { - log::trace!("e = {e:?}"); - - sandbox_env::env::ERR_EXECUTION - } - }; + instance_idx, + function, + args, + return_val_ptr, + return_val_len, + state_ptr, + ); }); method_result @@ -411,59 +221,21 @@ pub fn memory_get( buf_ptr: Pointer, buf_len: u32, ) -> u32 { - use gear_sandbox_host::util::MemoryTransfer; - let mut method_result = u32::MAX; sp_wasm_interface::with_caller_mut(context, |caller| { - trace("memory_get", caller); - - let data_ptr: *const _ = caller.data(); - let sandboxed_memory = SANDBOXES.with(|sandboxes| { - sandboxes - .borrow_mut() - .get(data_ptr as usize) - .memory(memory_idx) - .expect("sandboxed memory not found") - }); - - let len = buf_len as usize; - - let buffer = match sandboxed_memory.read(Pointer::new(offset), len) { - Err(_) => { - method_result = sandbox_env::env::ERR_OUT_OF_BOUNDS; - return; - } - Ok(buffer) => buffer, - }; - - method_result = match util::write_memory_from(caller, buf_ptr, &buffer) { - Ok(_) => sandbox_env::env::ERR_OK, - Err(_) => sandbox_env::env::ERR_OUT_OF_BOUNDS, - }; + method_result = + host::memory_get::(caller, memory_idx, offset, buf_ptr, buf_len); }); method_result } pub fn memory_grow(context: &mut dyn FunctionContext, memory_idx: u32, size: u32) -> u32 { - use gear_sandbox_host::util::MemoryTransfer; - let mut method_result = u32::MAX; sp_wasm_interface::with_caller_mut(context, |caller| { - trace("memory_grow", caller); - - let data_ptr: *const _ = caller.data(); - method_result = SANDBOXES.with(|sandboxes| { - let mut memory = sandboxes - .borrow_mut() - .get(data_ptr as usize) - .memory(memory_idx) - .expect("Failed to grow memory: cannot get backend memory"); - - memory.memory_grow(size).expect("Failed to grow memory") - }); + method_result = host::memory_grow::(caller, memory_idx, size); }); method_result @@ -473,28 +245,7 @@ pub fn memory_new(context: &mut dyn FunctionContext, initial: u32, maximum: u32) let mut method_result = u32::MAX; sp_wasm_interface::with_caller_mut(context, |caller| { - trace("memory_new", caller); - - let data_ptr: *const _ = caller.data(); - method_result = SANDBOXES.with(|sandboxes| { - // HACK: It was discovered that starting with version 4.0, Wasmer experiences a slowdown - // when creating a large number of memory/instances beyond a certain threshold. - // The usual method to clear the store doesn't work for benchmarks (see `Sandboxes::get`) - // or when too many instances/memories are created **within a single block**, as the store - // is only cleared at the start of a new block. - // This is a temporary solution to reset the store after reaching a certain limit - // (see `SANDBOX_STORE_CLEAR_COUNTER_LIMIT`) for memory/instances. - // Otherwise, the store grows too large, leading to performance degradation during - // normal node execution and benchmarks. - sandboxes.borrow_mut().clear(); - - sandboxes - .borrow_mut() - .get(data_ptr as usize) - .new_memory(initial, maximum) - .map_err(|e| e.to_string()) - .expect("Failed to create new memory with sandbox") - }); + method_result = host::memory_new::(caller, initial, maximum); }); method_result @@ -507,54 +258,21 @@ pub fn memory_set( val_ptr: Pointer, val_len: u32, ) -> u32 { - use gear_sandbox_host::util::MemoryTransfer; - let mut method_result = u32::MAX; sp_wasm_interface::with_caller_mut(context, |caller| { - trace("memory_set", caller); - - let Ok(buffer) = read_memory(&mut *caller, val_ptr, val_len) else { - method_result = sandbox_env::env::ERR_OUT_OF_BOUNDS; - return; - }; - - let data_ptr: *const _ = caller.data(); - method_result = SANDBOXES.with(|sandboxes| { - let sandboxed_memory = sandboxes - .borrow_mut() - .get(data_ptr as usize) - .memory(memory_idx) - .expect("memory_set: not found"); - - match sandboxed_memory.write_from(Pointer::new(offset), &buffer) { - Ok(_) => sandbox_env::env::ERR_OK, - Err(_) => sandbox_env::env::ERR_OUT_OF_BOUNDS, - } - }); + method_result = + host::memory_set::(caller, memory_idx, offset, val_ptr, val_len); }); method_result } pub fn memory_size(context: &mut dyn FunctionContext, memory_idx: u32) -> u32 { - use gear_sandbox_host::util::MemoryTransfer; - let mut method_result = 0; sp_wasm_interface::with_caller_mut(context, |caller| { - trace("memory_size", caller); - - let data_ptr: *const _ = caller.data(); - method_result = SANDBOXES.with(|sandboxes| { - let mut memory = sandboxes - .borrow_mut() - .get(data_ptr as usize) - .memory(memory_idx) - .expect("Failed to get memory size: cannot get backend memory"); - - memory.memory_size() - }); + method_result = host::memory_size::(caller, memory_idx); }); method_result @@ -562,16 +280,7 @@ pub fn memory_size(context: &mut dyn FunctionContext, memory_idx: u32) -> u32 { pub fn memory_teardown(context: &mut dyn FunctionContext, memory_idx: u32) { sp_wasm_interface::with_caller_mut(context, |caller| { - trace("memory_teardown", caller); - - let data_ptr: *const _ = caller.data(); - SANDBOXES.with(|sandboxes| { - sandboxes - .borrow_mut() - .get(data_ptr as usize) - .memory_teardown(memory_idx) - .expect("Failed to teardown sandbox memory") - }); + host::memory_teardown::(caller, memory_idx); }); } @@ -584,39 +293,9 @@ pub fn set_global_val( let mut method_result = u32::MAX; sp_wasm_interface::with_caller_mut(context, |caller| { - trace("set_global_val", caller); - - log::trace!("set_global_val, instance_idx={instance_idx}"); - - let data_ptr: *const _ = caller.data(); - let result = SANDBOXES.with(|sandboxes| { - let instance = sandboxes - .borrow_mut() - .get(data_ptr as usize) - .instance(instance_idx) - .map_err(|e| e.to_string()) - .expect("Failed to set global in sandbox"); - - instance.set_global_val(name, value) - }); - - log::trace!("set_global_val, name={name}, value={value:?}, result={result:?}",); - - method_result = match result { - Ok(None) => sandbox_env::env::ERROR_GLOBALS_NOT_FOUND, - Ok(Some(_)) => sandbox_env::env::ERROR_GLOBALS_OK, - Err(_) => sandbox_env::env::ERROR_GLOBALS_OTHER, - }; + method_result = + host::set_global_val::(caller, instance_idx, name, value); }); method_result } - -const DEFAULT_SANDBOX_STORE_CLEAR_COUNTER_LIMIT: u32 = 50; - -static SANDBOX_STORE_CLEAR_COUNTER_LIMIT: AtomicU32 = - AtomicU32::new(DEFAULT_SANDBOX_STORE_CLEAR_COUNTER_LIMIT); - -thread_local! { - static SANDBOX_STORE_CLEAR_COUNTER: RefCell = const { RefCell::new(0) }; -} diff --git a/runtime-interface/src/lib.rs b/runtime-interface/src/lib.rs index 2fbe8192995..090dc8486df 100644 --- a/runtime-interface/src/lib.rs +++ b/runtime-interface/src/lib.rs @@ -42,8 +42,9 @@ use { gear_lazy_pages_common::ProcessAccessError, }; +#[cfg(feature = "sandbox")] pub use gear_sandbox_interface::sandbox; -#[cfg(feature = "std")] +#[cfg(feature = "sandbox")] pub use gear_sandbox_interface::{ Instantiate, SandboxBackend, detail as sandbox_detail, init as sandbox_init, }; diff --git a/sandbox/host/src/host.rs b/sandbox/host/src/host.rs new file mode 100644 index 00000000000..040ef46379c --- /dev/null +++ b/sandbox/host/src/host.rs @@ -0,0 +1,526 @@ +// This file is part of Gear. +// +// Copyright (C) Gear Technologies Inc. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![allow(missing_docs)] + +use core::{ + cell::RefCell, + marker::PhantomData, + sync::atomic::{AtomicU32, Ordering}, +}; +use std::panic::{self, AssertUnwindSafe}; + +use parity_scale_codec::{Decode, Encode}; + +use crate::sandbox::{self as sandbox_env, SupervisorContext as _}; + +pub use crate::{ + error::Result as HostResult, + sandbox::{SandboxBackend, SupervisorFuncIndex, env::Instantiate}, +}; +pub use sp_wasm_interface_common::{HostPointer, Pointer, ReturnValue, Value, WordSize}; + +static SANDBOX_BACKEND_TYPE: sandbox_env::AtomicSandboxBackend = + sandbox_env::AtomicSandboxBackend::new(sandbox_env::SandboxBackend::Wasmer); + +const DEFAULT_SANDBOX_STORE_CLEAR_COUNTER_LIMIT: u32 = 50; + +static SANDBOX_STORE_CLEAR_COUNTER_LIMIT: AtomicU32 = + AtomicU32::new(DEFAULT_SANDBOX_STORE_CLEAR_COUNTER_LIMIT); + +pub fn init(sandbox_backend: sandbox_env::SandboxBackend, store_clear_counter_limit: Option) { + SANDBOX_BACKEND_TYPE.store(sandbox_backend, Ordering::SeqCst); + SANDBOX_STORE_CLEAR_COUNTER_LIMIT.store( + store_clear_counter_limit.unwrap_or(DEFAULT_SANDBOX_STORE_CLEAR_COUNTER_LIMIT), + Ordering::SeqCst, + ); +} + +pub struct Sandboxes { + store_data_key: usize, + store: sandbox_env::SandboxComponents, +} + +impl Sandboxes { + pub fn new() -> Self { + let sandbox_backend = SANDBOX_BACKEND_TYPE.load(Ordering::SeqCst); + + Self { + store_data_key: 0, + store: sandbox_env::SandboxComponents::new(sandbox_backend), + } + } + + pub fn get(&mut self, store_data_key: usize) -> &mut sandbox_env::SandboxComponents { + if self.store_data_key != store_data_key { + self.store_data_key = store_data_key; + self.store.clear(); + } + + &mut self.store + } + + pub fn clear(&mut self, counter: &mut u32) { + if *counter >= SANDBOX_STORE_CLEAR_COUNTER_LIMIT.load(Ordering::SeqCst) { + *counter = 0; + self.store.clear(); + } + *counter += 1; + } +} + +impl Default for Sandboxes { + fn default() -> Self { + Self::new() + } +} + +#[derive(Default)] +struct ThreadState { + sandboxes: Sandboxes, + clear_counter: u32, +} + +thread_local! { + static THREAD_STATE: RefCell = RefCell::new(ThreadState::default()); +} + +pub trait ContextOps { + type Caller<'a>; + + fn trace(func: &str, caller: &Self::Caller<'_>); + fn store_data_key(caller: &Self::Caller<'_>) -> usize; + + fn invoke_dispatch_thunk( + caller: &mut Self::Caller<'_>, + dispatch_thunk_id: u32, + invoke_args_ptr: Pointer, + invoke_args_len: WordSize, + state: u32, + func_idx: SupervisorFuncIndex, + ) -> HostResult; + + fn read_memory_into( + caller: &Self::Caller<'_>, + address: Pointer, + dest: &mut [u8], + ) -> Result<(), String>; + + fn write_memory( + caller: &mut Self::Caller<'_>, + address: Pointer, + data: &[u8], + ) -> Result<(), String>; + + fn allocate_memory( + caller: &mut Self::Caller<'_>, + size: WordSize, + ) -> Result, String>; + + fn deallocate_memory(caller: &mut Self::Caller<'_>, ptr: Pointer) -> Result<(), String>; +} + +fn with_thread_state(f: impl FnOnce(&mut ThreadState) -> R) -> R { + THREAD_STATE.with(|state| { + let mut state = state.borrow_mut(); + f(&mut state) + }) +} + +pub struct SupervisorContext<'a, 'b, O: ContextOps> { + pub caller: &'a mut O::Caller<'b>, + pub dispatch_thunk_id: u32, + pub state: u32, + _marker: PhantomData, +} + +impl<'a, 'b, O: ContextOps> SupervisorContext<'a, 'b, O> { + pub fn new(caller: &'a mut O::Caller<'b>, dispatch_thunk_id: u32, state: u32) -> Self { + Self { + caller, + dispatch_thunk_id, + state, + _marker: PhantomData, + } + } +} + +impl sandbox_env::SupervisorContext for SupervisorContext<'_, '_, O> { + fn invoke( + &mut self, + invoke_args_ptr: Pointer, + invoke_args_len: WordSize, + func_idx: SupervisorFuncIndex, + ) -> HostResult { + O::invoke_dispatch_thunk( + self.caller, + self.dispatch_thunk_id, + invoke_args_ptr, + invoke_args_len, + self.state, + func_idx, + ) + } + + fn read_memory_into(&self, address: Pointer, dest: &mut [u8]) -> Result<(), String> { + O::read_memory_into(self.caller, address, dest) + } + + fn write_memory(&mut self, address: Pointer, data: &[u8]) -> Result<(), String> { + O::write_memory(self.caller, address, data) + } + + fn allocate_memory(&mut self, size: WordSize) -> Result, String> { + O::allocate_memory(self.caller, size) + } + + fn deallocate_memory(&mut self, ptr: Pointer) -> Result<(), String> { + O::deallocate_memory(self.caller, ptr) + } +} + +fn read_memory( + caller: &O::Caller<'_>, + address: Pointer, + size: WordSize, +) -> Result, String> { + let mut vec = vec![0; size as usize]; + O::read_memory_into(caller, address, &mut vec)?; + Ok(vec) +} + +pub fn get_buff( + caller: &mut O::Caller<'_>, + memory_idx: u32, +) -> HostPointer { + use crate::util::MemoryTransfer; + + O::trace("get_buff", caller); + + with_thread_state(|state| { + state + .sandboxes + .get(O::store_data_key(caller)) + .memory(memory_idx) + .expect("Failed to get memory buffer pointer: cannot get backend memory") + .get_buff() as HostPointer + }) +} + +pub fn get_global_val( + caller: &mut O::Caller<'_>, + instance_idx: u32, + name: &str, +) -> Option { + O::trace("get_global_val", caller); + + with_thread_state(|state| { + state + .sandboxes + .get(O::store_data_key(caller)) + .instance(instance_idx) + .map(|instance| instance.get_global_val(name)) + .map_err(|err| err.to_string()) + .expect("Failed to get global from sandbox") + }) +} + +pub fn get_instance_ptr( + caller: &mut O::Caller<'_>, + instance_idx: u32, +) -> HostPointer { + O::trace("get_instance_ptr", caller); + + let instance = with_thread_state(|state| { + state + .sandboxes + .get(O::store_data_key(caller)) + .instance(instance_idx) + .expect("Failed to get sandboxed instance") + }); + + instance.as_ref().get_ref() as *const sandbox_env::SandboxInstance as HostPointer +} + +pub fn instance_teardown(caller: &mut O::Caller<'_>, instance_idx: u32) { + O::trace("instance_teardown", caller); + + with_thread_state(|state| { + state + .sandboxes + .get(O::store_data_key(caller)) + .instance_teardown(instance_idx) + .expect("Failed to teardown sandbox instance"); + }); +} + +pub fn instantiate( + caller: &mut O::Caller<'_>, + dispatch_thunk_id: u32, + wasm_code: &[u8], + raw_env_def: &[u8], + state_ptr: Pointer, + version: Instantiate, +) -> u32 { + O::trace("instantiate", caller); + + let store_data_key = O::store_data_key(caller); + + let guest_env = with_thread_state(|state| { + let store = state.sandboxes.get(store_data_key); + sandbox_env::GuestEnvironment::decode(store, raw_env_def) + }); + + let Ok(guest_env) = guest_env else { + return sandbox_env::env::ERR_MODULE; + }; + + let result = panic::catch_unwind(AssertUnwindSafe(|| { + with_thread_state(|state| { + state.sandboxes.get(store_data_key).instantiate( + version, + wasm_code, + guest_env, + &mut SupervisorContext::::new(caller, dispatch_thunk_id, state_ptr.into()), + ) + }) + })); + + let result = match result { + Ok(result) => result, + Err(error) => panic::resume_unwind(error), + }; + + match result { + Ok(instance) => with_thread_state(|state| { + let store = state.sandboxes.get(store_data_key); + instance.register(store, dispatch_thunk_id) + }), + Err(sandbox_env::InstantiationError::StartTrapped) => sandbox_env::env::ERR_EXECUTION, + Err(_) => sandbox_env::env::ERR_MODULE, + } +} + +#[allow(clippy::too_many_arguments)] +pub fn invoke( + caller: &mut O::Caller<'_>, + instance_idx: u32, + function: &str, + mut args: &[u8], + return_val_ptr: Pointer, + return_val_len: u32, + state_ptr: Pointer, +) -> u32 { + O::trace("invoke", caller); + log::trace!("invoke, instance_idx={instance_idx}"); + + let args = Vec::::decode(&mut args) + .expect("Can't decode serialized arguments for the invocation") + .into_iter() + .collect::>(); + + let (instance, dispatch_thunk_id) = with_thread_state(|state| { + let store = state.sandboxes.get(O::store_data_key(caller)); + + let instance = store + .instance(instance_idx) + .expect("backend instance not found"); + + let dispatch_thunk_id = store + .dispatch_thunk_id(instance_idx) + .expect("dispatch_thunk not found"); + + (instance, dispatch_thunk_id) + }); + + let mut sandbox_context = + SupervisorContext::::new(caller, dispatch_thunk_id, state_ptr.into()); + + match instance.invoke(function, &args, &mut sandbox_context) { + Ok(None) => sandbox_env::env::ERR_OK, + Ok(Some(val)) => { + let encoded = ReturnValue::Value(val).encode(); + if encoded.len() > return_val_len as usize { + panic!("Return value buffer is too small"); + } + + sandbox_context + .write_memory(return_val_ptr, &encoded) + .expect("can't write return value"); + + sandbox_env::env::ERR_OK + } + Err(err) => { + log::trace!("invoke error = {err:?}"); + sandbox_env::env::ERR_EXECUTION + } + } +} + +pub fn memory_get( + caller: &mut O::Caller<'_>, + memory_idx: u32, + offset: u32, + buf_ptr: Pointer, + buf_len: u32, +) -> u32 { + use crate::util::MemoryTransfer; + + O::trace("memory_get", caller); + + let sandboxed_memory = with_thread_state(|state| { + state + .sandboxes + .get(O::store_data_key(caller)) + .memory(memory_idx) + .expect("sandboxed memory not found") + }); + + let buffer = match sandboxed_memory.read(Pointer::new(offset), buf_len as usize) { + Err(_) => return sandbox_env::env::ERR_OUT_OF_BOUNDS, + Ok(buffer) => buffer, + }; + + match O::write_memory(caller, buf_ptr, &buffer) { + Ok(()) => sandbox_env::env::ERR_OK, + Err(_) => sandbox_env::env::ERR_OUT_OF_BOUNDS, + } +} + +pub fn memory_grow( + caller: &mut O::Caller<'_>, + memory_idx: u32, + size: u32, +) -> u32 { + use crate::util::MemoryTransfer; + + O::trace("memory_grow", caller); + + with_thread_state(|state| { + state + .sandboxes + .get(O::store_data_key(caller)) + .memory(memory_idx) + .expect("Failed to grow memory: cannot get backend memory") + .memory_grow(size) + .expect("Failed to grow memory") + }) +} + +pub fn memory_new( + caller: &mut O::Caller<'_>, + initial: u32, + maximum: u32, +) -> u32 { + O::trace("memory_new", caller); + + with_thread_state(|state| { + state.sandboxes.clear(&mut state.clear_counter); + state + .sandboxes + .get(O::store_data_key(caller)) + .new_memory(initial, maximum) + .map_err(|err| err.to_string()) + .expect("Failed to create new memory with sandbox") + }) +} + +pub fn memory_set( + caller: &mut O::Caller<'_>, + memory_idx: u32, + offset: u32, + val_ptr: Pointer, + val_len: u32, +) -> u32 { + use crate::util::MemoryTransfer; + + O::trace("memory_set", caller); + + let Ok(buffer) = read_memory::(caller, val_ptr, val_len) else { + return sandbox_env::env::ERR_OUT_OF_BOUNDS; + }; + + let sandboxed_memory = with_thread_state(|state| { + state + .sandboxes + .get(O::store_data_key(caller)) + .memory(memory_idx) + .expect("memory_set: not found") + }); + + match sandboxed_memory.write_from(Pointer::new(offset), &buffer) { + Ok(()) => sandbox_env::env::ERR_OK, + Err(_) => sandbox_env::env::ERR_OUT_OF_BOUNDS, + } +} + +pub fn memory_size(caller: &mut O::Caller<'_>, memory_idx: u32) -> u32 { + use crate::util::MemoryTransfer; + + O::trace("memory_size", caller); + + with_thread_state(|state| { + state + .sandboxes + .get(O::store_data_key(caller)) + .memory(memory_idx) + .expect("Failed to get memory size: cannot get backend memory") + .memory_size() + }) +} + +pub fn memory_teardown(caller: &mut O::Caller<'_>, memory_idx: u32) { + O::trace("memory_teardown", caller); + + with_thread_state(|state| { + state + .sandboxes + .get(O::store_data_key(caller)) + .memory_teardown(memory_idx) + .expect("Failed to teardown sandbox memory"); + }); +} + +pub fn set_global_val( + caller: &mut O::Caller<'_>, + instance_idx: u32, + name: &str, + value: Value, +) -> u32 { + O::trace("set_global_val", caller); + log::trace!("set_global_val, instance_idx={instance_idx}"); + + let result = with_thread_state(|state| { + let instance = state + .sandboxes + .get(O::store_data_key(caller)) + .instance(instance_idx) + .map_err(|err| err.to_string()) + .expect("Failed to set global in sandbox"); + + instance.set_global_val(name, value) + }); + + log::trace!("set_global_val, name={name}, value={value:?}, result={result:?}"); + + match result { + Ok(None) => sandbox_env::env::ERROR_GLOBALS_NOT_FOUND, + Ok(Some(_)) => sandbox_env::env::ERROR_GLOBALS_OK, + Err(_) => sandbox_env::env::ERROR_GLOBALS_OTHER, + } +} diff --git a/sandbox/host/src/lib.rs b/sandbox/host/src/lib.rs index f3ddba7aaa8..95eda8d40df 100644 --- a/sandbox/host/src/lib.rs +++ b/sandbox/host/src/lib.rs @@ -21,6 +21,8 @@ #![warn(missing_docs)] pub mod error; +/// Shared host-side sandbox glue for different supervisor embeddings. +pub mod host; pub mod sandbox; pub mod util; diff --git a/sandbox/host/src/sandbox.rs b/sandbox/host/src/sandbox.rs index d6072378235..e26d0a6a391 100644 --- a/sandbox/host/src/sandbox.rs +++ b/sandbox/host/src/sandbox.rs @@ -376,8 +376,8 @@ impl GuestEnvironment { /// Decodes an environment definition from the given raw bytes. /// /// Returns `Err` if the definition cannot be decoded. - pub fn decode
( - store: &SandboxComponents
, + pub fn decode( + store: &SandboxComponents, raw_env_def: &[u8], ) -> std::result::Result { let (imports, guest_to_supervisor_mapping) = @@ -399,9 +399,9 @@ pub struct UnregisteredInstance { impl UnregisteredInstance { /// Finalizes instantiation of this module. - pub fn register
(self, store: &mut SandboxComponents
, dispatch_thunk: DT) -> u32 { + pub fn register(self, store: &mut SandboxComponents, dispatch_thunk_id: u32) -> u32 { // At last, register the instance. - store.register_sandbox_instance(self.sandbox_instance, dispatch_thunk) + store.register_sandbox_instance(self.sandbox_instance, dispatch_thunk_id) } } @@ -516,19 +516,17 @@ impl BackendContext { } /// This struct keeps track of all sandboxed components. -/// -/// This is generic over a supervisor function reference type. -pub struct SandboxComponents
{ +pub struct SandboxComponents { /// Stores the instance and the dispatch thunk associated to per instance. /// /// Instances are `Some` until torn down. - instances: Vec>, DT)>>, + instances: Vec>, u32)>>, /// Memories are `Some` until torn down. memories: Vec>, backend_context: BackendContext, } -impl SandboxComponents
{ +impl SandboxComponents { /// Create a new empty sandbox store. pub fn new(backend: SandboxBackend) -> Self { SandboxComponents { @@ -607,13 +605,13 @@ impl SandboxComponents
{ /// Returns `Err` If `instance_idx` isn't a valid index of an instance or /// instance is already torndown. #[allow(clippy::useless_asref)] - pub fn dispatch_thunk(&self, instance_idx: u32) -> Result
{ + pub fn dispatch_thunk_id(&self, instance_idx: u32) -> Result { self.instances .get(instance_idx as usize) .as_ref() .ok_or("Trying to access a non-existent instance")? .as_ref() - .map(|v| v.1.clone()) + .map(|v| v.1) .ok_or_else(|| "Trying to access a torndown instance".into()) } @@ -696,15 +694,15 @@ impl SandboxComponents
{ } // Private routines -impl
SandboxComponents
{ +impl SandboxComponents { fn register_sandbox_instance( &mut self, sandbox_instance: SandboxInstance, - dispatch_thunk: DT, + dispatch_thunk_id: u32, ) -> u32 { let instance_idx = self.instances.len(); self.instances - .push(Some((Rc::pin(sandbox_instance), dispatch_thunk))); + .push(Some((Rc::pin(sandbox_instance), dispatch_thunk_id))); instance_idx as u32 } } diff --git a/utils/gear-replay-cli/Cargo.toml b/utils/gear-replay-cli/Cargo.toml index e585192540a..d3d9b6f2d08 100644 --- a/utils/gear-replay-cli/Cargo.toml +++ b/utils/gear-replay-cli/Cargo.toml @@ -11,7 +11,7 @@ path = "src/main.rs" [dependencies] # Internal -gear-runtime-interface.workspace = true +gear-runtime-interface = { workspace = true, features = ["std", "sandbox"] } runtime-primitives.workspace = true service = { workspace = true, optional = true } diff --git a/utils/gear-workspace-hack/Cargo.toml b/utils/gear-workspace-hack/Cargo.toml index d148da49993..6c69ca14fef 100644 --- a/utils/gear-workspace-hack/Cargo.toml +++ b/utils/gear-workspace-hack/Cargo.toml @@ -214,7 +214,7 @@ branch = "gear-polkadot-stable2409-wasm32v1-none" features = ["test-helpers"] ### BEGIN HAKARI SECTION -[dependencies] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] aes = { version = "0.8", default-features = false, features = ["zeroize"] } ahash = { version = "0.8" } alloy = { version = "2", features = ["kzg", "node-bindings", "provider-anvil-api", "provider-ws", "rpc-types-beacon", "rpc-types-eth", "signer-mnemonic"] } @@ -231,6 +231,7 @@ alloy-signer-local = { version = "2", default-features = false, features = ["mne alloy-sol-type-parser = { version = "1", default-features = false, features = ["serde", "std"] } alloy-sol-types = { version = "1", features = ["json"] } anyhow = { version = "1" } +arbitrary = { version = "1", default-features = false, features = ["derive"] } ark-bls12-381 = { version = "0.4", default-features = false, features = ["curve", "std"] } ark-bls12-381-ext = { version = "0.4", default-features = false, features = ["std"] } ark-ec = { version = "0.4", features = ["parallel"] } @@ -251,6 +252,7 @@ bounded-collections = { version = "0.2", default-features = false, features = [" bp-header-chain = { git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409-wasm32v1-none", default-features = false, features = ["std"] } bp-runtime = { git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409-wasm32v1-none", default-features = false, features = ["std"] } bs58 = { version = "0.5", features = ["check"] } +bumpalo = { version = "3", features = ["allocator-api2"] } byte-slice-cast = { version = "1", default-features = false, features = ["std"] } bytemuck = { version = "1", default-features = false, features = ["const_zeroed", "derive", "min_const_generics", "must_cast"] } byteorder = { version = "1" } @@ -261,6 +263,7 @@ clap_builder = { version = "4", default-features = false, features = ["color", " concurrent-queue = { version = "2" } const-hex = { version = "1", features = ["core-error", "serde"] } constant_time_eq = { version = "0.4", default-features = false, features = ["std"] } +cranelift-bitset = { version = "0.130", default-features = false, features = ["enable-serde"] } crc32fast = { version = "1" } crossbeam-channel = { version = "0.5" } crossbeam-utils = { version = "0.8" } @@ -285,6 +288,7 @@ event-listener = { version = "5" } event-listener-strategy = { version = "0.5" } finality-grandpa = { version = "0.16", features = ["derive-codec"] } fixed-hash = { version = "0.8", default-features = false, features = ["std"] } +foldhash = { version = "0.2", default-features = false, features = ["std"] } form_urlencoded = { version = "1" } frame-metadata-8ee676a8f9a6c413 = { package = "frame-metadata", version = "16", default-features = false, features = ["current", "std"] } frame-metadata-e761569b921b4a02 = { package = "frame-metadata", version = "23", default-features = false, features = ["current", "std"] } @@ -320,6 +324,7 @@ impl-serde = { version = "0.4" } indexmap-dff4ba8e3ae991db = { package = "indexmap", version = "1", default-features = false, features = ["serde-1", "std"] } indexmap-f595c2ba2a3f28df = { package = "indexmap", version = "2", features = ["serde"] } ipnet = { version = "2" } +itertools-582f2526e08bb6a0 = { package = "itertools", version = "0.14" } itertools-93f6ce9d446188ac = { package = "itertools", version = "0.10" } js-sys = { version = "0.3" } jsonrpsee = { version = "0.24", default-features = false, features = ["client", "macros", "server"] } @@ -354,15 +359,18 @@ parity-scale-codec = { version = "3", features = ["bytes", "derive", "full", "ma parity-wasm = { git = "https://github.com/gear-tech/parity-wasm", branch = "v0.45.0-sign-ext" } pbkdf2 = { version = "0.12", features = ["std"] } percent-encoding = { version = "2" } +petgraph = { version = "0.6" } pkcs8 = { version = "0.10", default-features = false, features = ["std"] } polkavm-common = { version = "0.9", features = ["alloc", "logging"] } portable-atomic = { version = "1", features = ["require-cas"] } +postcard = { version = "1", features = ["use-std"] } ppv-lite86 = { version = "0.2", default-features = false, features = ["simd", "std"] } predicates = { version = "3" } primitive-types-594e8ee84c453af0 = { package = "primitive-types", version = "0.13", default-features = false, features = ["scale-info", "serde", "serde_no_std"] } primitive-types-5ef9efb8ec2df382 = { package = "primitive-types", version = "0.12", default-features = false, features = ["byteorder", "rustc-hex", "scale-info", "serde", "serde_no_std"] } proc-macro2 = { version = "1", features = ["span-locations"] } prost = { version = "0.12", features = ["prost-derive"] } +pulley-interpreter = { version = "43", default-features = false, features = ["disas", "interp", "std"] } quanta = { version = "0.12" } quote = { version = "1" } rand-274715c4dabd11b0 = { package = "rand", version = "0.9" } @@ -473,20 +481,23 @@ unicode-normalization = { version = "0.1", default-features = false, features = unsigned-varint-c38e5c1d305a1b54 = { package = "unsigned-varint", version = "0.8", default-features = false, features = ["codec"] } unsigned-varint-ca01ad9e24f5d932 = { package = "unsigned-varint", version = "0.7", default-features = false, features = ["asynchronous_codec", "futures"] } url = { version = "2", features = ["serde"] } +uuid = { version = "1", features = ["v4"] } wasm-bindgen = { version = "0.2" } wasm-encoder = { version = "0.230", default-features = false, features = ["std", "wasmparser"] } wasmi-3d9dd527f574b61f = { package = "wasmi", git = "https://github.com/gear-tech/wasmi", branch = "v0.13.2-sign-ext", features = ["virtual_memory"] } wasmi-d585fab2519d2d1 = { package = "wasmi", version = "0.38", features = ["extra-checks"] } wasmi_core = { git = "https://github.com/gear-tech/wasmi", branch = "v0.13.2-sign-ext", default-features = false, features = ["virtual_memory"] } -wasmparser = { version = "0.230", default-features = false, features = ["component-model", "features", "simd", "std", "validate"] } -wasmtime = { version = "8" } -wasmtime-jit = { version = "8", default-features = false, features = ["jitdump", "vtune"] } +wasmparser-1a16dca237765f34 = { package = "wasmparser", version = "0.230", default-features = false, features = ["component-model", "features", "simd", "std", "validate"] } +wasmparser-a893a8ede649c5e9 = { package = "wasmparser", version = "0.245", default-features = false, features = ["component-model", "features", "serde", "simd", "std", "validate"] } +wasmtime = { version = "8", default-features = false, features = ["cache", "cranelift", "jitdump", "parallel-compilation", "pooling-allocator"] } +wasmtime-internal-core = { version = "43", default-features = false, features = ["anyhow", "backtrace", "serde"] } +wasmtime-jit = { version = "8", default-features = false, features = ["jitdump"] } wasmtime-jit-debug = { version = "8", default-features = false, features = ["gdb_jit_int", "perf_jitdump"] } -wasmtime-runtime = { version = "8", default-features = false, features = ["async", "pooling-allocator"] } +wasmtime-runtime = { version = "8", default-features = false, features = ["pooling-allocator"] } winnow = { version = "0.7" } zeroize = { version = "1", features = ["derive", "std"] } -[build-dependencies] +[target.'cfg(not(target_arch = "wasm32"))'.build-dependencies] aes = { version = "0.8", default-features = false, features = ["zeroize"] } ahash = { version = "0.8" } alloy = { version = "2", features = ["kzg", "node-bindings", "provider-anvil-api", "provider-ws", "rpc-types-beacon", "rpc-types-eth", "signer-mnemonic"] } @@ -506,6 +517,7 @@ alloy-sol-macro-input = { version = "1", default-features = false, features = [" alloy-sol-type-parser = { version = "1", default-features = false, features = ["serde", "std"] } alloy-sol-types = { version = "1", features = ["json"] } anyhow = { version = "1" } +arbitrary = { version = "1", default-features = false, features = ["derive"] } ark-bls12-381 = { version = "0.4", default-features = false, features = ["curve", "std"] } ark-bls12-381-ext = { version = "0.4", default-features = false, features = ["std"] } ark-ec = { version = "0.4", features = ["parallel"] } @@ -526,6 +538,7 @@ bounded-collections = { version = "0.2", default-features = false, features = [" bp-header-chain = { git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409-wasm32v1-none", default-features = false, features = ["std"] } bp-runtime = { git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409-wasm32v1-none", default-features = false, features = ["std"] } bs58 = { version = "0.5", features = ["check"] } +bumpalo = { version = "3", features = ["allocator-api2"] } byte-slice-cast = { version = "1", default-features = false, features = ["std"] } bytemuck = { version = "1", default-features = false, features = ["const_zeroed", "derive", "min_const_generics", "must_cast"] } byteorder = { version = "1" } @@ -537,6 +550,7 @@ clap_builder = { version = "4", default-features = false, features = ["color", " concurrent-queue = { version = "2" } const-hex = { version = "1", features = ["core-error", "serde"] } constant_time_eq = { version = "0.4", default-features = false, features = ["std"] } +cranelift-bitset = { version = "0.130", default-features = false, features = ["enable-serde"] } crc32fast = { version = "1" } crossbeam-channel = { version = "0.5" } crossbeam-utils = { version = "0.8" } @@ -566,6 +580,7 @@ event-listener = { version = "5" } event-listener-strategy = { version = "0.5" } finality-grandpa = { version = "0.16", features = ["derive-codec"] } fixed-hash = { version = "0.8", default-features = false, features = ["std"] } +foldhash = { version = "0.2", default-features = false, features = ["std"] } form_urlencoded = { version = "1" } frame-metadata-8ee676a8f9a6c413 = { package = "frame-metadata", version = "16", default-features = false, features = ["current", "std"] } frame-metadata-e761569b921b4a02 = { package = "frame-metadata", version = "23", default-features = false, features = ["current", "std"] } @@ -602,6 +617,7 @@ impl-serde = { version = "0.4" } indexmap-dff4ba8e3ae991db = { package = "indexmap", version = "1", default-features = false, features = ["serde-1", "std"] } indexmap-f595c2ba2a3f28df = { package = "indexmap", version = "2", features = ["serde"] } ipnet = { version = "2" } +itertools-582f2526e08bb6a0 = { package = "itertools", version = "0.14" } itertools-93f6ce9d446188ac = { package = "itertools", version = "0.10" } js-sys = { version = "0.3" } jsonrpsee = { version = "0.24", default-features = false, features = ["client", "macros", "server"] } @@ -637,15 +653,18 @@ parity-scale-codec-derive = { version = "3", default-features = false, features parity-wasm = { git = "https://github.com/gear-tech/parity-wasm", branch = "v0.45.0-sign-ext" } pbkdf2 = { version = "0.12", features = ["std"] } percent-encoding = { version = "2" } +petgraph = { version = "0.6" } pkcs8 = { version = "0.10", default-features = false, features = ["std"] } polkavm-common = { version = "0.9", features = ["alloc", "logging"] } portable-atomic = { version = "1", features = ["require-cas"] } +postcard = { version = "1", features = ["use-std"] } ppv-lite86 = { version = "0.2", default-features = false, features = ["simd", "std"] } predicates = { version = "3" } primitive-types-594e8ee84c453af0 = { package = "primitive-types", version = "0.13", default-features = false, features = ["scale-info", "serde", "serde_no_std"] } primitive-types-5ef9efb8ec2df382 = { package = "primitive-types", version = "0.12", default-features = false, features = ["byteorder", "rustc-hex", "scale-info", "serde", "serde_no_std"] } proc-macro2 = { version = "1", features = ["span-locations"] } prost = { version = "0.12", features = ["prost-derive"] } +pulley-interpreter = { version = "43", default-features = false, features = ["disas", "interp", "std"] } quanta = { version = "0.12" } quote = { version = "1" } rand-274715c4dabd11b0 = { package = "rand", version = "0.9" } @@ -760,16 +779,19 @@ unicode-normalization = { version = "0.1", default-features = false, features = unsigned-varint-c38e5c1d305a1b54 = { package = "unsigned-varint", version = "0.8", default-features = false, features = ["codec"] } unsigned-varint-ca01ad9e24f5d932 = { package = "unsigned-varint", version = "0.7", default-features = false, features = ["asynchronous_codec", "futures"] } url = { version = "2", features = ["serde"] } +uuid = { version = "1", features = ["v4"] } wasm-bindgen = { version = "0.2" } wasm-encoder = { version = "0.230", default-features = false, features = ["std", "wasmparser"] } wasmi-3d9dd527f574b61f = { package = "wasmi", git = "https://github.com/gear-tech/wasmi", branch = "v0.13.2-sign-ext", features = ["virtual_memory"] } wasmi-d585fab2519d2d1 = { package = "wasmi", version = "0.38", features = ["extra-checks"] } wasmi_core = { git = "https://github.com/gear-tech/wasmi", branch = "v0.13.2-sign-ext", default-features = false, features = ["virtual_memory"] } -wasmparser = { version = "0.230", default-features = false, features = ["component-model", "features", "simd", "std", "validate"] } -wasmtime = { version = "8" } -wasmtime-jit = { version = "8", default-features = false, features = ["jitdump", "vtune"] } +wasmparser-1a16dca237765f34 = { package = "wasmparser", version = "0.230", default-features = false, features = ["component-model", "features", "simd", "std", "validate"] } +wasmparser-a893a8ede649c5e9 = { package = "wasmparser", version = "0.245", default-features = false, features = ["component-model", "features", "serde", "simd", "std", "validate"] } +wasmtime = { version = "8", default-features = false, features = ["cache", "cranelift", "jitdump", "parallel-compilation", "pooling-allocator"] } +wasmtime-internal-core = { version = "43", default-features = false, features = ["anyhow", "backtrace", "serde"] } +wasmtime-jit = { version = "8", default-features = false, features = ["jitdump"] } wasmtime-jit-debug = { version = "8", default-features = false, features = ["gdb_jit_int", "perf_jitdump"] } -wasmtime-runtime = { version = "8", default-features = false, features = ["async", "pooling-allocator"] } +wasmtime-runtime = { version = "8", default-features = false, features = ["pooling-allocator"] } winnow = { version = "0.7" } zeroize = { version = "1", features = ["derive", "std"] } @@ -779,8 +801,9 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["aws-lc-rs", "http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } +linux-raw-sys = { version = "0.11", default-features = false, features = ["auxvec", "elf", "errno", "general", "ioctl", "no_std", "prctl"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } mio = { version = "1", features = ["net", "os-ext"] } nix = { version = "0.26" } @@ -789,7 +812,7 @@ once_cell = { version = "1", default-features = false, features = ["critical-sec openssl = { version = "0.10", features = ["vendored"] } openssl-sys = { version = "0.9", default-features = false, features = ["vendored"] } rustix-4e55305914c60c55 = { package = "rustix", version = "0.36", features = ["mm", "param", "process", "time", "use-libc"] } -rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios"] } +rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "mm", "param", "process", "termios", "thread", "time"] } rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs", "aws_lc_rs", "logging", "ring", "std", "tls12"] } rustls-webpki = { version = "0.103", features = ["aws-lc-rs", "ring"] } sha-1 = { version = "0.10", features = ["asm"] } @@ -803,8 +826,9 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["aws-lc-rs", "http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } +linux-raw-sys = { version = "0.11", default-features = false, features = ["auxvec", "elf", "errno", "general", "ioctl", "no_std", "prctl"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } mio = { version = "1", features = ["net", "os-ext"] } nix = { version = "0.26" } @@ -814,7 +838,7 @@ openssl = { version = "0.10", features = ["vendored"] } openssl-sys = { version = "0.9", default-features = false, features = ["vendored"] } prettyplease = { version = "0.2", default-features = false, features = ["verbatim"] } rustix-4e55305914c60c55 = { package = "rustix", version = "0.36", features = ["mm", "param", "process", "time", "use-libc"] } -rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios"] } +rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "mm", "param", "process", "termios", "thread", "time"] } rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs", "aws_lc_rs", "logging", "ring", "std", "tls12"] } rustls-webpki = { version = "0.103", features = ["aws-lc-rs", "ring"] } sha-1 = { version = "0.10", features = ["asm"] } @@ -828,8 +852,9 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["aws-lc-rs", "http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } +linux-raw-sys = { version = "0.11", default-features = false, features = ["auxvec", "elf", "errno", "general", "ioctl", "no_std", "prctl"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } mio = { version = "1", features = ["net", "os-ext"] } nix = { version = "0.26" } @@ -838,7 +863,7 @@ once_cell = { version = "1", default-features = false, features = ["critical-sec openssl = { version = "0.10", features = ["vendored"] } openssl-sys = { version = "0.9", default-features = false, features = ["vendored"] } rustix-4e55305914c60c55 = { package = "rustix", version = "0.36", features = ["mm", "param", "process", "time", "use-libc"] } -rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios"] } +rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "mm", "param", "process", "termios", "thread", "time"] } rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs", "aws_lc_rs", "logging", "ring", "std", "tls12"] } rustls-webpki = { version = "0.103", features = ["aws-lc-rs", "ring"] } sha-1 = { version = "0.10", features = ["asm"] } @@ -851,8 +876,9 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["aws-lc-rs", "http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } +linux-raw-sys = { version = "0.11", default-features = false, features = ["auxvec", "elf", "errno", "general", "ioctl", "no_std", "prctl"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } mio = { version = "1", features = ["net", "os-ext"] } nix = { version = "0.26" } @@ -862,7 +888,7 @@ openssl = { version = "0.10", features = ["vendored"] } openssl-sys = { version = "0.9", default-features = false, features = ["vendored"] } prettyplease = { version = "0.2", default-features = false, features = ["verbatim"] } rustix-4e55305914c60c55 = { package = "rustix", version = "0.36", features = ["mm", "param", "process", "time", "use-libc"] } -rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios"] } +rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "mm", "param", "process", "termios", "thread", "time"] } rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs", "aws_lc_rs", "logging", "ring", "std", "tls12"] } rustls-webpki = { version = "0.103", features = ["aws-lc-rs", "ring"] } sha-1 = { version = "0.10", features = ["asm"] } @@ -875,14 +901,14 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["aws-lc-rs", "http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } nom = { version = "7" } once_cell = { version = "1", default-features = false, features = ["critical-section"] } openssl-sys = { version = "0.9", default-features = false, features = ["vendored"] } rustix-4e55305914c60c55 = { package = "rustix", version = "0.36", features = ["mm", "param", "process", "use-libc"] } -rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios"] } +rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "mm", "param", "process", "termios", "thread"] } rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs", "aws_lc_rs", "logging", "ring", "std", "tls12"] } rustls-webpki = { version = "0.103", features = ["aws-lc-rs", "ring"] } security-framework = { version = "3", features = ["OSX_10_14"] } @@ -897,7 +923,7 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["aws-lc-rs", "http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } nom = { version = "7" } @@ -905,7 +931,7 @@ once_cell = { version = "1", default-features = false, features = ["critical-sec openssl-sys = { version = "0.9", default-features = false, features = ["vendored"] } prettyplease = { version = "0.2", default-features = false, features = ["verbatim"] } rustix-4e55305914c60c55 = { package = "rustix", version = "0.36", features = ["mm", "param", "process", "use-libc"] } -rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "termios"] } +rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", features = ["fs", "mm", "param", "process", "termios", "thread"] } rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs", "aws_lc_rs", "logging", "ring", "std", "tls12"] } rustls-webpki = { version = "0.103", features = ["aws-lc-rs", "ring"] } security-framework = { version = "3", features = ["OSX_10_14"] }