diff --git a/Cargo.lock b/Cargo.lock index 0d6c10c3a8..782f43c47e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -207,6 +207,28 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-lc-rs" +version = "1.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e84ce723ab67259cfeb9877c6a639ee9eb7a27b28123abd71db7f0d5d0cc9d86" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a442ece363113bd4bd4c8b18977a7798dd4d3c3383f34fb61936960e8f4ad8" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "backtrace" version = "0.3.76" @@ -500,9 +522,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cexpr" version = "0.6.0" @@ -561,9 +591,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ "iana-time-zone", "js-sys", @@ -694,6 +724,16 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "common-path" version = "1.0.0" @@ -771,6 +811,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1144,6 +1194,12 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dynasm" version = "4.0.2" @@ -1483,12 +1539,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - [[package]] name = "fiat-crypto" version = "0.2.9" @@ -1553,21 +1603,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -1688,6 +1723,12 @@ dependencies = [ "multiversx-sc-meta-lib", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures" version = "0.3.31" @@ -2272,23 +2313,6 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", ] [[package]] @@ -2588,11 +2612,43 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -3389,23 +3445,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nft-minter" version = "0.0.0" @@ -3562,49 +3601,11 @@ dependencies = [ "num-traits", ] -[[package]] -name = "openssl" -version = "0.10.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - [[package]] name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.111" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] +checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" [[package]] name = "order-book-factory" @@ -3848,12 +3849,6 @@ dependencies = [ "spki", ] -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - [[package]] name = "plotters" version = "0.3.7" @@ -4123,6 +4118,7 @@ version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.3.4", "lru-slab", @@ -4374,9 +4370,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.28" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62" dependencies = [ "base64", "bytes", @@ -4390,23 +4386,20 @@ dependencies = [ "http-body-util", "hyper", "hyper-rustls", - "hyper-tls", "hyper-util", "js-sys", "log", "mime", - "native-tls", "percent-encoding", "pin-project-lite", "quinn", "rustls", "rustls-pki-types", + "rustls-platform-verifier", "serde", "serde_json", - "serde_urlencoded", "sync_wrapper", "tokio", - "tokio-native-tls", "tokio-rustls", "tower", "tower-http", @@ -4415,7 +4408,6 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", ] [[package]] @@ -4540,9 +4532,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" @@ -4584,14 +4576,26 @@ version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ + "aws-lc-rs", "once_cell", - "ring", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.13.2" @@ -4602,12 +4606,40 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -4730,12 +4762,12 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.1" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ "bitflags 2.10.0", - "core-foundation", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -5164,7 +5196,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.10.0", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -5206,19 +5238,6 @@ version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" -[[package]] -name = "tempfile" -version = "3.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" -dependencies = [ - "fastrand", - "getrandom 0.3.4", - "once_cell", - "rustix", - "windows-sys 0.61.2", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -5366,16 +5385,6 @@ dependencies = [ "syn 2.0.114", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.26.4" @@ -5736,12 +5745,6 @@ dependencies = [ "vault", ] -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "vec-repeat" version = "0.0.0" @@ -5801,9 +5804,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", @@ -5814,11 +5817,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ "cfg-if", + "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -5827,9 +5831,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5837,9 +5841,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ "bumpalo", "proc-macro2", @@ -5850,9 +5854,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] @@ -6086,9 +6090,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -6105,10 +6109,10 @@ dependencies = [ ] [[package]] -name = "webpki-roots" +name = "webpki-root-certs" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" +checksum = "36a29fc0408b113f68cf32637857ab740edfafdf460c326cd2afaa2d84cc05dc" dependencies = [ "rustls-pki-types", ] @@ -6192,6 +6196,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -6228,6 +6241,21 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -6261,6 +6289,12 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -6273,6 +6307,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -6285,6 +6325,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -6309,6 +6355,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -6321,6 +6373,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -6333,6 +6391,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -6345,6 +6409,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" diff --git a/chain/vm/src/host/context/managed_type_container/handle_map.rs b/chain/vm/src/host/context/managed_type_container/handle_map.rs index 4473e9104b..f121389696 100644 --- a/chain/vm/src/host/context/managed_type_container/handle_map.rs +++ b/chain/vm/src/host/context/managed_type_container/handle_map.rs @@ -47,4 +47,8 @@ impl HandleMap { pub fn insert(&mut self, handle: RawHandle, value: V) { let _ = self.map.insert(handle, value); } + + pub fn remove_handle(&mut self, handle: RawHandle) { + let _ = self.map.remove(&handle); + } } diff --git a/chain/vm/src/host/context/managed_type_container/tx_big_float.rs b/chain/vm/src/host/context/managed_type_container/tx_big_float.rs index 3da9b0333b..002a5635b9 100644 --- a/chain/vm/src/host/context/managed_type_container/tx_big_float.rs +++ b/chain/vm/src/host/context/managed_type_container/tx_big_float.rs @@ -10,4 +10,8 @@ impl ManagedTypeContainer { pub fn bf_overwrite(&mut self, handle: RawHandle, value: f64) { self.big_float_map.insert(handle, value); } + + pub fn bf_remove(&mut self, handle: RawHandle) { + self.big_float_map.remove_handle(handle); + } } diff --git a/chain/vm/src/host/context/managed_type_container/tx_big_int.rs b/chain/vm/src/host/context/managed_type_container/tx_big_int.rs index 08acedd9bd..cc61b5cc60 100644 --- a/chain/vm/src/host/context/managed_type_container/tx_big_int.rs +++ b/chain/vm/src/host/context/managed_type_container/tx_big_int.rs @@ -11,6 +11,10 @@ impl ManagedTypeContainer { self.big_int_map.insert_new_handle_raw(value) } + pub fn bi_remove(&mut self, handle: RawHandle) { + self.big_int_map.remove_handle(handle); + } + pub fn bi_overwrite(&mut self, destination: RawHandle, value: num_bigint::BigInt) { self.big_int_map.insert(destination, value); } diff --git a/chain/vm/src/host/context/managed_type_container/tx_managed_buffer.rs b/chain/vm/src/host/context/managed_type_container/tx_managed_buffer.rs index 5f8aeccf4d..0fff43c1c4 100644 --- a/chain/vm/src/host/context/managed_type_container/tx_managed_buffer.rs +++ b/chain/vm/src/host/context/managed_type_container/tx_managed_buffer.rs @@ -183,6 +183,10 @@ impl ManagedTypeContainer { num_bytes_copied } + + pub fn mb_remove(&mut self, handle: RawHandle) { + self.managed_buffer_map.remove_handle(handle); + } } pub fn handle_to_be_bytes(handle: RawHandle) -> [u8; 4] { diff --git a/chain/vm/src/host/context/managed_type_container/tx_managed_map.rs b/chain/vm/src/host/context/managed_type_container/tx_managed_map.rs index 37891b2296..2a2efff96f 100644 --- a/chain/vm/src/host/context/managed_type_container/tx_managed_map.rs +++ b/chain/vm/src/host/context/managed_type_container/tx_managed_map.rs @@ -31,4 +31,8 @@ impl ManagedTypeContainer { let mmap = self.managed_map_map.get_mut(map_handle); mmap.remove(key).unwrap_or_default() } + + pub fn mm_remove(&mut self, handle: RawHandle) { + self.managed_map_map.remove_handle(handle); + } } diff --git a/chain/vm/src/host/context/tx_context_ref.rs b/chain/vm/src/host/context/tx_context_ref.rs index c58b3b307c..05f1a69cf2 100644 --- a/chain/vm/src/host/context/tx_context_ref.rs +++ b/chain/vm/src/host/context/tx_context_ref.rs @@ -1,4 +1,7 @@ -use std::{ops::Deref, sync::Arc}; +use std::{ + ops::Deref, + sync::{Arc, Weak}, +}; use crate::host::context::{TxContext, TxResult}; @@ -62,7 +65,30 @@ impl TxContextRef { Arc::ptr_eq(&this.0, &other.0) } + /// Returns a raw pointer to the underlying `TxContext`. + /// + /// This is useful for pointer comparisons, particularly when comparing + /// with weak references to determine if they point to the same context. + pub fn as_ptr(&self) -> *const TxContext { + Arc::as_ptr(&self.0) + } + pub fn into_ref(self) -> Arc { self.0 } + + /// Creates a new [`Weak`] pointer to the [`TxContext`]. + /// + /// This is the preferred way to obtain a non‑owning reference to the underlying + /// `TxContext` when you need to store a handle that should not keep the transaction + /// alive on its own. In particular, this method underpins the weak‑pointer pattern + /// used by [`DebugHandle`], which holds a `Weak` so that debug tooling + /// can observe a transaction while it exists, without extending its lifetime. + /// + /// Callers that use the returned [`Weak`] must call [`Weak::upgrade`] before + /// accessing the `TxContext` and be prepared to handle the case where upgrading + /// fails because the transaction context has already been dropped. + pub fn downgrade(&self) -> Weak { + Arc::downgrade(&self.0) + } } diff --git a/chain/vm/src/host/vm_hooks/vh_dispatcher.rs b/chain/vm/src/host/vm_hooks/vh_dispatcher.rs index dd54f42e36..64f027c426 100644 --- a/chain/vm/src/host/vm_hooks/vh_dispatcher.rs +++ b/chain/vm/src/host/vm_hooks/vh_dispatcher.rs @@ -10,7 +10,7 @@ pub(super) const RESULT_ERROR: i32 = 1; /// Dispatches messages coming via VMHooks to the underlying implementation (the VMHooksHandler). #[derive(Debug)] pub struct VMHooksDispatcher { - pub(crate) handler: VMHooksHandler, + pub handler: VMHooksHandler, } impl VMHooksDispatcher { diff --git a/chain/vm/src/host/vm_hooks/vh_handler/vh_error.rs b/chain/vm/src/host/vm_hooks/vh_handler/vh_error.rs index 64c6b0c087..49142f5a8d 100644 --- a/chain/vm/src/host/vm_hooks/vh_handler/vh_error.rs +++ b/chain/vm/src/host/vm_hooks/vh_handler/vh_error.rs @@ -1,23 +1,16 @@ use multiversx_chain_core::types::ReturnCode; use multiversx_chain_vm_executor::VMHooksEarlyExit; -use crate::{ - host::vm_hooks::{VMHooksContext, vh_early_exit::early_exit_vm_error}, - types::RawHandle, -}; +use crate::{host::vm_hooks::VMHooksContext, types::RawHandle}; use super::VMHooksHandler; impl VMHooksHandler { pub fn signal_error(&mut self, message: &[u8]) -> Result<(), VMHooksEarlyExit> { - match String::from_utf8(message.to_owned()) { - Ok(message_string) => { - self.context.log_error_trace(&message_string); - Err(VMHooksEarlyExit::new(ReturnCode::UserError.as_u64()) - .with_message(message_string)) - } - Err(_) => Err(early_exit_vm_error("error message utf-8 error")), - } + let message_string = String::from_utf8_lossy(message); + self.context.log_error_trace(&message_string); + Err(VMHooksEarlyExit::new(ReturnCode::UserError.as_u64()) + .with_message(message_string.to_string())) } pub fn signal_error_from_buffer( diff --git a/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs b/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs index 31e2efa1d1..366177f92b 100644 --- a/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs +++ b/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs @@ -285,4 +285,8 @@ impl VMHooksHandler { Ok(()) } + + pub fn bf_drop(&self, map_handle: RawHandle) { + self.context.m_types_lock().bf_remove(map_handle); + } } diff --git a/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs b/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs index d9cd09866e..d93871870a 100644 --- a/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs +++ b/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs @@ -360,4 +360,8 @@ impl VMHooksHandler { Ok(()) } + + pub fn bi_drop(&self, map_handle: RawHandle) { + self.context.m_types_lock().bi_remove(map_handle); + } } diff --git a/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_managed_buffer.rs b/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_managed_buffer.rs index 4797df14a3..baa2439b8f 100644 --- a/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_managed_buffer.rs +++ b/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_managed_buffer.rs @@ -210,4 +210,8 @@ impl VMHooksHandler { .mb_set(dest_handle, encoded.into_bytes()); Ok(()) } + + pub fn mb_drop(&self, handle: RawHandle) { + self.context.m_types_lock().mb_remove(handle); + } } diff --git a/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_managed_map.rs b/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_managed_map.rs index 25280af635..1584a6063d 100644 --- a/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_managed_map.rs +++ b/chain/vm/src/host/vm_hooks/vh_handler/vh_managed_types/vh_managed_map.rs @@ -50,4 +50,8 @@ impl VMHooksHandler { .m_types_lock() .mm_contains(map_handle, key.as_slice()) } + + pub fn mm_drop(&self, map_handle: RawHandle) { + self.context.m_types_lock().mm_remove(map_handle); + } } diff --git a/contracts/feature-tests/basic-features/tests/basic_features_managed_buffer_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_managed_buffer_test.rs index 88320b17f6..e775c5e167 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_managed_buffer_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_managed_buffer_test.rs @@ -15,3 +15,10 @@ fn test_managed_address_zero() { let result = bf.managed_address_zero(); assert_eq!(ManagedAddress::zero(), result); } + +#[test] +fn test_managed_buffer_destructor() { + let my_buffer = ManagedBuffer::::from(b"my buffer"); + assert_eq!(my_buffer, managed_buffer!(b"my buffer")); + drop(my_buffer); +} diff --git a/framework/base/src/api/managed_types/managed_type_api_impl.rs b/framework/base/src/api/managed_types/managed_type_api_impl.rs index 024ed79537..64fc31d81e 100644 --- a/framework/base/src/api/managed_types/managed_type_api_impl.rs +++ b/framework/base/src/api/managed_types/managed_type_api_impl.rs @@ -59,4 +59,10 @@ pub trait ManagedTypeApiImpl: fn get_token_ticker_len(&self, token_id_len: usize) -> usize { token_identifier_util::get_token_ticker_len(token_id_len) } + + fn drop_managed_buffer(&self, _handle: Self::ManagedBufferHandle) {} + fn drop_big_float(&self, _handle: Self::BigFloatHandle) {} + fn drop_big_int(&self, _handle: Self::BigIntHandle) {} + fn drop_elliptic_curve(&self, _handle: Self::EllipticCurveHandle) {} + fn drop_managed_map(&self, _handle: Self::ManagedMapHandle) {} } diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index 55caf8a42a..bfa0b30a83 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -418,6 +418,13 @@ impl Clone for ManagedBuffer { } } +impl Drop for ManagedBuffer { + fn drop(&mut self) { + // TODO: enable, after fixing all ownership issues + // M::managed_type_impl().drop_managed_buffer(self.handle.clone()); + } +} + impl PartialEq for ManagedBuffer { #[inline] fn eq(&self, other: &Self) -> bool { @@ -583,11 +590,8 @@ impl core::fmt::Debug for ManagedBuffer { impl core::fmt::Display for ManagedBuffer { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - use crate::contract_base::ErrorHelper; - - let s = alloc::string::String::from_utf8(self.to_boxed_bytes().into_vec()) - .unwrap_or_else(|err| ErrorHelper::::signal_error_with_message(err.as_bytes())); - + let bytes = self.to_boxed_bytes(); + let s = alloc::string::String::from_utf8_lossy(bytes.as_slice()); s.fmt(f) } } diff --git a/framework/meta/Cargo.toml b/framework/meta/Cargo.toml index 7f5905c5ff..26cd53cdbc 100644 --- a/framework/meta/Cargo.toml +++ b/framework/meta/Cargo.toml @@ -35,7 +35,7 @@ convert_case = "0.10" semver = "1.0.20" ruplacer = { version = "0.10", default-features = false } regex = "1.11" -reqwest = { version = "0.12", features = ["blocking", "json"] } +reqwest = { version = "0.13", features = ["rustls", "blocking", "json"] } zip = { version = "6.0", features = ["deflate"], default-features = false } copy_dir = "0.1.2" pathdiff = "0.2.1" diff --git a/framework/scenario/src/api/impl_vh/debug_api.rs b/framework/scenario/src/api/impl_vh/debug_api.rs index 3076d6a24a..531a54f5a2 100644 --- a/framework/scenario/src/api/impl_vh/debug_api.rs +++ b/framework/scenario/src/api/impl_vh/debug_api.rs @@ -1,12 +1,12 @@ use multiversx_chain_vm::{ - executor::{VMHooks, VMHooksEarlyExit}, - host::context::TxContextRef, + executor::VMHooksEarlyExit, host::vm_hooks::{TxVMHooksContext, VMHooksDispatcher}, }; use multiversx_sc::{chain_core::types::ReturnCode, err_msg}; use crate::executor::debug::{ ContractDebugInstance, ContractDebugInstanceState, ContractDebugStack, StaticVarData, + VMHooksDebugger, }; use super::{DebugHandle, VMHooksApi, VMHooksApiBackend}; @@ -19,7 +19,7 @@ impl VMHooksApiBackend for DebugApiBackend { fn with_vm_hooks(f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { let instance = ContractDebugStack::static_peek(); let tx_context_ref = instance.tx_context_ref.clone(); @@ -30,9 +30,9 @@ impl VMHooksApiBackend for DebugApiBackend { fn with_vm_hooks_ctx_1(handle: Self::HandleType, f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { - let tx_context_ref = TxContextRef(handle.context.clone()); + let tx_context_ref = handle.to_tx_context_ref(); let vh_context = TxVMHooksContext::new(tx_context_ref, ContractDebugInstanceState); let mut dispatcher = VMHooksDispatcher::new(vh_context); f(&mut dispatcher).unwrap_or_else(|err| ContractDebugInstanceState::early_exit_panic(err)) @@ -40,7 +40,7 @@ impl VMHooksApiBackend for DebugApiBackend { fn with_vm_hooks_ctx_2(handle1: Self::HandleType, handle2: Self::HandleType, f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { assert_handles_on_same_context(&handle1, &handle2); Self::with_vm_hooks_ctx_1(handle1, f) @@ -53,7 +53,7 @@ impl VMHooksApiBackend for DebugApiBackend { f: F, ) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { assert_handles_on_same_context(&handle1, &handle2); assert_handles_on_same_context(&handle1, &handle3); diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 7f3da0d20f..086d166d17 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -1,6 +1,6 @@ -use std::sync::Arc; +use std::sync::Weak; -use multiversx_chain_vm::host::context::TxContext; +use multiversx_chain_vm::host::context::{TxContext, TxContextRef}; use multiversx_sc::{ api::{HandleConstraints, RawHandle}, codec::TryStaticCast, @@ -10,22 +10,30 @@ use crate::executor::debug::ContractDebugStack; #[derive(Clone)] pub struct DebugHandle { - /// TODO: would be nice to be an actual TxContextRef, - /// but that requires changing the debugger scripts - pub(crate) context: Arc, + /// Only keep a weak reference to the context, to avoid stray handles keeping the context from being released. + /// Using the pointer after the context is released will panic. + pub(crate) context: Weak, raw_handle: RawHandle, } impl DebugHandle { + /// Should almost never call directly, only used directly in a test. + pub fn new_with_explicit_context_ref(context: Weak, raw_handle: RawHandle) -> Self { + Self { + context, + raw_handle, + } + } + pub fn is_on_current_context(&self) -> bool { - Arc::ptr_eq( - &self.context, - &ContractDebugStack::static_peek().tx_context_ref.into_ref(), + std::ptr::eq( + self.context.as_ptr(), + ContractDebugStack::static_peek().tx_context_ref.as_ptr(), ) } pub fn is_on_same_context(&self, other: &DebugHandle) -> bool { - Arc::ptr_eq(&self.context, &other.context) + Weak::ptr_eq(&self.context, &other.context) } pub fn assert_current_context(&self) { @@ -34,6 +42,30 @@ impl DebugHandle { "Managed value not used in original context" ); } + + /// Upgrades the weak reference to a strong `TxContextRef`. + /// + /// This method attempts to upgrade the weak reference stored in this handle + /// to a strong reference. This is necessary when you need to access the + /// underlying `TxContext` for operations. + /// + /// # Panics + /// + /// Panics if the `TxContext` is no longer valid (has been dropped). This can + /// happen if the object was created on a VM execution stack frame that has + /// already been popped, or if objects are mixed between different execution + /// contexts during whitebox testing. + pub fn to_tx_context_ref(&self) -> TxContextRef { + let tx_context_arc = self.context.upgrade().unwrap_or_else(|| { + panic!( + "TxContext is no longer valid for handle {}. +The object was created on a VM execution stack frame that has already been popped. +This can sometimes happen during whitebox testing if the objects are mixed between execution contexts.", + self.raw_handle + ) + }); + TxContextRef::new(tx_context_arc) + } } impl core::fmt::Debug for DebugHandle { @@ -44,10 +76,8 @@ impl core::fmt::Debug for DebugHandle { impl HandleConstraints for DebugHandle { fn new(handle: multiversx_sc::api::RawHandle) -> Self { - Self { - context: ContractDebugStack::static_peek().tx_context_ref.into_ref(), - raw_handle: handle, - } + let context = ContractDebugStack::static_peek().tx_context_ref.downgrade(); + DebugHandle::new_with_explicit_context_ref(context, handle) } fn to_be_bytes(&self) -> [u8; 4] { @@ -73,7 +103,7 @@ impl PartialEq for DebugHandle { impl PartialEq for DebugHandle { fn eq(&self, other: &DebugHandle) -> bool { - Arc::ptr_eq(&self.context, &other.context) && self.raw_handle == other.raw_handle + Weak::ptr_eq(&self.context, &other.context) && self.raw_handle == other.raw_handle } } diff --git a/framework/scenario/src/api/impl_vh/single_tx_api.rs b/framework/scenario/src/api/impl_vh/single_tx_api.rs index 00b0299143..9357f5b094 100644 --- a/framework/scenario/src/api/impl_vh/single_tx_api.rs +++ b/framework/scenario/src/api/impl_vh/single_tx_api.rs @@ -1,13 +1,12 @@ use std::sync::Mutex; use multiversx_chain_vm::{ - blockchain::state::AccountData, executor::VMHooks, host::vm_hooks::VMHooksDispatcher, - types::VMAddress, + blockchain::state::AccountData, host::vm_hooks::VMHooksDispatcher, types::VMAddress, }; use multiversx_chain_vm_executor::VMHooksEarlyExit; use multiversx_sc::api::RawHandle; -use crate::executor::debug::{ContractDebugInstanceState, StaticVarData}; +use crate::executor::debug::{ContractDebugInstanceState, StaticVarData, VMHooksDebugger}; use super::{SingleTxApiData, SingleTxApiVMHooksContext, VMHooksApi, VMHooksApiBackend}; @@ -25,7 +24,7 @@ impl VMHooksApiBackend for SingleTxApiBackend { fn with_vm_hooks(f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { SINGLE_TX_API_VH_CELL.with(|cell| { let vh_context = cell.lock().unwrap().clone(); diff --git a/framework/scenario/src/api/impl_vh/static_api.rs b/framework/scenario/src/api/impl_vh/static_api.rs index 233087b3d4..9f335982f9 100644 --- a/framework/scenario/src/api/impl_vh/static_api.rs +++ b/framework/scenario/src/api/impl_vh/static_api.rs @@ -1,9 +1,9 @@ -use multiversx_chain_vm::{executor::VMHooks, host::vm_hooks::VMHooksDispatcher}; +use multiversx_chain_vm::host::vm_hooks::VMHooksDispatcher; use multiversx_chain_vm_executor::VMHooksEarlyExit; use multiversx_sc::{api::RawHandle, types::Address}; use std::sync::Mutex; -use crate::executor::debug::StaticVarData; +use crate::executor::debug::{StaticVarData, VMHooksDebugger}; use super::{StaticApiVMHooksContext, VMHooksApi, VMHooksApiBackend}; @@ -25,7 +25,7 @@ impl VMHooksApiBackend for StaticApiBackend { fn with_vm_hooks(f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { let result = STATIC_API_VH_CELL.with(|vh_mutex| { let mut vh = vh_mutex.lock().unwrap(); diff --git a/framework/scenario/src/api/impl_vh/vm_hooks_api.rs b/framework/scenario/src/api/impl_vh/vm_hooks_api.rs index 0384b5f8e1..a22fec08c5 100644 --- a/framework/scenario/src/api/impl_vh/vm_hooks_api.rs +++ b/framework/scenario/src/api/impl_vh/vm_hooks_api.rs @@ -1,10 +1,10 @@ -use crate::executor::debug::StaticVarData; +use crate::executor::debug::{StaticVarData, VMHooksDebugger}; use super::VMHooksApiBackend; use std::marker::PhantomData; -use multiversx_chain_vm::executor::{MemPtr, VMHooks}; +use multiversx_chain_vm::executor::MemPtr; use multiversx_chain_vm_executor::VMHooksEarlyExit; use multiversx_sc::api::{HandleTypeInfo, ManagedBufferApiImpl}; @@ -23,7 +23,7 @@ impl VMHooksApi { /// All communication with the VM happens via this method. pub fn with_vm_hooks(&self, f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { VHB::with_vm_hooks(f) } @@ -31,7 +31,7 @@ impl VMHooksApi { /// Works with the VM hooks given by the context of 1 handle. pub fn with_vm_hooks_ctx_1(&self, handle: &VHB::HandleType, f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { VHB::with_vm_hooks_ctx_1(handle.clone(), f) } @@ -44,7 +44,7 @@ impl VMHooksApi { f: F, ) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { VHB::with_vm_hooks_ctx_2(handle1.clone(), handle2.clone(), f) } @@ -58,7 +58,7 @@ impl VMHooksApi { f: F, ) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { VHB::with_vm_hooks_ctx_3(handle1.clone(), handle2.clone(), handle3.clone(), f) } diff --git a/framework/scenario/src/api/impl_vh/vm_hooks_backend.rs b/framework/scenario/src/api/impl_vh/vm_hooks_backend.rs index a54d5d0ae3..80b2c8f960 100644 --- a/framework/scenario/src/api/impl_vh/vm_hooks_backend.rs +++ b/framework/scenario/src/api/impl_vh/vm_hooks_backend.rs @@ -1,8 +1,7 @@ -use multiversx_chain_vm::executor::VMHooks; use multiversx_chain_vm_executor::VMHooksEarlyExit; use multiversx_sc::api::HandleConstraints; -use crate::executor::debug::StaticVarData; +use crate::executor::debug::{StaticVarData, VMHooksDebugger}; pub trait VMHooksApiBackend: Clone + Send + Sync + 'static { /// We use a single handle type for all handles. @@ -11,18 +10,18 @@ pub trait VMHooksApiBackend: Clone + Send + Sync + 'static { /// All communication with the VM happens via this method. fn with_vm_hooks(f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result; + F: FnOnce(&mut dyn VMHooksDebugger) -> Result; fn with_vm_hooks_ctx_1(_handle: Self::HandleType, f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { Self::with_vm_hooks(f) } fn with_vm_hooks_ctx_2(_handle1: Self::HandleType, _handle2: Self::HandleType, f: F) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { Self::with_vm_hooks(f) } @@ -34,7 +33,7 @@ pub trait VMHooksApiBackend: Clone + Send + Sync + 'static { f: F, ) -> R where - F: FnOnce(&mut dyn VMHooks) -> Result, + F: FnOnce(&mut dyn VMHooksDebugger) -> Result, { Self::with_vm_hooks(f) } diff --git a/framework/scenario/src/api/managed_type_api_vh.rs b/framework/scenario/src/api/managed_type_api_vh.rs index 62c9f4e4f6..e3a547ba6b 100644 --- a/framework/scenario/src/api/managed_type_api_vh.rs +++ b/framework/scenario/src/api/managed_type_api_vh.rs @@ -127,4 +127,28 @@ impl ManagedTypeApiImpl for VMHooksApi { }); i32_to_bool(result) } + + fn drop_managed_buffer(&self, handle: Self::ManagedBufferHandle) { + self.with_vm_hooks_ctx_1(&handle, |vh| { + vh.drop_managed_buffer(handle.get_raw_handle_unchecked()) + }); + } + fn drop_big_float(&self, handle: Self::BigFloatHandle) { + self.with_vm_hooks_ctx_1(&handle, |vh| { + vh.drop_big_float(handle.get_raw_handle_unchecked()) + }); + } + fn drop_big_int(&self, handle: Self::BigIntHandle) { + self.with_vm_hooks_ctx_1(&handle, |vh| { + vh.drop_big_int(handle.get_raw_handle_unchecked()) + }); + } + fn drop_elliptic_curve(&self, _handle: Self::EllipticCurveHandle) { + // TODO + } + fn drop_managed_map(&self, handle: Self::ManagedMapHandle) { + self.with_vm_hooks_ctx_1(&handle, |vh| { + vh.drop_managed_map(handle.get_raw_handle_unchecked()) + }); + } } diff --git a/framework/scenario/src/executor/debug.rs b/framework/scenario/src/executor/debug.rs index 1d8f31a04b..a2890d240e 100644 --- a/framework/scenario/src/executor/debug.rs +++ b/framework/scenario/src/executor/debug.rs @@ -9,6 +9,7 @@ mod contract_debug_whitebox_lambda; mod contract_map; mod static_var_data; mod tx_static_vars; +mod vm_hooks_debugger; pub use catch_tx_panic::catch_tx_panic; pub use contract_container::{ContractContainer, ContractContainerRef}; @@ -21,3 +22,4 @@ pub use contract_debug_whitebox_lambda::ContractDebugWhiteboxLambda; pub use contract_map::{ContractMap, ContractMapRef}; pub use static_var_data::StaticVarData; pub use tx_static_vars::TxStaticVars; +pub use vm_hooks_debugger::VMHooksDebugger; diff --git a/framework/scenario/src/executor/debug/vm_hooks_debugger.rs b/framework/scenario/src/executor/debug/vm_hooks_debugger.rs new file mode 100644 index 0000000000..86194eae43 --- /dev/null +++ b/framework/scenario/src/executor/debug/vm_hooks_debugger.rs @@ -0,0 +1,37 @@ +use multiversx_chain_vm::host::vm_hooks::{VMHooksContext, VMHooksDispatcher}; +use multiversx_chain_vm_executor::{VMHooks, VMHooksEarlyExit}; + +pub trait VMHooksDebugger: VMHooks { + fn drop_managed_buffer(&self, handle: i32) -> Result<(), VMHooksEarlyExit>; + fn drop_big_float(&self, handle: i32) -> Result<(), VMHooksEarlyExit>; + fn drop_big_int(&self, handle: i32) -> Result<(), VMHooksEarlyExit>; + fn drop_elliptic_curve(&self, handle: i32) -> Result<(), VMHooksEarlyExit>; + fn drop_managed_map(&self, handle: i32) -> Result<(), VMHooksEarlyExit>; +} + +impl VMHooksDebugger for VMHooksDispatcher { + fn drop_managed_buffer(&self, handle: i32) -> Result<(), VMHooksEarlyExit> { + self.handler.mb_drop(handle); + Ok(()) + } + + fn drop_big_float(&self, handle: i32) -> Result<(), VMHooksEarlyExit> { + self.handler.bf_drop(handle); + Ok(()) + } + + fn drop_big_int(&self, handle: i32) -> Result<(), VMHooksEarlyExit> { + self.handler.bi_drop(handle); + Ok(()) + } + + fn drop_elliptic_curve(&self, _handle: i32) -> Result<(), VMHooksEarlyExit> { + // TODO: not implemented + Ok(()) + } + + fn drop_managed_map(&self, handle: i32) -> Result<(), VMHooksEarlyExit> { + self.handler.mm_drop(handle); + Ok(()) + } +} diff --git a/framework/snippets/Cargo.toml b/framework/snippets/Cargo.toml index a0d17833db..eb16d567d8 100644 --- a/framework/snippets/Cargo.toml +++ b/framework/snippets/Cargo.toml @@ -14,11 +14,9 @@ keywords = ["multiversx", "blockchain", "contract", "snippets"] categories = ["cryptography::cryptocurrencies"] [features] -default = ["http", "default-tls"] +default = ["http"] http = ["multiversx-sdk-http", "tokio"] dapp = ["multiversx-sdk-dapp"] -default-tls = ["multiversx-sdk-http/default-tls"] -static-tls = ["multiversx-sdk-http/static-tls"] [dependencies] hex = "0.4" diff --git a/sdk/http/Cargo.toml b/sdk/http/Cargo.toml index a67ec45516..839e2056d9 100644 --- a/sdk/http/Cargo.toml +++ b/sdk/http/Cargo.toml @@ -16,14 +16,11 @@ categories = ["cryptography::cryptocurrencies", "api-bindings"] keywords = ["multiversx", "blockchain", "sdk", "api"] [features] -default = ["default-tls"] -default-tls = ["reqwest/default-tls"] -static-tls = ["reqwest/rustls-tls"] chain_simulator = [] [dependencies] tokio = { version = "1.24", features = ["full"] } -reqwest = { version = "0.12", features = ["blocking", "json"], default-features = false } +reqwest = { version = "0.13", features = ["rustls", "blocking", "json"], default-features = false } anyhow = "1.0.44" hex = "0.4.3" itertools = "0.14.0" diff --git a/tools/git-scraper/Cargo.toml b/tools/git-scraper/Cargo.toml index 59a6032bcc..e9294ce3bb 100644 --- a/tools/git-scraper/Cargo.toml +++ b/tools/git-scraper/Cargo.toml @@ -10,7 +10,7 @@ edition = "2024" authors = ["you"] [dependencies] -reqwest = { version = "0.11", features = ["blocking", "json"] } +reqwest = { version = "0.13", features = ["rustls", "blocking", "json"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" dotenv = "0.15" diff --git a/tools/rust-debugger/format-tests/src/format_tests.rs b/tools/rust-debugger/format-tests/src/format_tests.rs index 4e878b2df6..28129aa9a8 100644 --- a/tools/rust-debugger/format-tests/src/format_tests.rs +++ b/tools/rust-debugger/format-tests/src/format_tests.rs @@ -1,4 +1,7 @@ -use multiversx_sc_scenario::imports::*; +use multiversx_sc_scenario::{ + executor::debug::{ContractDebugInstance, ContractDebugStack}, + imports::*, +}; macro_rules! push { ($list: ident, $name:ident, $expected: expr ) => {{ @@ -13,7 +16,8 @@ macro_rules! push { // they have to be cloned if used before that point #[allow(clippy::redundant_clone)] fn main() { - DebugApi::dummy(); + // Set up a dummy context on the debug stack, required for all managed types + ContractDebugStack::static_push(ContractDebugInstance::dummy()); // Used by the python script which checks the variable summaries let mut to_check: Vec<(String, String)> = Vec::new(); @@ -76,7 +80,11 @@ fn main() { let hex_esdt_safe_address = Address::new(hex_esdt_safe); let esdt_safe_managed_address: ManagedAddress = ManagedAddress::from(hex_esdt_safe_address); - push!(to_check, esdt_safe_managed_address, "\"esdt-safe_____________\" - (32) 0x00000000000000000500657364742d736166655f5f5f5f5f5f5f5f5f5f5f5f5f"); + push!( + to_check, + esdt_safe_managed_address, + "\"esdt-safe_____________\" - (32) 0x00000000000000000500657364742d736166655f5f5f5f5f5f5f5f5f5f5f5f5f" + ); let test_token_identifier: TestTokenIdentifier = TestTokenIdentifier::new("TEST-123456"); push!(to_check, test_token_identifier, "\"str:TEST-123456\""); @@ -137,7 +145,11 @@ fn main() { 100, 5000u64.into(), )); - push!(to_check, managed_vec_of_payments, "(2) { [0] = { token_identifier: \"MYTOK-123456\", nonce: 42, amount: 1000 }, [1] = { token_identifier: \"MYTOK-abcdef\", nonce: 100, amount: 5000 } }"); + push!( + to_check, + managed_vec_of_payments, + "(2) { [0] = { token_identifier: \"MYTOK-123456\", nonce: 42, amount: 1000 }, [1] = { token_identifier: \"MYTOK-abcdef\", nonce: 100, amount: 5000 } }" + ); let egld_or_esdt_token_identifier_egld: EgldOrEsdtTokenIdentifier = EgldOrEsdtTokenIdentifier::egld(); @@ -169,7 +181,11 @@ fn main() { DebugApi, ManagedVec>, > = ManagedOption::some(managed_vec_of_addresses.clone()); - push!(to_check, managed_option_of_vec_of_addresses, "ManagedOption::some((1) { [0] = (32) 0x000000000000000000010000000000000000000000000000000000000002ffff })"); + push!( + to_check, + managed_option_of_vec_of_addresses, + "ManagedOption::some((1) { [0] = (32) 0x000000000000000000010000000000000000000000000000000000000002ffff })" + ); // 5. SC wasm - heap let heap_address: Address = managed_address.to_address(); @@ -244,7 +260,25 @@ fn main() { "OptionalValue::Some()" ); + // Invalid TxContext test - simulate access after context change + // This test relies on the debugger pretty printer's error handling + // to detect when a weak pointer becomes invalid + let biguint_with_invalid_context = + unsafe { BigUint::::from_handle(create_handle_from_dropped_context()) }; + push!( + to_check, + biguint_with_invalid_context, + "" + ); + breakpoint_marker_end_of_main(); + + // Clean up the dummy entry on stack + ContractDebugStack::static_pop(); +} + +fn create_handle_from_dropped_context() -> DebugHandle { + DebugHandle::new_with_explicit_context_ref(std::sync::Weak::new(), -100i32) } fn breakpoint_marker_end_of_main() {} diff --git a/tools/rust-debugger/pretty-printers/format-python.sh b/tools/rust-debugger/pretty-printers/format-python.sh new file mode 100755 index 0000000000..1fb4d0e0e3 --- /dev/null +++ b/tools/rust-debugger/pretty-printers/format-python.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Python code formatting script for MultiversX SDK pretty-printers +echo "🐍 Formatting Python code..." + +# Get the SDK root directory (3 levels up from this script) +SDK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +PYTHON_CMD="$SDK_ROOT/.venv/bin/python" + +# Find Python files in this directory +PYTHON_FILES=$(find . -name "*.py" -maxdepth 1) + +if [ -z "$PYTHON_FILES" ]; then + echo "No Python files found to format" + exit 0 +fi + +echo "Found $(echo "$PYTHON_FILES" | wc -l) Python files to format" + +# Check if virtual environment exists +if [ ! -f "$PYTHON_CMD" ]; then + echo "❌ Python virtual environment not found at $PYTHON_CMD" + echo "Please run 'configure_python_environment' from the SDK root first" + exit 1 +fi + +# 1. Sort imports with isort +echo "📦 Sorting imports with isort..." +$PYTHON_CMD -m isort $PYTHON_FILES + +# 2. Format code with black +echo "🖤 Formatting code with black..." +$PYTHON_CMD -m black $PYTHON_FILES + +# 3. Check style with flake8 (optional) +if [ "$1" = "--check" ]; then + echo "🔍 Checking style with flake8..." + $PYTHON_CMD -m flake8 $PYTHON_FILES --max-line-length=88 --extend-ignore=E203,W503 +fi + +echo "✅ Python formatting complete!" \ No newline at end of file diff --git a/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py b/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py index 009e010f56..3a92d034b8 100644 --- a/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py +++ b/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py @@ -4,14 +4,15 @@ ### Version: 0.64.1 ############################################################################## -from functools import partial -import string -from typing import Callable, Collection, Iterable, List, Tuple, Type -from lldb import SBValue, SBDebugger -import lldb -from pathlib import Path import re +import string import struct +from functools import partial +from pathlib import Path +from typing import Callable, Collection, Iterable, List, Tuple, Type + +import lldb # type: ignore[import] +from lldb import SBDebugger, SBValue # type: ignore[import] VM_TYPE_ADDRESS = "0000000050" DEBUG_API_TYPE = "multiversx_sc_scenario::api::impl_vh::vm_hooks_api::VMHooksApi" @@ -27,15 +28,21 @@ BIG_INT_TYPE = f"{MANAGED_BASIC_PATH}::big_int::BigInt<{DEBUG_API_TYPE} ?>" BIG_FLOAT_TYPE = f"{MANAGED_BASIC_PATH}::big_float::BigFloat<{DEBUG_API_TYPE} ?>" -MANAGED_BUFFER_TYPE = f"{MANAGED_BASIC_PATH}::managed_buffer::ManagedBuffer<{DEBUG_API_TYPE} ?>" +MANAGED_BUFFER_TYPE = ( + f"{MANAGED_BASIC_PATH}::managed_buffer::ManagedBuffer<{DEBUG_API_TYPE} ?>" +) # 3. SC wasm - Managed wrapped types ## 3a. general MANAGED_WRAPPED_PATH = "multiversx_sc::types::managed::wrapped" BIG_UINT_TYPE = f"{MANAGED_WRAPPED_PATH}::num::big_uint::BigUint<{DEBUG_API_TYPE} ?>" NON_ZERO_BIG_UINT_TYPE = f"{MANAGED_WRAPPED_PATH}::num::non_zero_big_uint::NonZeroBigUint<{DEBUG_API_TYPE} ?>" -MANAGED_ADDRESS_TYPE = f"{MANAGED_WRAPPED_PATH}::managed_address::ManagedAddress<{DEBUG_API_TYPE} ?>" -MANAGED_BYTE_ARRAY_TYPE = f"{MANAGED_WRAPPED_PATH}::managed_byte_array::ManagedByteArray<{DEBUG_API_TYPE} ?>" +MANAGED_ADDRESS_TYPE = ( + f"{MANAGED_WRAPPED_PATH}::managed_address::ManagedAddress<{DEBUG_API_TYPE} ?>" +) +MANAGED_BYTE_ARRAY_TYPE = ( + f"{MANAGED_WRAPPED_PATH}::managed_byte_array::ManagedByteArray<{DEBUG_API_TYPE} ?>" +) ## 3b. tokens & payments MANAGED_WRAPPED_TOKEN_PATH = "multiversx_sc::types::managed::wrapped::token" ESDT_TOKEN_IDENTIFIER_TYPE = f"{MANAGED_WRAPPED_TOKEN_PATH}::esdt_token_identifier::EsdtTokenIdentifier<{DEBUG_API_TYPE} ?>" @@ -49,7 +56,9 @@ MANAGED_OPTION_TYPE = f"{MANAGED_WRAPPED_PATH}::managed_option::ManagedOption<{DEBUG_API_TYPE}, {ANY_TYPE}>" # ManagedVec MANAGED_VEC_INNER_TYPE_INDEX = 1 -MANAGED_VEC_TYPE = f"{MANAGED_WRAPPED_PATH}::managed_vec::ManagedVec<{DEBUG_API_TYPE}, {ANY_TYPE}>" +MANAGED_VEC_TYPE = ( + f"{MANAGED_WRAPPED_PATH}::managed_vec::ManagedVec<{DEBUG_API_TYPE}, {ANY_TYPE}>" +) # 4. SC wasm - Managed multi value types @@ -64,12 +73,17 @@ TEST_SC_ADDRESS_TYPE = f"{INTERACTION_EXPR_PATH}::test_sc_address::TestSCAddress" TEST_ADDRESS_TYPE = f"{INTERACTION_EXPR_PATH}::test_address::TestAddress" -TEST_TOKEN_IDENTIFIER_TYPE = f"{INTERACTION_EXPR_PATH}::test_token_identifier::TestTokenIdentifier" +TEST_TOKEN_IDENTIFIER_TYPE = ( + f"{INTERACTION_EXPR_PATH}::test_token_identifier::TestTokenIdentifier" +) # 7. MultiversX codec - Multi-types MULTI_TYPES_PATH = "multiversx_sc_codec::multi_types" -OPTIONAL_VALUE_TYPE = f"{MULTI_TYPES_PATH}::multi_value_optional::OptionalValue<{ANY_TYPE}>" +OPTIONAL_VALUE_TYPE = ( + f"{MULTI_TYPES_PATH}::multi_value_optional::OptionalValue<{ANY_TYPE}>" +) + class InvalidHandle(Exception): def __init__(self, raw_handle: int, map_: lldb.value) -> None: @@ -78,12 +92,24 @@ def __init__(self, raw_handle: int, map_: lldb.value) -> None: super().__init__(error) +class InvalidWeakPointer(Exception): + def __init__(self, raw_handle: int) -> None: + error = f"" + super().__init__(error) + + def check_invalid_handle(callable: Callable) -> Callable: def wrapped(*args) -> str: try: return callable(*args) except InvalidHandle as e: return str(e) + except InvalidWeakPointer as e: + return str(e) + except Exception as e: + # Catch any other exceptions that might occur during pointer dereferencing + return f"" + return wrapped @@ -151,12 +177,12 @@ def bytes_to_int(bytes: Collection[int]) -> int: def num_bigint_data_to_int(value_vec_u64: lldb.value) -> int: - value_hex = ''.join(reversed(list(map(sb_value_to_hex, value_vec_u64.sbvalue)))) + value_hex = "".join(reversed(list(map(sb_value_to_hex, value_vec_u64.sbvalue)))) return hex_to_int(value_hex) def ints_to_hex(ints: Iterable[int]) -> str: - return ''.join(map(u8_to_hex, ints)) + return "".join(map(u8_to_hex, ints)) def buffer_to_bytes(buffer: lldb.value) -> List[int]: @@ -179,7 +205,7 @@ def bytes_to_handle(bytes: List[int]) -> int: -112 """ bytes_hex = ints_to_hex(bytes) - return struct.unpack('>i', bytearray.fromhex(bytes_hex))[0] + return struct.unpack(">i", bytearray.fromhex(bytes_hex))[0] def format_buffer_hex_string(buffer_hex: str) -> str: @@ -199,27 +225,31 @@ def ascii_to_string(buffer_iterator: Iterable[int]) -> str: >>> ascii_to_string([116, 101, 115, 116]) 'test' """ - return ''.join(map(chr, buffer_iterator)) + return "".join(map(chr, buffer_iterator)) + def buffer_to_bytes_without_vm_type(buffer: lldb.value) -> List[int]: buffer_ints = buffer_to_bytes(buffer) buffer_vm_type = buffer_to_bytes(VM_TYPE_ADDRESS) - if buffer_ints[:len(buffer_vm_type)] == buffer_vm_type: - return buffer_ints[len(buffer_vm_type):] + if buffer_ints[: len(buffer_vm_type)] == buffer_vm_type: + return buffer_ints[len(buffer_vm_type) :] return buffer_ints + def buffer_as_string(buffer: lldb.value) -> str: buffer_ints = buffer_to_bytes_without_vm_type(buffer) buffer_string = ascii_to_string(buffer_ints) return f'"{buffer_string}"' + def interaction_type_as_string(buffer: lldb.value, prefix: str) -> str: buffer_ints = buffer_to_bytes(buffer) buffer_string = ascii_to_string(buffer_ints) return f'"{prefix}:{buffer_string}"' + def mixed_representation(buffer: lldb.value) -> str: buffer_hex = format_buffer_hex(buffer) buffer_string = buffer_as_string(buffer) @@ -237,8 +267,8 @@ def parse_handles_from_buffer_hex(buffer_hex: str) -> List[int]: """ raw_handles = [] for handle_bytes_iter in zip(*[iter(buffer_hex)] * 8): - handle_bytes_hex = ''.join(handle_bytes_iter) - raw_handle = struct.unpack('>i', bytearray.fromhex(handle_bytes_hex))[0] + handle_bytes_hex = "".join(handle_bytes_iter) + raw_handle = struct.unpack(">i", bytearray.fromhex(handle_bytes_hex))[0] raw_handles.append(raw_handle) return raw_handles @@ -277,14 +307,32 @@ def map_picker(self) -> Callable: def lookup(self, full_value: lldb.value) -> lldb.value: return full_value - def extract_value_from_raw_handle(self, context: lldb.value, raw_handle: int, map_picker: Callable) -> lldb.value: - managed_types = context[0].managed_types.data.value + def extract_value_from_raw_handle( + self, context: lldb.value, raw_handle: int, map_picker: Callable + ) -> lldb.value: + weak_inner = context.ptr.pointer # object is of Rust type: ArcInner + + # Check the strong count to see if the object is still alive + # If strong count is 0, the object has been dropped + strong_atomic_usize = weak_inner.strong # object is of Rust type: Atomic + strong_count = int(strong_atomic_usize.v.value) + if strong_count == 0: + raise InvalidWeakPointer(raw_handle) + + # Handle Weak by accessing the ptr field directly + # context is Weak, which contains ptr that points to the WeakInner + # The WeakInner contains a pointer to the actual TxContext data + # In LLDB, we access: context.ptr.pointer (NonNull>) -> pointer.data -> TxContext + tx_context = weak_inner.data + managed_types = tx_context.managed_types.data.value chosen_map = map_picker(managed_types) value = map_lookup(chosen_map, raw_handle) return value @check_invalid_handle - def summary_from_raw_handle(self, raw_handle: int, context: lldb.value, type_info: lldb.SBType) -> str: + def summary_from_raw_handle( + self, raw_handle: int, context: lldb.value, type_info: lldb.SBType + ) -> str: map_picker = self.map_picker() value = self.extract_value_from_raw_handle(context, raw_handle, map_picker) return self.value_summary(value, context, type_info) @@ -294,10 +342,13 @@ def summary(self, original_value: lldb.value) -> str: managed_value = self.lookup(original_value) handle = managed_value.handle raw_handle = int(handle.raw_handle) + # Handle Weak by getting the context from the handle context = handle.context return self.summary_from_raw_handle(raw_handle, context, type_info) - def value_summary(self, value: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + def value_summary( + self, value: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: pass @@ -305,7 +356,9 @@ class ManagedVecItem(Handler): def item_size(self) -> int: pass - def summarize_item(self, bytes: List[int], context: lldb.value, type_info: lldb.SBType) -> str: + def summarize_item( + self, bytes: List[int], context: lldb.value, type_info: lldb.SBType + ) -> str: pass @@ -317,7 +370,9 @@ class PlainManagedVecItem(ManagedVecItem, ManagedType): def item_size(self) -> int: return 4 - def summarize_item(self, handle_bytes: List[int], context: lldb.value, type_info: lldb.SBType) -> str: + def summarize_item( + self, handle_bytes: List[int], context: lldb.value, type_info: lldb.SBType + ) -> str: raw_handle = bytes_to_handle(handle_bytes) return self.summary_from_raw_handle(raw_handle, context, type_info) @@ -325,7 +380,7 @@ def summarize_item(self, handle_bytes: List[int], context: lldb.value, type_info class NumBigInt(Handler): def summary(self, num_big_int: lldb.value) -> str: value_int = num_bigint_data_to_int(num_big_int.data.data) - if num_big_int.sign.sbvalue.GetValue() == 'Minus': + if num_big_int.sign.sbvalue.GetValue() == "Minus": return str(-value_int) return str(value_int) @@ -340,7 +395,9 @@ class BigInt(PlainManagedVecItem, ManagedType): def map_picker(self) -> Callable: return pick_big_int - def value_summary(self, value: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + def value_summary( + self, value: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: return str(value.sbvalue.GetSummary()) @@ -348,23 +405,29 @@ class BigFloat(PlainManagedVecItem, ManagedType): def map_picker(self) -> Callable: return pick_big_float - def value_summary(self, value: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + def value_summary( + self, value: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: return str(value.sbvalue.GetValue()) class ManagedBuffer(PlainManagedVecItem, ManagedType): - def value_summary(self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + def value_summary( + self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: return mixed_representation(buffer) class BigUint(PlainManagedVecItem, ManagedType): def map_picker(self) -> Callable: return pick_big_int - + def lookup(self, big_uint: lldb.value) -> lldb.value: return big_uint.value - def value_summary(self, big_uint: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + def value_summary( + self, big_uint: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: return big_uint.sbvalue.GetSummary() @@ -372,7 +435,9 @@ class EsdtTokenIdentifier(PlainManagedVecItem, ManagedType): def lookup(self, token_identifier: lldb.value) -> lldb.value: return token_identifier.token_id.buffer - def value_summary(self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + def value_summary( + self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: return buffer_as_string(buffer) @@ -380,24 +445,35 @@ class ManagedAddress(PlainManagedVecItem, ManagedType): def lookup(self, managed_address: lldb.value) -> lldb.value: return managed_address.bytes.buffer - def value_summary(self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + def value_summary( + self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: return mixed_representation(buffer) + class ManagedByteArray(PlainManagedVecItem, ManagedType): def lookup(self, managed_byte_array: lldb.value) -> lldb.value: return managed_byte_array.buffer - def value_summary(self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + def value_summary( + self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: return mixed_representation(buffer) class ManagedOption(PlainManagedVecItem, ManagedType): - def summary_from_raw_handle(self, raw_handle: int, context: lldb.value, type_info: lldb.SBType) -> str: + def summary_from_raw_handle( + self, raw_handle: int, context: lldb.value, type_info: lldb.SBType + ) -> str: if raw_handle == MANAGED_OPTION_NONE_HANDLE: return "ManagedOption::none()" - inner_type_handler, inner_type = get_inner_type_handler(type_info, MANAGED_OPTION_INNER_TYPE_INDEX) - assert(isinstance(inner_type_handler, ManagedType)) - inner_summary = inner_type_handler.summary_from_raw_handle(raw_handle, context, inner_type) + inner_type_handler, inner_type = get_inner_type_handler( + type_info, MANAGED_OPTION_INNER_TYPE_INDEX + ) + assert isinstance(inner_type_handler, ManagedType) + inner_summary = inner_type_handler.summary_from_raw_handle( + raw_handle, context, inner_type + ) return f"ManagedOption::some({inner_summary})" @@ -410,7 +486,7 @@ def split_bytes(bytes: List[int], sizes: Iterable[int]) -> List[List[int]]: chunks = [] i = 0 for size in sizes: - chunks.append(bytes[i: i + size]) + chunks.append(bytes[i : i + size]) i += size return chunks @@ -425,7 +501,7 @@ def split_bytes_fixed_size(bytes: List[int], size: int) -> List[List[int]]: i = 0 byte_count = len(bytes) while i < byte_count: - chunks.append(bytes[i: i + size]) + chunks.append(bytes[i : i + size]) i += size return chunks @@ -442,9 +518,15 @@ def summary(self, payment: lldb.value) -> str: def item_size(self) -> int: return sum(self.COMPONENT_SIZES) - def summarize_item(self, bytes: List[int], context: lldb.value, type_info: lldb.SBType) -> str: - token_id_handle_bytes, nonce_bytes, amount_handle_bytes = split_bytes(bytes, self.COMPONENT_SIZES) - token_id = EsdtTokenIdentifier().summarize_item(token_id_handle_bytes, context, None) + def summarize_item( + self, bytes: List[int], context: lldb.value, type_info: lldb.SBType + ) -> str: + token_id_handle_bytes, nonce_bytes, amount_handle_bytes = split_bytes( + bytes, self.COMPONENT_SIZES + ) + token_id = EsdtTokenIdentifier().summarize_item( + token_id_handle_bytes, context, None + ) nonce = bytes_to_int(nonce_bytes) amount = BigInt().summarize_item(amount_handle_bytes, context, None) return self.to_string(token_id, nonce, amount) @@ -457,24 +539,33 @@ class EgldOrEsdtTokenIdentifier(PlainManagedVecItem, ManagedType): def lookup(self, egld_or_esdt_token_identifier: lldb.value) -> lldb.value: return egld_or_esdt_token_identifier.token_id.buffer - def value_summary(self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + def value_summary( + self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: token_id = buffer_as_string(buffer) if token_id == '"EGLD-000000"': return "EgldOrEsdtTokenIdentifier::egld()" - return f"EgldOrEsdtTokenIdentifier::esdt({token_id})" + return f"EgldOrEsdtTokenIdentifier::esdt({token_id})" class ManagedVec(PlainManagedVecItem, ManagedType): def lookup(self, managed_vec: lldb.value) -> lldb.value: return managed_vec.buffer - def value_summary(self, value: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: - item_handler, inner_type = get_inner_type_handler(type_info, MANAGED_VEC_INNER_TYPE_INDEX) - assert(isinstance(item_handler, ManagedVecItem)) + def value_summary( + self, value: lldb.value, context: lldb.value, type_info: lldb.SBType + ) -> str: + item_handler, inner_type = get_inner_type_handler( + type_info, MANAGED_VEC_INNER_TYPE_INDEX + ) + assert isinstance(item_handler, ManagedVecItem) buffer_bytes = buffer_to_bytes(value) item_size = item_handler.item_size() bytes_of_all_items = split_bytes_fixed_size(buffer_bytes, item_size) - items = [item_handler.summarize_item(bytes, context, inner_type) for bytes in bytes_of_all_items] + items = [ + item_handler.summarize_item(bytes, context, inner_type) + for bytes in bytes_of_all_items + ] return format_vec(items) @@ -493,25 +584,33 @@ def summary(self, boxed_bytes: lldb.value) -> str: buffer_hex = ints_to_hex(raw) return format_buffer_hex_string(buffer_hex) + class TestSCAddress(Handler): def summary(self, test_sc_address: lldb.value) -> str: buffer = lldb.value(test_sc_address.sbvalue.GetChildAtIndex(0)) return interaction_type_as_string(buffer, "sc") - + + class TestAddress(Handler): def summary(self, test_address: lldb.value) -> str: buffer = lldb.value(test_address.sbvalue.GetChildAtIndex(0)) return interaction_type_as_string(buffer, "address") - + + class TestTokenIdentifier(Handler): def summary(self, test_address: lldb.value) -> str: buffer = lldb.value(test_address.sbvalue.GetChildAtIndex(0)) return interaction_type_as_string(buffer, "str") + class OptionalValue(Handler): def summary(self, optional_value: lldb.value) -> str: base_type = optional_value.sbvalue.GetType().GetName() - if optional_value.value.sbvalue.GetType().GetName().startswith(f'{base_type}::Some'): + if ( + optional_value.value.sbvalue.GetType() + .GetName() + .startswith(f"{base_type}::Some") + ): summary = optional_value.value.sbvalue.GetChildAtIndex(0).GetSummary() return f"OptionalValue::Some({summary})" return "OptionalValue::None" @@ -550,10 +649,12 @@ def summary(self, optional_value: lldb.value) -> str: class UnknownType(Exception): def __init__(self, type_name: str) -> None: - super().__init__(f'unknown type: {type_name}') + super().__init__(f"unknown type: {type_name}") -def get_inner_type_handler(type_info: lldb.SBType, inner_type_index: int) -> Tuple[Handler, lldb.SBType]: +def get_inner_type_handler( + type_info: lldb.SBType, inner_type_index: int +) -> Tuple[Handler, lldb.SBType]: inner_type = type_info.GetTemplateArgumentType(inner_type_index).GetCanonicalType() handler = get_handler(inner_type.GetName()) return handler, inner_type @@ -573,7 +674,7 @@ def summarize_handler(handler_type: Type[Handler], valobj: SBValue, dictionary) def __lldb_init_module(debugger: SBDebugger, dict): - python_module_name = Path(__file__).with_suffix('').name + python_module_name = Path(__file__).with_suffix("").name for rust_type, handler_class in MULTIVERSX_WASM_TYPE_HANDLERS: # Add summary binding @@ -585,4 +686,4 @@ def __lldb_init_module(debugger: SBDebugger, dict): # print(f"Registered: {summary_command}") # Enable categories - debugger.HandleCommand('type category enable multiversx-sc') + debugger.HandleCommand("type category enable multiversx-sc") diff --git a/tools/rust-debugger/pretty-printers/pyproject.toml b/tools/rust-debugger/pretty-printers/pyproject.toml new file mode 100644 index 0000000000..400b7c3f24 --- /dev/null +++ b/tools/rust-debugger/pretty-printers/pyproject.toml @@ -0,0 +1,13 @@ +[tool.black] +line-length = 88 +target-version = ['py38', 'py39', 'py310', 'py311'] +include = '\.pyi?$' +extend-exclude = ''' +/( + # directories + \.eggs + | \.git + | \.venv + | target +)/ +''' \ No newline at end of file