diff --git a/Cargo.lock b/Cargo.lock index b85b2e1..2fdf91d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,11 +14,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ - "gimli 0.28.1", + "gimli 0.29.0", ] [[package]] @@ -29,9 +29,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -40,20 +40,32 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -70,11 +82,11 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786689872ec4e7d354810ab0dffd48bb40b838c047522eb031cbd47d15634849" +checksum = "bc05b04ac331a9f07e3a4036ef7926e49a8bf84a99a1ccfc7e2ab55a5fcbb372" dependencies = [ - "alloy-primitives 0.7.2", + "alloy-primitives 0.7.7", "alloy-sol-type-parser", "serde", "serde_json", @@ -104,9 +116,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525448f6afc1b70dd0f9d0a8145631bf2f5e434678ab23ab18409ca264cae6b3" +checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" dependencies = [ "alloy-rlp", "bytes", @@ -126,9 +138,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.4" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" +checksum = "a43b18702501396fa9bcdeecd533bc85fac75150d308fc0f6800a01e6234a003" dependencies = [ "arrayvec", "bytes", @@ -136,53 +148,68 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89c80a2cb97e7aa48611cbb63950336f9824a174cdf670527cc6465078a26ea1" +checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" dependencies = [ "alloy-sol-macro-input", "const-hex", - "heck 0.4.1", - "indexmap 2.1.0", + "heck", + "indexmap 2.2.6", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58894b58ac50979eeac6249661991ac40b9d541830d9a725f7714cc9ef08c23" +checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" dependencies = [ "const-hex", "dunce", - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8e71ea68e780cc203919e03f69f59e7afe92d2696fb1dcb6662f61e4031b6" +checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" dependencies = [ - "winnow 0.6.7", + "serde", + "winnow 0.6.16", ] [[package]] name = "alloy-sol-types" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399287f68d1081ed8b1f4903c49687658b95b142207d7cb4ae2f4813915343ef" +checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" dependencies = [ - "alloy-primitives 0.7.2", + "alloy-primitives 0.7.7", "alloy-sol-macro", "const-hex", "serde", @@ -190,47 +217,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -377,13 +405,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -399,27 +427,26 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -483,9 +510,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -530,9 +557,9 @@ dependencies = [ [[package]] name = "bs58" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ "sha2", "tinyvec", @@ -540,9 +567,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -552,9 +579,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytecheck" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -563,15 +590,21 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "byteorder" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" + [[package]] name = "byteorder" version = "1.5.0" @@ -580,9 +613,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" dependencies = [ "serde", ] @@ -616,25 +649,25 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] [[package]] name = "cargo-stylus" -version = "0.4.0" +version = "0.4.2" dependencies = [ "cargo-stylus-util", "clap", @@ -643,7 +676,7 @@ dependencies = [ [[package]] name = "cargo-stylus-cgen" -version = "0.4.0" +version = "0.4.2" dependencies = [ "alloy-json-abi", "clap", @@ -654,11 +687,11 @@ dependencies = [ [[package]] name = "cargo-stylus-check" -version = "0.4.0" +version = "0.4.2" dependencies = [ "alloy-ethers-typecast", "alloy-json-abi", - "alloy-primitives 0.7.2", + "alloy-primitives 0.7.7", "alloy-sol-macro", "alloy-sol-types", "brotli2", @@ -673,25 +706,30 @@ dependencies = [ "lazy_static", "serde", "serde_json", + "sys-info", "tempfile", "thiserror", "tiny-keccak", "tokio", + "toml", + "wasm-encoder 0.213.0", + "wasm-gen", "wasmer", + "wasmparser 0.213.0", ] [[package]] name = "cargo-stylus-example" -version = "0.4.0" +version = "0.4.2" dependencies = [ "clap", ] [[package]] name = "cargo-stylus-replay" -version = "0.4.0" +version = "0.4.2" dependencies = [ - "alloy-primitives 0.7.2", + "alloy-primitives 0.7.7", "cargo-stylus-util", "clap", "ethers", @@ -709,7 +747,7 @@ dependencies = [ [[package]] name = "cargo-stylus-util" -version = "0.4.0" +version = "0.4.2" dependencies = [ "ethers", "eyre", @@ -725,7 +763,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -733,9 +771,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" dependencies = [ "jobserver", "libc", @@ -749,9 +787,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "num-traits", ] @@ -768,9 +806,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" dependencies = [ "clap_builder", "clap_derive", @@ -778,9 +816,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" dependencies = [ "anstream", "anstyle", @@ -790,21 +828,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "coins-bip32" @@ -860,15 +898,15 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "const-hex" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" dependencies = [ "cfg-if", "cpufeatures", @@ -1027,9 +1065,9 @@ checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -1055,9 +1093,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1098,9 +1136,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -1108,26 +1146,26 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1137,7 +1175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -1145,15 +1183,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -1181,23 +1219,17 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 1.0.109", + "syn 2.0.72", ] -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - [[package]] name = "digest" version = "0.9.0" @@ -1283,9 +1315,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -1308,27 +1340,27 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] [[package]] name = "enr" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" +checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" dependencies = [ "base64 0.21.7", "bytes", @@ -1364,23 +1396,23 @@ dependencies = [ [[package]] name = "enumset" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" +checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.8.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1391,9 +1423,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1471,9 +1503,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5344eea9b20effb5efeaad29418215c4d27017639fd1f908260f59cbbd226e" +checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1487,9 +1519,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf35eb7d2e2092ad41f584951e08ec7c077b142dba29c4f1b8f52d2efddc49c" +checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" dependencies = [ "ethers-core", "once_cell", @@ -1499,9 +1531,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0111ead599d17a7bff6985fd5756f39ca7033edc79a31b23026a8d5d64fa95cd" +checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -1518,9 +1550,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbdfb952aafd385b31d316ed80d7b76215ce09743c172966d840e96924427e0c" +checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" dependencies = [ "Inflector", "const-hex", @@ -1535,16 +1567,16 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.48", + "syn 2.0.72", "toml", "walkdir", ] [[package]] name = "ethers-contract-derive" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7465c814a2ecd0de0442160da13584205d1cdc08f4717a6511cad455bd5d7dc4" +checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" dependencies = [ "Inflector", "const-hex", @@ -1553,14 +1585,14 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "ethers-core" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918b1a9ba585ea61022647def2f27c29ba19f6d2a4a4c8f68a9ae97fd5769737" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" dependencies = [ "arrayvec", "bytes", @@ -1579,7 +1611,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.48", + "syn 2.0.72", "tempfile", "thiserror", "tiny-keccak", @@ -1588,14 +1620,14 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "facabf8551b4d1a3c08cb935e7fca187804b6c2525cc0dafb8e5a6dd453a24de" +checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" dependencies = [ "chrono", "ethers-core", "reqwest", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -1604,9 +1636,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681ece6eb1d10f7cf4f873059a77c04ff1de4f35c63dd7bccde8f438374fcb93" +checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" dependencies = [ "async-trait", "auto_impl", @@ -1631,9 +1663,9 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25d6c0c9455d93d4990c06e049abf9b30daf148cf461ee939c11d88907c60816" +checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" dependencies = [ "async-trait", "auto_impl", @@ -1668,9 +1700,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb1b714e227bbd2d8c53528adb580b203009728b17d0d0e4119353aa9bc5532" +checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" dependencies = [ "async-trait", "coins-bip32", @@ -1687,9 +1719,9 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2e46e3ec8ef0c986145901fa9864205dc4dcee701f9846be2d56112d34bdea" +checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" dependencies = [ "cfg-if", "const-hex", @@ -1704,7 +1736,7 @@ dependencies = [ "path-slash", "rayon", "regex", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "solang-parser", @@ -1719,9 +1751,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -1735,9 +1767,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fastrlp" @@ -1766,7 +1798,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ - "byteorder", + "byteorder 1.5.0", "rand", "rustc-hex", "static_assertions", @@ -1780,9 +1812,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1900,7 +1932,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1917,9 +1949,9 @@ checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ "gloo-timers", "send_wrapper 0.4.0", @@ -1949,7 +1981,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "byteorder", + "byteorder 1.5.0", ] [[package]] @@ -1965,9 +1997,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1987,9 +2019,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -2022,9 +2054,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -2032,7 +2064,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -2045,14 +2077,18 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.8", ] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash 0.8.11", + "serde", +] [[package]] name = "hashers" @@ -2063,12 +2099,6 @@ dependencies = [ "fxhash", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -2077,9 +2107,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -2116,9 +2146,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -2138,9 +2168,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -2150,9 +2180,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -2258,12 +2288,13 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", + "serde", ] [[package]] @@ -2277,9 +2308,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2291,15 +2322,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] -name = "is-terminal" -version = "0.4.10" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.52.0", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -2321,24 +2347,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -2382,9 +2408,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +checksum = "47a3633291834c4fbebf8673acbc1b04ec9d151418ff9b8e26dcd79129928758" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -2392,37 +2418,39 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", "bit-set", - "diff", "ena", - "is-terminal", - "itertools 0.10.5", + "itertools 0.11.0", "lalrpop-util", "petgraph", "regex", - "regex-syntax 0.7.5", + "regex-syntax", "string_cache", "term", "tiny-keccak", "unicode-xid", + "walkdir", ] [[package]] name = "lalrpop-util" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata", +] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -2438,12 +2466,12 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.1" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-targets 0.52.6", ] [[package]] @@ -2454,26 +2482,25 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "libc", - "redox_syscall", ] [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2481,9 +2508,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "mach" @@ -2494,6 +2521,15 @@ dependencies = [ "libc", ] +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + [[package]] name = "md-5" version = "0.10.6" @@ -2506,9 +2542,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" @@ -2536,22 +2572,23 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.10" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2562,36 +2599,40 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -2622,17 +2663,17 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "object" -version = "0.32.2" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" dependencies = [ "memchr", ] @@ -2676,9 +2717,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", "bitvec", @@ -2690,11 +2731,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 2.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -2702,9 +2743,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2712,15 +2753,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -2736,9 +2777,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "path-slash" @@ -2785,9 +2826,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -2796,12 +2837,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap 2.2.6", ] [[package]] @@ -2844,7 +2885,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -2867,29 +2908,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2909,9 +2950,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "powerfmt" @@ -2933,12 +2974,12 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.16" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -2955,32 +2996,13 @@ dependencies = [ "uint", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" -dependencies = [ - "toml_edit 0.20.7", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.0", + "toml_edit 0.21.1", ] [[package]] @@ -3009,28 +3031,28 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.2", + "bitflags 2.6.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.2", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -3064,9 +3086,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3118,9 +3140,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3138,18 +3160,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox", @@ -3170,65 +3192,59 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "region" -version = "3.0.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" +checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7" dependencies = [ "bitflags 1.3.2", "libc", - "mach", - "winapi", + "mach2", + "windows-sys 0.52.0", ] [[package]] name = "rend" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ "bytecheck", ] [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", "bytes", @@ -3252,6 +3268,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-rustls", @@ -3291,16 +3308,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3314,9 +3332,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", @@ -3328,14 +3346,14 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid 1.7.0", + "uuid 1.10.0", ] [[package]] name = "rkyv_derive" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" dependencies = [ "proc-macro2", "quote", @@ -3366,9 +3384,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.11.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -3390,15 +3408,15 @@ dependencies = [ [[package]] name = "ruint-macro" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hex" @@ -3430,7 +3448,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.21", + "semver 1.0.23", ] [[package]] @@ -3439,7 +3457,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -3448,12 +3466,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.17.7", + "ring 0.17.8", "rustls-webpki", "sct", ] @@ -3473,15 +3491,15 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty-fork" @@ -3497,9 +3515,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "salsa20" @@ -3521,9 +3539,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "cfg-if", "derive_more", @@ -3533,11 +3551,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -3567,7 +3585,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -3602,9 +3620,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -3632,9 +3650,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -3652,20 +3670,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -3674,9 +3692,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -3727,9 +3745,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" +checksum = "a9b57fd861253bff08bb1919e995f90ba8f4889de2726091c8876f3a4e823b40" dependencies = [ "cc", "cfg-if", @@ -3786,29 +3804,29 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" -version = "1.13.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b187f0231d56fe41bfb12034819dd2bf336422a5866de41bc3fec4b2e3883e8" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "sneks" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1754a9953937d149fb279d362241e4b92c4f237a491f4524835e8e78dd43810d" +checksum = "9659a8ce0c2f862add056dc8f43cb481176298f1df141ca16ea4d1fe3e6c8ad7" dependencies = [ "convert_case 0.6.0", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3880,44 +3898,44 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.25.0" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "svm-rs" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20689c7d03b6461b502d0b95d6c24874c7d24dea2688af80486a130a06af3b07" +checksum = "11297baafe5fa0c99d5722458eac6a5e25c01eb1b8e5cd137f54079093daa7a4" dependencies = [ "dirs", "fs2", "hex", "once_cell", "reqwest", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "sha2", @@ -3939,9 +3957,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -3950,14 +3968,30 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa0cefd02f532035d83cfec82647c6eb53140b0485220760e669f4bad489e36" +checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sys-info" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" +dependencies = [ + "cc", + "libc", ] [[package]] @@ -3989,9 +4023,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.13" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" +checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2" [[package]] name = "tempfile" @@ -4018,32 +4052,33 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4058,10 +4093,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -4076,9 +4112,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4091,30 +4127,29 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4144,72 +4179,60 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.8" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "81967dd0dd2c1ab0bc3468bd7caecc32b8a4aa47d0c8c695d8c2b2108168d62c" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit 0.22.17", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "toml_datetime", - "winnow 0.5.34", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.7" +version = "0.22.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +checksum = "8d9f8729f5aea9562aac1cc0441f5d6de3cff1ee0c5d67293eeca5eb36ee7c16" dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow 0.5.34", -] - -[[package]] -name = "toml_edit" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" -dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.5.34", + "winnow 0.6.16", ] [[package]] @@ -4237,7 +4260,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4271,7 +4294,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ - "byteorder", + "byteorder 1.5.0", "bytes", "data-encoding", "http", @@ -4303,7 +4326,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ - "byteorder", + "byteorder 1.5.0", "crunchy", "hex", "static_assertions", @@ -4329,24 +4352,24 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -4368,9 +4391,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -4385,9 +4408,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -4401,9 +4424,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" [[package]] name = "valuable" @@ -4428,9 +4451,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -4453,9 +4476,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4463,16 +4486,16 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -4501,9 +4524,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -4513,9 +4536,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4523,29 +4546,48 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-encoder" -version = "0.39.0" +version = "0.213.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850e4e6a56413a8f33567741a2388c8f6dafd841a939d945c7248671a8739dd8" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-encoder" +version = "0.214.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff694f02a8d7a50b6922b197ae03883fbf18cdb2ae9fbee7b6148456f5f44041" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-gen" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "111495d6204760238512f57a9af162f45086504da332af210f2f75dd80b34f1d" +checksum = "b854b1461005a7b3365742310f7faa3cac3add809d66928c64a40c7e9e842ebb" dependencies = [ + "byteorder 0.5.3", "leb128", ] @@ -4596,7 +4638,7 @@ dependencies = [ "thiserror", "wasmer-types", "wasmer-vm", - "wasmparser", + "wasmparser 0.95.0", "winapi", ] @@ -4684,32 +4726,47 @@ dependencies = [ "url", ] +[[package]] +name = "wasmparser" +version = "0.213.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48e5a90a9e0afc2990437f5600b8de682a32b18cbaaf6f2b5db185352868b6b" +dependencies = [ + "ahash 0.8.11", + "bitflags 2.6.0", + "hashbrown 0.14.5", + "indexmap 2.2.6", + "semver 1.0.23", + "serde", +] + [[package]] name = "wast" -version = "70.0.0" +version = "214.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee4bc54bbe1c6924160b9f75e374a1d07532e7580eb632c0ee6cdd109bb217e" +checksum = "694bcdb24c49c8709bd8713768b71301a11e823923eee355d530f1d8d0a7f8e9" dependencies = [ + "bumpalo", "leb128", "memchr", "unicode-width", - "wasm-encoder", + "wasm-encoder 0.214.0", ] [[package]] name = "wat" -version = "1.0.83" +version = "1.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f0dce8cdc288c717cf01e461a1e451a7b8445d53451123536ba576e423a101a" +checksum = "347249eb56773fa728df2656cfe3a8c19437ded61a922a0b5e0839d9790e278e" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -4717,9 +4774,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "winapi" @@ -4739,11 +4796,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -4780,7 +4837,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -4800,17 +4857,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -4821,9 +4879,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -4839,9 +4897,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -4857,9 +4915,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -4875,9 +4939,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -4893,9 +4957,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -4905,9 +4969,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -4923,24 +4987,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winnow" -version = "0.6.7" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578" +checksum = "b480ae9340fc261e6be3e95a1ba86d54ae3f9171132a73ce8d4bbaf68339507c" dependencies = [ "memchr", ] @@ -4989,11 +5053,31 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -5006,7 +5090,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -5016,7 +5100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ "aes", - "byteorder", + "byteorder 1.5.0", "bzip2", "constant_time_eq", "crc32fast", @@ -5050,9 +5134,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.12+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 55aed5d..640811d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,17 +4,17 @@ resolver = "2" [workspace.package] authors = ["Offchain Labs"] -version = "0.4.0" +version = "0.4.2" edition = "2021" homepage = "https://arbitrum.io" license = "MIT OR Apache-2.0" repository = "https://github.com/OffchainLabs/cargo-stylus" [workspace.dependencies] -alloy-primitives = "0.7.2" -alloy-json-abi = "0.7.2" -alloy-sol-macro = "0.7.2" -alloy-sol-types = "0.7.2" +alloy-primitives = "0.7.6" +alloy-json-abi = "0.7.6" +alloy-sol-macro = "0.7.6" +alloy-sol-types = "0.7.6" alloy-ethers-typecast = "0.2.0" clap = { version = "4.5.4", features = [ "derive", "color" ] } ethers = "2.0.10" @@ -34,4 +34,4 @@ parking_lot = "0.12.1" sneks = "0.1.2" # members -cargo-stylus-util = { path = "util", version = "0.4.0" } +cargo-stylus-util = { path = "util", version = "0.4.2" } diff --git a/README.md b/README.md index 9d2541f..cbee947 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Cargo Stylus +# Cargo Stylus [![linux](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/linux.yml/badge.svg)](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/linux.yml) [![mac](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/mac.yml/badge.svg)](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/mac.yml) [![windows](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/windows.yml/badge.svg)](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/windows.yml) [![lint](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/check.yml/badge.svg)](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/check.yml) -A cargo subcommand for building, verifying, and deploying Arbitrum Stylus WASM programs in Rust. +A cargo subcommand for building, verifying, and deploying Arbitrum Stylus WASM contracts in Rust. ## Quick Start @@ -29,16 +29,16 @@ cargo stylus --help Cargo command for developing Arbitrum Stylus projects -Usage: +Usage: cargo stylus new cargo stylus export-abi - cargo stylus check + cargo stylus check cargo stylus deploy ``` ### Overview -The cargo stylus command comes with useful commands such as `new`, `check` and `deploy`, and `export-abi` for developing and deploying Stylus programs to Arbitrum chains. Here's a common workflow: +The cargo stylus command comes with useful commands such as `new`, `check` and `deploy`, and `export-abi` for developing and deploying Stylus contracts to Arbitrum chains. Here's a common workflow: Start a new Stylus project with @@ -54,24 +54,23 @@ You can also use `cargo stylus new --minimal ` to create a mo All testnet information, including faucets and RPC endpoints can be found [here](https://docs.arbitrum.io/stylus/reference/testnet-information). - ### Developing With Stylus -Then, develop your Rust program normally and take advantage of all the features the [stylus-sdk](https://github.com/OffchainLabs/stylus-sdk-rs) has to offer. To check whether or not your program will successfully deploy and activate onchain, use the `cargo stylus check` subcommand: +Then, develop your Rust contract normally and take advantage of all the features the [stylus-sdk](https://github.com/OffchainLabs/stylus-sdk-rs) has to offer. To check whether or not your contract will successfully deploy and activate onchain, use the `cargo stylus check` subcommand: ``` cargo stylus check ``` -This command will attempt to verify that your program can be deployed and activated onchain without requiring a transaction by specifying a JSON-RPC endpoint. By default, it will use the public URL of the Stylus testnet as its endpoint. See [here](https://docs.arbitrum.io/stylus/reference/testnet-information) for available testnet RPC URLs. See `cargo stylus check --help` for more options. +This command will attempt to verify that your contract can be deployed and activated onchain without requiring a transaction by specifying a JSON-RPC endpoint. By default, it will use the public URL of the Stylus testnet as its endpoint. See [here](https://docs.arbitrum.io/stylus/reference/testnet-information) for available testnet RPC URLs. See `cargo stylus check --help` for more options. If the command above fails, you'll see detailed information about why your WASM will be rejected: ``` Reading WASM file at bad-export.wat Compressed WASM size: 55 B -Stylus checks failed: program predeployment check failed when checking against -ARB_WASM_ADDRESS 0x0000…0071: (code: -32000, message: program activation failed: failed to parse program) +Stylus checks failed: contract predeployment check failed when checking against +ARB_WASM_ADDRESS 0x0000…0071: (code: -32000, message: contract activation failed: failed to parse contract) Caused by: binary exports reserved symbol stylus_ink_left @@ -80,18 +79,18 @@ Location: prover/src/binary.rs:493:9, data: None) ``` -To read more about what counts as valid vs. invalid user WASM programs, see [VALID_WASM](./check/VALID_WASM.md). +To read more about what counts as valid vs. invalid user WASM contracts, see [VALID_WASM](./check/VALID_WASM.md). -If your program succeeds, you'll see the following message: +If your contract succeeds, you'll see the following message: ``` Finished release [optimized] target(s) in 1.88s Reading WASM file at hello-stylus/target/wasm32-unknown-unknown/release/hello-stylus.wasm Compressed WASM size: 3 KB -Program succeeded Stylus onchain activation checks with Stylus version: 1 +Contract succeeded Stylus onchain activation checks with Stylus version: 1 ``` -Once you're ready to deploy your program onchain, you can use the `cargo stylus deploy` subcommand as follows: +Once you're ready to deploy your contract onchain, you can use the `cargo stylus deploy` subcommand as follows: First, we can estimate the gas required to perform our deployment and activation with: @@ -105,7 +104,7 @@ and see: ``` Compressed WASM size: 3 KB -Deploying program to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 +Deploying contract to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 Estimated gas: 12756792 ``` @@ -120,21 +119,21 @@ and see: ``` Compressed WASM size: 3 KB -Deploying program to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 +Deploying contract to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 Estimated gas: 12756792 Submitting tx... Confirmed tx 0x42db…7311, gas used 11657164 -Activating program at address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 +Activating contract at address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 Estimated gas: 14251759 Submitting tx... Confirmed tx 0x0bdb…3307, gas used 14204908 ``` -## Compiling and Checking Stylus Programs +## Compiling and Checking Stylus Contracts **cargo stylus check** -Instruments a Rust project using Stylus. This command runs compiled WASM code through Stylus instrumentation checks and reports any failures. It **verifies the program can compile onchain** by making an eth_call to a Arbitrum chain RPC endpoint. +Instruments a Rust project using Stylus. This command runs compiled WASM code through Stylus instrumentation checks and reports any failures. It **verifies the contract can compile onchain** by making an eth_call to a Arbitrum chain RPC endpoint. ``` Usage: cargo stylus check [OPTIONS] @@ -142,11 +141,11 @@ Usage: cargo stylus check [OPTIONS] See `--help` for all available flags and default values. -## Deploying Stylus Programs +## Deploying Stylus Contracts **cargo stylus deploy** -Instruments a Rust project using Stylus and by outputting its brotli-compressed WASM code. Then, it submits **two transactions** by default: the first **deploys** the WASM program code to an address and the second triggers an **activation onchain**. Developers can choose to split up the deploy and activate steps via this command as desired. +Instruments a Rust project using Stylus and by outputting its brotli-compressed WASM code. Then, it submits **two transactions** by default: the first **deploys** the WASM contract code to an address and the second triggers an **activation onchain**. Developers can choose to split up the deploy and activate steps via this command as desired. ``` Usage: cargo stylus deploy [OPTIONS] @@ -154,26 +153,9 @@ Usage: cargo stylus deploy [OPTIONS] See `--help` for all available flags and default values. -## Verifying Stylus Programs - -**cargo stylus verify** - -Verifies that a deployed smart contract is identical to that produced by the -current project. Since Stylus smart contracts include a hash of all project -files, this additionally verifies that code comments and other files are -identical. To ensure build reproducibility, if a program is to be verified, -it should be both deployed and verified using `cargo stylus reproducible`. - -See `--help` for all available flags and default values. - -## Reproducibly Deploying and Verifying - -**cargo stylus reproducible** +## Verifying Stylus Contracts -Runs a `cargo stylus` command in a Docker container to ensure build -reproducibility. - -See `--help` for all available flags and default values. +See [here](https://hackmd.io/bpeMnrzbSvO4mohhvkrKqw) ## Deploying Non-Rust WASM Projects @@ -209,9 +191,14 @@ cargo stylus export-abi ## Optimizing Binary Sizes +<<<<<<< HEAD Brotli-compressed, Stylus program WASM binaries must fit within the **24Kb** [code-size limit](https://ethereum.org/en/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) of Ethereum smart contracts. By default, the `cargo stylus check` will attempt to compile a Rust program into WASM with reasonable optimizations and verify its compressed size fits within the limit. However, there are additional options available in case a program exceeds the 24Kb limit from using default settings. Deploying smaller binaries onchain is cheaper and better for the overall network, as deployed WASM programs will exist on the Arbitrum chain's storage forever. +======= +Brotli-compressed, Stylus contract WASM binaries must fit within the **24Kb** [code-size limit](https://ethereum.org/en/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) of Ethereum smart contracts. By default, the `cargo stylus check` will attempt to compile a Rust contract into WASM with reasonable optimizations and verify its compressed size fits within the limit. However, there are additional options available in case a contract exceeds the 24Kb limit from using default settings. Deploying smaller binaries onchain is cheaper and better for the overall network, as deployed WASM contracts will exist on the Arbitrum chain's storage forever. + +> > > > > > > main -We recommend optimizing your Stylus program's sizes to smaller sizes, but keep in mind the safety tradeoffs of using some of the more advanced optimizations. However, some small programs when compiled to much smaller sizes can suffer performance penalties. +We recommend optimizing your Stylus contract's sizes to smaller sizes, but keep in mind the safety tradeoffs of using some of the more advanced optimizations. However, some small contracts when compiled to much smaller sizes can suffer performance penalties. For a deep-dive into the different options for optimizing binary sizes using cargo stylus, see [OPTIMIZING_BINARIES.md](./check/OPTIMIZING_BINARIES.md). diff --git a/check/Cargo.toml b/check/Cargo.toml index c428200..d94052f 100644 --- a/check/Cargo.toml +++ b/check/Cargo.toml @@ -33,3 +33,8 @@ tokio.workspace = true wasmer = "3.1.0" glob = "0.3.1" tempfile = "3.10.1" +wasmparser = "0.213.0" +wasm-encoder = "0.213.0" +wasm-gen = "0.1.4" +toml = "0.8.14" +sys-info = "0.9.1" diff --git a/check/Dockerfile b/check/Dockerfile deleted file mode 100644 index cea0606..0000000 --- a/check/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM rust:1.71 as builder -COPY . . -RUN cargo build --release - -FROM debian:buster-slim -COPY --from=builder ./target/release/cargo-stylus ./target/release/cargo-stylus -CMD ["/target/release/cargo-stylus"] \ No newline at end of file diff --git a/check/OPTIMIZING_BINARIES.md b/check/OPTIMIZING_BINARIES.md index 45c66b3..24e2240 100644 --- a/check/OPTIMIZING_BINARIES.md +++ b/check/OPTIMIZING_BINARIES.md @@ -1,6 +1,6 @@ -# Optimizing Stylus Program WASM Binaries +# Optimizing Stylus Contract WASM Binaries -WASM programs need to be small to be deployed onchain. Stylus applies [brotli compression](https://github.com/google/brotli), which empirically reduces the footprint of common Rust WASMs by over 50%, the Stylus runtime obeys the EVM contract size limit of 24KB. This means that, after compression, **all WASMs must not exceed 24KB**. +WASM contracts need to be small to be deployed onchain. Stylus applies [brotli compression](https://github.com/google/brotli), which empirically reduces the footprint of common Rust WASMs by over 50%, the Stylus runtime obeys the EVM contract size limit of 24KB. This means that, after compression, **all WASMs must not exceed 24KB**. **Uncompressed WASM** files also have an enforced limit of **128Kb**. diff --git a/check/VALID_WASM.md b/check/VALID_WASM.md index 219246b..95b7ff9 100644 --- a/check/VALID_WASM.md +++ b/check/VALID_WASM.md @@ -1,8 +1,8 @@ -# Invalid Stylus WASM Programs +# Invalid Stylus WASM Contracts -This document explains the limitations of Stylus WASM programs and why certain programs might fail `cargo stylus check`. Stylus programs are bound by similar rules to Ethereum smart contracts when it comes to bounded execution, bounded memory use, and determinism. +This document explains the limitations of Stylus WASM contracts and why certain contracts might fail `cargo stylus check`. Stylus contracts are bound by similar rules to Ethereum smart contracts when it comes to bounded execution, bounded memory use, and determinism. -WASM programs must fit within the **24Kb** code size limit of Arbitrum chains _after_ compression. Uncompressed WASMs must have a size less than **128Kb**. +WASM contracts must fit within the **24Kb** code size limit of Arbitrum chains _after_ compression. Uncompressed WASMs must have a size less than **128Kb**. While Stylus includes a large portion of available WASM opcodes, not all of them are supported. To see the set of allowed / disallowed opcodes, see [here](https://github.com/OffchainLabs/stylus/blob/stylus/arbitrator/prover/src/wavm.rs#L731). @@ -15,4 +15,4 @@ When a user WASM gets "activated" on chain, it goes through a series of checks t 5. Check for **disallowed opcodes**, such as SIMD or other features 6. Disallow WASMs with an enormous amount of **functions and exports** -Stylus programs should use `#[no_std]` to avoid including the Rust standard library and keep code small. Many crates that build without the standard library make for great dependencies to use in Stylus programs, as long as the total, compressed WASM size is within the 24Kb code size limit. +Stylus contracts should use `#[no_std]` to avoid including the Rust standard library and keep code small. Many crates that build without the standard library make for great dependencies to use in Stylus contracts, as long as the total, compressed WASM size is within the 24Kb code size limit. diff --git a/check/src/activate.rs b/check/src/activate.rs index 9b8f213..21d8cf9 100644 --- a/check/src/activate.rs +++ b/check/src/activate.rs @@ -1,74 +1,72 @@ // Copyright 2023-2024, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md +// 라이선스 정보는 https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md에서 확인할 수 있습니다. -#![allow(clippy::println_empty_string)] +#![allow(clippy::println_empty_string)] // 빈 문자열을 println에 사용해도 Clippy 경고를 무시합니다. -use std::fs; -use std::io::{Read, Write}; -use std::path::PathBuf; +use std::fs; // 파일 시스템 작업을 위한 표준 라이브러리 사용 +use std::io::Write; // 파일에 데이터를 쓰기 위한 표준 라이브러리 사용 +use std::path::PathBuf; // 파일 경로를 처리하기 위한 표준 라이브러리 사용 -use alloy_primitives::{Address, U256 as AU256}; -use alloy_sol_macro::sol; -use alloy_sol_types::SolCall; +use alloy_primitives::Address; // Ethereum 주소를 처리하기 위한 라이브러리 +use alloy_sol_macro::sol; // Solidity 인터페이스를 정의하기 위한 매크로 +use alloy_sol_types::SolCall; // Solidity 함수 호출을 처리하기 위한 타입 use ethers::{ core::k256::ecdsa::SigningKey, middleware::SignerMiddleware, prelude::*, providers::{Middleware, Provider}, - types::{H160, U256, U64}, + types::transaction::eip2718::TypedTransaction, + types::{Eip1559TransactionRequest, H160, U256}, + utils::format_units, }; -use eyre::{eyre, Result}; +use eyre::{bail, eyre, Context, Result, WrapErr}; // 에러 핸들링을 위한 라이브러리 -use cargo_stylus_util::color::Color; +use cargo_stylus_util::color::{Color, DebugColor}; // 컬러 출력을 위한 유틸리티 +use cargo_stylus_util::sys; // 시스템 관련 유틸리티 -use crate::macros::greyln; -use crate::ActivateConfig; +use crate::check::check_activate; // 계약 활성화 체크 함수를 가져옵니다. +use crate::constants::ARB_WASM_H160; // Arbitrum WASM 주소 상수를 가져옵니다. +use crate::macros::greyln; // 컬러와 함께 로그를 출력하는 매크로를 가져옵니다. +use crate::ActivateConfig; // 활성화 구성 구조체를 가져옵니다. +use crate::ActivateWithoutPrivateKeyConfig; // 활성화 구성 구조체를 가져옵니다. pub enum TxKind { - Deployment, - Activation, + Deployment, // 배포 트랜잭션 + Activation, // 활성화 트랜잭션 } impl std::fmt::Display for TxKind { + // TxKind를 문자열로 출력하는 방법을 정의합니다. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match *self { - TxKind::Deployment => write!(f, "deployment"), - TxKind::Activation => write!(f, "activation"), + TxKind::Deployment => write!(f, "deployment"), // 배포 트랜잭션 + TxKind::Activation => write!(f, "activation"), // 활성화 트랜잭션 } } } sol! { interface ArbWasm { + // Arbitrum WASM 프로그램을 활성화하는 Solidity 함수 정의 function activateProgram(address program) external payable returns (uint16 version, uint256 dataFee); } - - } -type SignerClient = SignerMiddleware, Wallet>; - -/// Deploys a stylus program, activating if needed. -pub async fn activate(cfg: ActivateConfig) -> Result<()> { - greyln!("@@@ activate"); - let contract = cfg.contract_address.unwrap(); - let program: Address = contract.to_fixed_bytes().into(); - let data = ArbWasm::activateProgramCall { program }.abi_encode(); - write_tx_data(TxKind::Activation, &data)?; - Ok(()) -} +type SignerClient = SignerMiddleware, Wallet>; // 서명된 트랜잭션을 보내기 위한 클라이언트 타입 fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { + // 트랜잭션 데이터를 파일로 작성하는 함수 let file_name = format!("{tx_kind}_tx_data"); let mut path = PathBuf::new(); path.push("./output"); if !path.exists() { fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; + // 출력 디렉토리를 생성합니다. } - + path = path.join(file_name); let path_str = path.as_os_str().to_string_lossy(); let hex: String = data @@ -83,7 +81,79 @@ fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { hex ); let mut f = std::fs::File::create(&path) - .map_err(|e| eyre!("could not create file to write tx data to path {path_str}: {e}",))?; + .map_err(|e| eyre!("could not create file to write tx data to path {path_str}: {e}",))?; // 파일을 생성합니다. f.write_all(data) .map_err(|e| eyre!("could not write tx data as bytes to file to path {path_str}: {e}")) + // 데이터를 파일에 씁니다. +} + +/// 이미 배포된 Stylus 계약을 주소를 통해 활성화합니다. +pub async fn activate_contract(cfg: &ActivateConfig) -> Result<()> { + let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; // 프로바이더를 생성합니다. + let chain_id = provider + .get_chainid() + .await + .wrap_err("failed to get chain id")?; // 체인 ID를 가져옵니다. + + let wallet = cfg.auth.wallet().wrap_err("failed to load wallet")?; // 지갑을 로드합니다. + let wallet = wallet.with_chain_id(chain_id.as_u64()); + let client = SignerMiddleware::new(provider.clone(), wallet); // 서명된 트랜잭션 클라이언트를 생성합니다. + + let code = client.get_code(cfg.address, None).await?; // 계약의 코드를 가져옵니다. + let data_fee = check_activate(code, cfg.address, &provider).await?; // 활성화에 필요한 데이터 수수료를 계산합니다. + let mut data_fee = alloy_ethers_typecast::alloy_u256_to_ethers(data_fee); + + greyln!( + "obtained estimated activation data fee {}", + format_units(data_fee, "ether")?.debug_lavender() + ); + greyln!( + "bumping estimated activation data fee by {}%", + cfg.data_fee_bump_percent.debug_lavender() + ); + data_fee = bump_data_fee(data_fee, cfg.data_fee_bump_percent); // 데이터 수수료를 조정합니다. + + let contract: Address = cfg.address.to_fixed_bytes().into(); + let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); // 프로그램 활성화 트랜잭션을 생성합니다. + let tx = Eip1559TransactionRequest::new() + .from(client.address()) + .to(*ARB_WASM_H160) + .value(data_fee) + .data(data); + let tx = TypedTransaction::Eip1559(tx); + let tx = client.send_transaction(tx, None).await?; // 트랜잭션을 전송합니다. + match tx.await? { + Some(receipt) => { + greyln!( + "successfully activated contract 0x{} with tx {}", + hex::encode(cfg.address), + hex::encode(receipt.transaction_hash).debug_lavender() + ); + let program: Address = cfg.address.to_fixed_bytes().into(); + let data = ArbWasm::activateProgramCall { program }.abi_encode(); + write_tx_data(TxKind::Activation, &data)?; // 트랜잭션 데이터를 파일로 작성합니다. + } + None => { + bail!( + "failed to fetch receipt for contract activation {}", + cfg.address + ); // 트랜잭션 영수증을 가져오지 못한 경우 오류를 발생시킵니다. + } + } + Ok(()) +} + +/// Deploys a stylus program, activating if needed. +pub async fn activate(cfg: &ActivateWithoutPrivateKeyConfig) -> Result<()> { + greyln!("@@@ activate"); + let contract: Address = cfg.address.to_fixed_bytes().into(); + let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); // 프로그램 활성화 트랜잭션을 생성합니다. + write_tx_data(TxKind::Activation, &data)?; + Ok(()) +} + +fn bump_data_fee(fee: U256, pct: u64) -> U256 { + // 데이터 수수료를 지정된 퍼센트만큼 증가시킵니다. + let num = 100 + pct; + fee * U256::from(num) / U256::from(100) } diff --git a/check/src/cache.rs b/check/src/cache.rs index ab6899d..f850e50 100644 --- a/check/src/cache.rs +++ b/check/src/cache.rs @@ -1,7 +1,7 @@ // Copyright 2023-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/stylus/licenses/COPYRIGHT.md -use alloy_primitives::FixedBytes; +use alloy_primitives::Address; use alloy_sol_macro::sol; use alloy_sol_types::{SolCall, SolInterface}; use cargo_stylus_util::color::{Color, DebugColor}; @@ -9,28 +9,32 @@ use cargo_stylus_util::sys; use ethers::middleware::{Middleware, SignerMiddleware}; use ethers::signers::Signer; use ethers::types::spoof::State; -use ethers::types::{Eip1559TransactionRequest, U256}; -use ethers::utils::keccak256; +use ethers::types::transaction::eip2718::TypedTransaction; +use ethers::types::{Eip1559TransactionRequest, H160, U256}; use eyre::{bail, Context, Result}; use crate::check::{eth_call, EthCallError}; -use crate::constants::{CACHE_MANAGER_H160, EOF_PREFIX_NO_DICT}; +use crate::constants::ARB_WASM_CACHE_H160; use crate::deploy::{format_gas, run_tx}; use crate::macros::greyln; use crate::CacheConfig; sol! { + interface ArbWasmCache { + function allCacheManagers() external view returns (address[] memory managers); + } interface CacheManager { - function placeBid(bytes32 codehash) external payable; + function placeBid(address program) external payable; error AsmTooLarge(uint256 asm, uint256 queueSize, uint256 cacheSize); error AlreadyCached(bytes32 codehash); error BidTooSmall(uint192 bid, uint192 min); error BidsArePaused(); + error ProgramNotActivated(); } } -pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { +pub async fn cache_contract(cfg: &CacheConfig) -> Result<()> { let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; let chain_id = provider .get_chainid() @@ -41,27 +45,25 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { let wallet = wallet.with_chain_id(chain_id.as_u64()); let client = SignerMiddleware::new(provider.clone(), wallet); - let program_code = client - .get_code(cfg.program_address, None) - .await - .wrap_err("failed to fetch program code")?; - - if !program_code.starts_with(hex::decode(EOF_PREFIX_NO_DICT).unwrap().as_slice()) { - bail!( - "program code does not start with Stylus prefix {}", - EOF_PREFIX_NO_DICT - ); + let data = ArbWasmCache::allCacheManagersCall {}.abi_encode(); + let tx = Eip1559TransactionRequest::new() + .to(*ARB_WASM_CACHE_H160) + .data(data); + let tx = TypedTransaction::Eip1559(tx); + let result = client.call(&tx, None).await?; + let cache_managers_result = + ArbWasmCache::allCacheManagersCall::abi_decode_returns(&result, true)?; + let cache_manager_addrs = cache_managers_result.managers; + if cache_manager_addrs.is_empty() { + bail!("no cache managers found in ArbWasmCache, perhaps the Stylus cache is not yet enabled on this chain"); } - let codehash = FixedBytes::<32>::from(keccak256(&program_code)); - greyln!( - "Program codehash {}", - hex::encode(codehash).debug_lavender() - ); - let codehash = FixedBytes::<32>::from(keccak256(&program_code)); + let cache_manager = *cache_manager_addrs.last().unwrap(); + let cache_manager = H160::from_slice(cache_manager.as_slice()); - let data = CacheManager::placeBidCall { codehash }.abi_encode(); + let contract: Address = cfg.address.to_fixed_bytes().into(); + let data = CacheManager::placeBidCall { program: contract }.abi_encode(); let mut tx = Eip1559TransactionRequest::new() - .to(*CACHE_MANAGER_H160) + .to(cache_manager) .data(data); // If a bid is set, specify it. Otherwise, a zero bid will be sent. @@ -79,13 +81,16 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { }; use CacheManager::CacheManagerErrors as C; match error { - C::AsmTooLarge(_) => bail!("program too large"), - C::AlreadyCached(_) => bail!("program already cached"), + C::AsmTooLarge(_) => bail!("Stylus contract was too large to cache"), + C::AlreadyCached(_) => bail!("Stylus contract is already cached"), C::BidsArePaused(_) => { - bail!("bidding is currently paused for the Stylus cache manager") + bail!("Bidding is currently paused for the Stylus cache manager") } C::BidTooSmall(_) => { - bail!("bid amount {} (wei) too small", cfg.bid.unwrap_or_default()) + bail!("Bid amount {} (wei) too small", cfg.bid.unwrap_or_default()) + } + C::ProgramNotActivated(_) => { + bail!("Your Stylus contract {} is not yet activated. To activate it, use the `cargo stylus activate` subcommand", hex::encode(contract)) } } } @@ -100,16 +105,16 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { ) .await?; - let address = cfg.program_address.debug_lavender(); + let address = cfg.address.debug_lavender(); if verbose { let gas = format_gas(receipt.gas_used.unwrap_or_default()); greyln!( - "Successfully cached program at address: {address} {} {gas}", + "Successfully cached contract at address: {address} {} {gas}", "with".grey() ); } else { - greyln!("Successfully cached program at address: {address}"); + greyln!("Successfully cached contract at address: {address}"); } let tx_hash = receipt.transaction_hash.debug_lavender(); greyln!("Sent Stylus cache tx with hash: {tx_hash}"); diff --git a/check/src/check.rs b/check/src/check.rs index fbde025..f755c1f 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -1,12 +1,12 @@ // Copyright 2023-2024, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md +// 라이선스 정보는 https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md에서 확인할 수 있습니다. use crate::deploy::TxKind; use crate::{ check::ArbWasm::ArbWasmErrors, - constants::{ARB_WASM_H160, ONE_ETH}, + constants::{ARB_WASM_H160, ONE_ETH, TOOLCHAIN_FILE_NAME}, macros::*, - project::{self, BuildConfig}, + project::{self, extract_toolchain_channel, BuildConfig}, CheckConfig, }; use alloy_primitives::{Address, B256, U256}; @@ -22,12 +22,13 @@ use ethers::{ }; use eyre::{bail, eyre, ErrReport, Result, WrapErr}; use serde_json::Value; +use std::fs::{self, File}; use std::io::Write; use std::path::PathBuf; -use std::fs::{self, File}; sol! { interface ArbWasm { + // ArbWasm 인터페이스 정의: 프로그램 활성화, Stylus 버전 확인, 코드 해시 버전 확인 및 오류 처리 함수들. function activateProgram(address program) external payable @@ -47,25 +48,29 @@ sol! { } } -/// Checks that a program is valid and can be deployed onchain. -/// Returns whether the WASM is already up-to-date and activated onchain, and the data fee. -pub async fn check(cfg: &CheckConfig) -> Result { +/// 계약이 유효하며 체인에 배포될 수 있는지 확인합니다. +/// 이더리움 WASM이 최신 상태로 이미 체인에서 활성화되었는지 여부와 데이터 수수료를 반환합니다. +pub async fn check(cfg: &CheckConfig) -> Result { if cfg.common_cfg.endpoint == "https://stylus-testnet.arbitrum.io/rpc" { let version = "cargo stylus version 0.2.1".to_string().red(); bail!("The old Stylus testnet is no longer supported.\nPlease downgrade to {version}",); } let verbose = cfg.common_cfg.verbose; - let (wasm, project_hash) = cfg.build_wasm().wrap_err("failed to build wasm")?; + let (wasm, project_hash) = cfg.build_wasm().wrap_err("failed to build wasm")?; // WASM 파일을 빌드합니다. if verbose { greyln!("reading wasm file at {}", wasm.to_string_lossy().lavender()); } - let (wasm, code) = project::compress_wasm(&wasm).wrap_err("failed to compress WASM")?; - + + // 다음으로, 사용자의 WASM(웹어셈블리) 파일에 프로젝트의 해시를 커스텀 섹션으로 포함시킵니다. + // 이 해시는 Cargo stylus의 재현 가능한 검증(reproducible verification)에 의해 검증될 수 있도록 추가됩니다. + // 이 해시는 WASM 런타임에서 무시되는 섹션으로 추가되기 때문에, 파일에는 메타데이터 용도로만 존재하게 됩니다. + let (wasm_file_bytes, code) = + project::compress_wasm(&wasm, project_hash).wrap_err("failed to compress WASM")?; // WASM 파일을 압축합니다. + let code_copied = code.clone(); - let mut code_len = [0u8; 32]; ethers::prelude::U256::from(code_copied.len()).to_big_endian(&mut code_len); let mut tx_code: Vec = vec![]; @@ -83,69 +88,53 @@ pub async fn check(cfg: &CheckConfig) -> Result { tx_code.push(0x00); // version tx_code.extend(project_hash); tx_code.extend(code_copied); - write_tx_data(TxKind::Deployment, &tx_code)?; + write_tx_data(TxKind::Deployment, &tx_code)?; // 트랜잭션 데이터를 작성하여 파일로 저장합니다. - greyln!("contract size: {}", format_file_size(code.len(), 16, 24)); + greyln!("contract size: {}", format_file_size(code.len(), 16, 24)); // 계약 크기를 출력합니다. if verbose { - greyln!("wasm size: {}", format_file_size(wasm.len(), 96, 128)); + greyln!( + "wasm size: {}", + format_file_size(wasm_file_bytes.len(), 96, 128) + ); greyln!("connecting to RPC: {}", &cfg.common_cfg.endpoint.lavender()); } - // check if the program already exists + // 계약이 이미 존재하는지 확인합니다. let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; let codehash = alloy_primitives::keccak256(&code); - if program_exists(codehash, &provider).await? { - return Ok(ProgramCheck::Active { code, project_hash }); + if contract_exists(codehash, &provider).await? { + return Ok(ContractCheck::Active { code }); // 계약이 이미 활성화된 경우. } - let address = cfg.program_address.unwrap_or(H160::random()); - let fee = check_activate(code.clone().into(), address, &provider).await?; + let address = cfg.contract_address.unwrap_or(H160::random()); // 계약 주소를 설정하거나 새로 생성합니다. + let fee = check_activate(code.clone().into(), address, &provider).await?; // 계약 활성화를 위한 데이터 수수료를 계산합니다. let visual_fee = format_data_fee(fee).unwrap_or("???".red()); - greyln!("wasm data fee: {visual_fee}"); - Ok(ProgramCheck::Ready { - code, - fee, - project_hash, - }) + greyln!("wasm data fee: {visual_fee}"); // 데이터 수수료를 출력합니다. + Ok(ContractCheck::Ready { code, fee }) // 계약이 활성화 준비가 된 경우. } -/// Whether a program is active, or needs activation. +/// 계약이 활성화되었는지, 아니면 활성화가 필요한지 확인하는 열거형. #[derive(PartialEq)] -pub enum ProgramCheck { - /// Program already exists onchain. - Active { - code: Vec, - project_hash: [u8; 32], - }, - /// Program can be activated with the given data fee. - Ready { - code: Vec, - fee: U256, - project_hash: [u8; 32], - }, +pub enum ContractCheck { + /// 계약이 이미 체인에 존재합니다. + Active { code: Vec }, + /// 계약을 데이터 수수료와 함께 활성화할 수 있습니다. + Ready { code: Vec, fee: U256 }, } -impl ProgramCheck { +impl ContractCheck { pub fn code(&self) -> &[u8] { match self { - Self::Active { code, .. } => code, - Self::Ready { code, .. } => code, - } - } - - pub fn project_hash(&self) -> &[u8; 32] { - match self { - Self::Active { project_hash, .. } => project_hash, - Self::Ready { project_hash, .. } => project_hash, + Self::Active { code, .. } => code, // 활성화된 경우 코드 반환 + Self::Ready { code, .. } => code, // 준비된 경우 코드 반환 } } - pub fn suggest_fee(&self) -> U256 { match self { - Self::Active { .. } => U256::default(), - Self::Ready { fee, .. } => fee * U256::from(120) / U256::from(100), + Self::Active { .. } => U256::default(), // 활성화된 경우 기본 수수료 반환 + Self::Ready { fee, .. } => fee * U256::from(120) / U256::from(100), // 준비된 경우 수수료를 조정하여 반환 } } } @@ -153,19 +142,20 @@ impl ProgramCheck { impl CheckConfig { fn build_wasm(&self) -> Result<(PathBuf, [u8; 32])> { if let Some(wasm) = self.wasm_file.clone() { - return Ok((wasm, [0u8; 32])); + return Ok((wasm, [0u8; 32])); // 기존 WASM 파일이 있으면 사용 } - let cfg = BuildConfig::new(self.common_cfg.rust_stable); - let project_hash = project::hash_files( - self.common_cfg.source_files_for_project_hash.clone(), - cfg.clone(), - )?; - let wasm = project::build_dylib(cfg)?; + let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); + let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; // 도구 체인 채널을 추출합니다. + let rust_stable = !toolchain_channel.contains("nightly"); + let cfg = BuildConfig::new(rust_stable); + let wasm = project::build_dylib(cfg.clone())?; // 동적 라이브러리(Dylib)를 빌드합니다. + let project_hash = + project::hash_files(self.common_cfg.source_files_for_project_hash.clone(), cfg)?; // 프로젝트 파일 해시를 계산합니다. Ok((wasm, project_hash)) } } -/// Pretty-prints a file size based on its limits. +/// 파일 크기를 포맷하여 예쁘게 출력합니다. pub fn format_file_size(len: usize, mid: u64, max: u64) -> String { let len = ByteSize::b(len as u64); let mid = ByteSize::kib(mid); @@ -179,7 +169,7 @@ pub fn format_file_size(len: usize, mid: u64, max: u64) -> String { } } -/// Pretty-prints a data fee. +/// 데이터 수수료를 포맷하여 출력합니다. fn format_data_fee(fee: U256) -> Result { let fee: u64 = (fee / U256::from(1e9)).try_into()?; let fee: f64 = fee as f64 / 1e9; @@ -200,41 +190,41 @@ pub struct EthCallError { impl From for ErrReport { fn from(value: EthCallError) -> Self { - eyre!(value.msg) + eyre!(value.msg) // EthCallError를 ErrReport로 변환 } } -/// A funded eth_call. +/// 자금이 충당된 eth_call을 실행합니다. pub async fn eth_call( tx: Eip1559TransactionRequest, mut state: State, provider: &Provider, ) -> Result, EthCallError>> { let tx = TypedTransaction::Eip1559(tx); - state.account(Default::default()).balance = Some(ethers::types::U256::MAX); // infinite balance + state.account(Default::default()).balance = Some(ethers::types::U256::MAX); // 무한한 잔고를 설정하여 가스 제한을 회피합니다. match provider.call_raw(&tx).state(&state).await { - Ok(bytes) => Ok(Ok(bytes.to_vec())), + Ok(bytes) => Ok(Ok(bytes.to_vec())), // 호출이 성공하면 결과를 바이트 배열로 반환 Err(ProviderError::JsonRpcClientError(error)) => { let error = error .as_error_response() - .ok_or_else(|| eyre!("json RPC failure: {error}"))?; + .ok_or_else(|| eyre!("json RPC failure: {error}"))?; // JSON RPC 실패 시 처리 let msg = error.message.clone(); let data = match &error.data { - Some(Value::String(data)) => text::decode0x(data)?.to_vec(), + Some(Value::String(data)) => text::decode0x(data)?.to_vec(), // 에러 데이터를 디코딩 Some(value) => bail!("failed to decode RPC failure: {value}"), - None => vec![], + None => vec![], // 데이터가 없는 경우 빈 벡터 반환 }; - Ok(Err(EthCallError { data, msg })) + Ok(Err(EthCallError { data, msg })) // EthCallError로 반환 } - Err(error) => Err(error.into()), + Err(error) => Err(error.into()), // 기타 에러 처리 } } -/// Checks whether a program has already been activated with the most recent version of Stylus. -async fn program_exists(codehash: B256, provider: &Provider) -> Result { - let data = ArbWasm::codehashVersionCall { codehash }.abi_encode(); +/// 계약이 최신 Stylus 버전으로 이미 활성화되어 있는지 확인합니다. +async fn contract_exists(codehash: B256, provider: &Provider) -> Result { + let data = ArbWasm::codehashVersionCall { codehash }.abi_encode(); // 코드 해시 버전을 확인하는 호출 데이터 생성 let tx = Eip1559TransactionRequest::new() .to(*ARB_WASM_H160) .data(data); @@ -242,6 +232,12 @@ async fn program_exists(codehash: B256, provider: &Provider) -> Result { + if outs.is_empty() { + bail!( + r#"No data returned from the ArbWasm precompile when checking if your Stylus contract exists. +Perhaps the Arbitrum node for the endpoint you are connecting to has not yet upgraded to Stylus"# + ); + } let ArbWasm::codehashVersionReturn { version } = ArbWasm::codehashVersionCall::abi_decode_returns(&outs, true)?; version @@ -252,16 +248,16 @@ async fn program_exists(codehash: B256, provider: &Provider) -> Result bail!("not a Stylus program"), + A::ProgramNotWasm(_) => bail!("not a Stylus contract"), // Stylus 계약이 아닌 경우 A::ProgramNotActivated(_) | A::ProgramNeedsUpgrade(_) | A::ProgramExpired(_) => { - return Ok(false); + return Ok(false); // 프로그램이 활성화되지 않았거나 업그레이드가 필요한 경우 } - _ => bail!("unexpected ArbWasm error: {msg}"), + _ => bail!("unexpected ArbWasm error: {msg}"), // 예기치 않은 오류 처리 } } }; - let data = ArbWasm::stylusVersionCall {}.abi_encode(); + let data = ArbWasm::stylusVersionCall {}.abi_encode(); // Stylus 버전을 확인하는 호출 데이터 생성 let tx = Eip1559TransactionRequest::new() .to(*ARB_WASM_H160) .data(data); @@ -269,33 +265,33 @@ async fn program_exists(codehash: B256, provider: &Provider) -> Result) -> Result { - let program = Address::from(address.to_fixed_bytes()); - let data = ArbWasm::activateProgramCall { program }.abi_encode(); +/// 계약 활성화를 확인하고, 데이터 수수료를 반환합니다. +pub async fn check_activate(code: Bytes, address: H160, provider: &Provider) -> Result { + let contract = Address::from(address.to_fixed_bytes()); + let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); // 프로그램 활성화 호출 데이터 생성 let tx = Eip1559TransactionRequest::new() .to(*ARB_WASM_H160) .data(data) - .value(ONE_ETH); - let state = spoof::code(address, code); + .value(ONE_ETH); // 활성화 트랜잭션을 위해 1 ETH를 설정 + let state = spoof::code(address, code); // 계약 코드와 주소를 기반으로 상태를 스푸핑(spoofing) let outs = eth_call(tx, state, provider).await??; let ArbWasm::activateProgramReturn { dataFee, .. } = ArbWasm::activateProgramCall::abi_decode_returns(&outs, true)?; - Ok(dataFee) + Ok(dataFee) // 활성화에 필요한 데이터 수수료 반환 } fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { - let file_name = format!("{tx_kind}_tx_data"); + let file_name = format!("{tx_kind}_tx_data"); // 트랜잭션 종류에 따라 파일 이름 설정 let mut path = PathBuf::new(); path.push("./output"); if !path.exists() { - fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; + fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; // 출력 디렉토리 생성 } - + path = path.join(file_name); let path_str = path.as_os_str().to_string_lossy(); println!( @@ -304,7 +300,7 @@ fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { path_str.grey(), ); let mut f = std::fs::File::create(&path) - .map_err(|e| eyre!("could not create file to write tx data to path {path_str}: {e}",))?; + .map_err(|e| eyre!("could not create file to write tx data to path {path_str}: {e}",))?; // 파일 생성 f.write_all(data) - .map_err(|e| eyre!("could not write tx data as bytes to file to path {path_str}: {e}")) + .map_err(|e| eyre!("could not write tx data as bytes to file to path {path_str}: {e}")) // 데이터를 파일에 씁니다. } diff --git a/check/src/constants.rs b/check/src/constants.rs index 25aa4c1..935d9b9 100644 --- a/check/src/constants.rs +++ b/check/src/constants.rs @@ -8,21 +8,21 @@ use lazy_static::lazy_static; /// EOF prefix used in Stylus compressed WASMs on-chain pub const EOF_PREFIX_NO_DICT: &str = "EFF00000"; -/// Maximum brotli compression level used for Stylus programs. +/// Maximum brotli compression level used for Stylus contracts. pub const BROTLI_COMPRESSION_LEVEL: u32 = 11; lazy_static! { /// Address of the ArbWasm precompile. pub static ref ARB_WASM_H160: H160 = H160(*ARB_WASM_ADDRESS.0); - /// Address of the Stylus program cache manager. - pub static ref CACHE_MANAGER_H160: H160 = H160(*CACHE_MANAGER_ADDRESS.0); + /// Address of the ArbWasmCache precompile. + pub static ref ARB_WASM_CACHE_H160: H160 = H160(*ARB_WASM_CACHE_ADDRESS.0); } /// Address of the ArbWasm precompile. pub const ARB_WASM_ADDRESS: Address = address!("0000000000000000000000000000000000000071"); -/// Address of the Stylus program cache manager for Arbitrum chains. -pub const CACHE_MANAGER_ADDRESS: Address = address!("d1bbd579988f394a26d6ec16e77b3fa8a5e8fcee"); +/// Address of the ArbWasmCache precompile. +pub const ARB_WASM_CACHE_ADDRESS: Address = address!("0000000000000000000000000000000000000072"); /// Target for compiled WASM folder in a Rust project pub const RUST_TARGET: &str = "wasm32-unknown-unknown"; @@ -36,3 +36,10 @@ pub const GITHUB_TEMPLATE_REPO_MINIMAL: &str = /// One ether in wei. pub const ONE_ETH: U256 = U256([1000000000000000000, 0, 0, 0]); + +/// Name of the custom wasm section that is added to contracts deployed with cargo stylus +/// to include a hash of the Rust project's source files for reproducible verification of builds. +pub const PROJECT_HASH_SECTION_NAME: &str = "project_hash"; + +/// Name of the toolchain file used to specify the Rust toolchain version for a project. +pub const TOOLCHAIN_FILE_NAME: &str = "rust-toolchain.toml"; diff --git a/check/src/deploy.rs b/check/src/deploy.rs index 8825466..7741062 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -3,9 +3,8 @@ #![allow(clippy::println_empty_string)] -use std::fs; use crate::{ - check::{self, ProgramCheck}, + check::{self, ContractCheck}, constants::ARB_WASM_H160, macros::*, DeployConfig, @@ -26,6 +25,7 @@ use ethers::{ types::{transaction::eip2718::TypedTransaction, Eip1559TransactionRequest, H160, U256, U64}, }; use eyre::{bail, eyre, Result, WrapErr}; +use std::fs; use std::io::Write; use std::path::PathBuf; @@ -54,7 +54,7 @@ sol! { pub type SignerClient = SignerMiddleware, Wallet>; -/// Deploys a stylus program, activating if needed. +/// Deploys a stylus contract, activating if needed. pub async fn deploy(cfg: DeployConfig) -> Result<()> { macro_rules! run { ($expr:expr) => { @@ -65,7 +65,7 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { }; } - let program = run!(check::check(&cfg.check_config), "cargo stylus check failed"); + let contract = run!(check::check(&cfg.check_config), "cargo stylus check failed"); let verbose = cfg.check_config.common_cfg.verbose; let client = sys::new_provider(&cfg.check_config.common_cfg.endpoint)?; @@ -80,9 +80,9 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { greyln!("sender address: {}", sender.debug_lavender()); } - let data_fee = program.suggest_fee(); + let data_fee = contract.suggest_fee(); - if let ProgramCheck::Ready { .. } = &program { + if let ContractCheck::Ready { .. } = &contract { // check balance early let balance = run!(client.get_balance(sender, None), "failed to get balance"); let balance = alloy_ethers_typecast::ethers_u256_to_alloy(balance); @@ -100,13 +100,16 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { } } - let contract = cfg - .deploy_contract(program.code(), program.project_hash(), sender, &client) + let contract_addr = cfg + .deploy_contract(contract.code(), sender, &client) .await?; - match program { - ProgramCheck::Ready { .. } => cfg.activate(sender, contract, data_fee, &client).await?, - ProgramCheck::Active { .. } => greyln!("wasm already activated!"), + match contract { + ContractCheck::Ready { .. } => { + cfg.activate(sender, contract_addr, data_fee, &client) + .await? + } + ContractCheck::Active { .. } => greyln!("wasm already activated!"), } Ok(()) } @@ -115,11 +118,10 @@ impl DeployConfig { async fn deploy_contract( &self, code: &[u8], - project_hash: &[u8; 32], sender: H160, client: &SignerClient, ) -> Result { - let init_code = program_deployment_calldata(code, project_hash); + let init_code = contract_deployment_calldata(code); write_tx_data(TxKind::Deployment, &init_code)?; let tx = Eip1559TransactionRequest::new() @@ -161,7 +163,13 @@ impl DeployConfig { greyln!("deployed code at address: {address}"); } let tx_hash = receipt.transaction_hash.debug_lavender(); - greyln!("Deployment tx hash: {tx_hash}"); + greyln!("deployment tx hash: {tx_hash}"); + println!( + r#"INFO: Your program is not yet part of the Stylus contract cache. We recommend running `cargo stylus cache --address={}` to cache your activated contract in ArbOS. +Cached contracts benefit from cheaper calls. To read more about the Stylus contract cache, see +https://docs.arbitrum.io/stylus/concepts/stylus-cache-manager"#, + hex::encode(contract) + ); Ok(contract) } @@ -174,9 +182,8 @@ impl DeployConfig { ) -> Result<()> { let verbose = self.check_config.common_cfg.verbose; let data_fee = alloy_ethers_typecast::alloy_u256_to_ethers(data_fee); - let program: Address = contract.to_fixed_bytes().into(); - - let data = ArbWasm::activateProgramCall { program }.abi_encode(); + let contract_addr: Address = contract.to_fixed_bytes().into(); + let data = ArbWasm::activateProgramCall {program: contract_addr}.abi_encode(); write_tx_data(TxKind::Activation, &data)?; let tx = Eip1559TransactionRequest::new() @@ -212,7 +219,7 @@ impl DeployConfig { greyln!("activated with {gas}"); } greyln!( - "program activated and ready onchain with tx hash: {}", + "contract activated and ready onchain with tx hash: {}", receipt.transaction_hash.debug_lavender() ); Ok(()) @@ -250,7 +257,7 @@ pub async fn run_tx( } /// Prepares an EVM bytecode prelude for contract creation. -pub fn program_deployment_calldata(code: &[u8], hash: &[u8; 32]) -> Vec { +pub fn contract_deployment_calldata(code: &[u8]) -> Vec { let mut code_len = [0u8; 32]; U256::from(code.len()).to_big_endian(&mut code_len); let mut deploy: Vec = vec![]; @@ -258,7 +265,7 @@ pub fn program_deployment_calldata(code: &[u8], hash: &[u8; 32]) -> Vec { deploy.extend(code_len); deploy.push(0x80); // DUP1 deploy.push(0x60); // PUSH1 - deploy.push(42 + 1 + 32); // prelude + version + hash + deploy.push(42 + 1); // prelude + version deploy.push(0x60); // PUSH1 deploy.push(0x00); deploy.push(0x39); // CODECOPY @@ -266,11 +273,24 @@ pub fn program_deployment_calldata(code: &[u8], hash: &[u8; 32]) -> Vec { deploy.push(0x00); deploy.push(0xf3); // RETURN deploy.push(0x00); // version - deploy.extend(hash); deploy.extend(code); deploy } +pub fn extract_contract_evm_deployment_prelude(calldata: &[u8]) -> Vec { + // The length of the prelude, version part is 42 + 1 as per the code + let metadata_length = 42 + 1; + // Extract and return the metadata part + calldata[0..metadata_length].to_vec() +} + +pub fn extract_compressed_wasm(calldata: &[u8]) -> Vec { + // The length of the prelude, version part is 42 + 1 as per the code + let metadata_length = 42 + 1; + // Extract and return the metadata part + calldata[metadata_length..].to_vec() +} + pub fn format_gas(gas: U256) -> String { let gas: u64 = gas.try_into().unwrap_or(u64::MAX); let text = format!("{gas} gas"); @@ -298,7 +318,7 @@ fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { if !path.exists() { fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; } - + path = path.join(file_name); let path_str = path.as_os_str().to_string_lossy(); println!( diff --git a/check/src/docker.rs b/check/src/docker.rs index 1b17e90..fa96700 100644 --- a/check/src/docker.rs +++ b/check/src/docker.rs @@ -2,10 +2,16 @@ // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md use std::io::Write; +use std::path::PathBuf; use std::process::{Command, Stdio}; +use cargo_stylus_util::color::Color; use eyre::{bail, eyre, Result}; +use crate::constants::TOOLCHAIN_FILE_NAME; +use crate::macros::greyln; +use crate::project::extract_toolchain_channel; + fn version_to_image_name(version: &str) -> String { format!("cargo-stylus-{}", version) } @@ -16,6 +22,21 @@ fn image_exists(name: &str) -> Result { .arg(name) .output() .map_err(|e| eyre!("failed to execute Docker command: {e}"))?; + + if !output.status.success() { + let stderr = std::str::from_utf8(&output.stderr) + .map_err(|e| eyre!("failed to read Docker command stderr: {e}"))?; + if stderr.contains("Cannot connect to the Docker daemon") { + println!( + r#"Cargo stylus deploy|check|verify run in a Docker container by default to ensure deployments +are reproducible, but Docker is not found in your system. Please install Docker if you wish to create +a reproducible deployment, or opt out by using the --no-verify flag for local builds"# + ); + bail!("Docker not running"); + } + bail!(stderr.to_string()) + } + Ok(output.stdout.iter().filter(|c| **c == b'\n').count() > 1) } @@ -24,6 +45,7 @@ fn create_image(version: &str) -> Result<()> { if image_exists(&name)? { return Ok(()); } + println!("Building Docker image for Rust toolchain {}", version,); let mut child = Command::new("docker") .arg("build") .arg("-t") @@ -32,20 +54,19 @@ fn create_image(version: &str) -> Result<()> { .arg("-f-") .stdin(Stdio::piped()) .spawn() - .map_err(|e| eyre!("failed to execure Docker command: {e}"))?; + .map_err(|e| eyre!("failed to execute Docker command: {e}"))?; write!( child.stdin.as_mut().unwrap(), "\ - FROM rust:{} as builder\n\ + FROM --platform=linux/amd64 offchainlabs/cargo-stylus-base as base + RUN rustup toolchain install {}-x86_64-unknown-linux-gnu + RUN rustup default {}-x86_64-unknown-linux-gnu RUN rustup target add wasm32-unknown-unknown - RUN rustup target add wasm32-wasi - RUN rustup target add aarch64-unknown-linux-gnu - RUN cargo install cargo-stylus - RUN cargo install --force cargo-stylus-check - RUN cargo install --force cargo-stylus-replay - RUN cargo install --force cargo-stylus-cgen + RUN rustup component add rust-src --toolchain {}-x86_64-unknown-linux-gnu ", - version + version, + version, + version, )?; child.wait().map_err(|e| eyre!("wait failed: {e}"))?; Ok(()) @@ -69,17 +90,47 @@ fn run_in_docker_container(version: &str, command_line: &[&str]) -> Result<()> { .arg(name) .args(command_line) .spawn() - .map_err(|e| eyre!("failed to execure Docker command: {e}"))? + .map_err(|e| eyre!("failed to execute Docker command: {e}"))? .wait() .map_err(|e| eyre!("wait failed: {e}"))?; Ok(()) } -pub fn run_reproducible(version: &str, command_line: &[String]) -> Result<()> { +pub fn run_reproducible(command_line: &[String]) -> Result<()> { + verify_valid_host()?; + let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); + let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; + greyln!( + "Running reproducible Stylus command with toolchain {}", + toolchain_channel.mint() + ); let mut command = vec!["cargo", "stylus"]; for s in command_line.iter() { command.push(s); } - create_image(version)?; - run_in_docker_container(version, &command) + create_image(&toolchain_channel)?; + run_in_docker_container(&toolchain_channel, &command) +} + +fn verify_valid_host() -> Result<()> { + let Ok(os_type) = sys_info::os_type() else { + bail!("unable to determine host OS type"); + }; + if os_type == "Windows" { + // Check for WSL environment + let Ok(kernel_version) = sys_info::os_release() else { + bail!("unable to determine kernel version"); + }; + if kernel_version.contains("microsoft") || kernel_version.contains("WSL") { + greyln!("Detected Windows Linux Subsystem host"); + } else { + bail!( + "Reproducible cargo stylus commands on Windows are only supported \ + in Windows Linux Subsystem (WSL). Please install within WSL. \ + To instead opt out of reproducible builds, add the --no-verify \ + flag to your commands." + ); + } + } + Ok(()) } diff --git a/check/src/export_abi.rs b/check/src/export_abi.rs index d508395..2eb0eda 100644 --- a/check/src/export_abi.rs +++ b/check/src/export_abi.rs @@ -10,7 +10,7 @@ use std::{ process::{self, Command, Stdio}, }; -/// Exports Solidity ABIs by running the program natively. +/// Exports Solidity ABIs by running the contract natively. pub fn export_abi(file: Option, json: bool) -> Result<()> { if json && !sys::command_exists("solc") { let link = "https://docs.soliditylang.org/en/latest/installing-solidity.html".red(); @@ -30,7 +30,7 @@ pub fn export_abi(file: Option, json: bool) -> Result<()> { let out = (out != "") .then_some(format!(": {out}")) .unwrap_or_default(); - egreyln!("failed to run program{out}"); + egreyln!("failed to run contract {out}"); process::exit(1); } diff --git a/check/src/main.rs b/check/src/main.rs index 3e23e68..1b2e686 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -4,6 +4,7 @@ use clap::{ArgGroup, Args, Parser}; use ethers::types::{H160, U256}; use eyre::{eyre, Context, Result}; +use std::fmt; use std::path::PathBuf; use tokio::runtime::Builder; @@ -17,8 +18,8 @@ mod export_abi; mod macros; mod new; mod project; -mod verify; mod tx; +mod verify; mod wallet; #[derive(Parser, Debug)] @@ -34,11 +35,17 @@ struct Opts { #[derive(Parser, Debug, Clone)] enum Apis { - /// Create a new Rust project. + /// Create a new Stylus project. New { /// Project name. name: PathBuf, - /// Create a minimal program. + /// Create a minimal contract. + #[arg(long)] + minimal: bool, + }, + /// Initializes a Stylus project in the current directory. + Init { + /// Create a minimal contract. #[arg(long)] minimal: bool, }, @@ -51,6 +58,9 @@ enum Apis { #[arg(long)] json: bool, }, + /// Activate an already deployed contract. + #[command(alias = "a")] + Activate(ActivateWithoutPrivateKeyConfig), /// Cache a contract using the Stylus CacheManager for Arbitrum chains. Cache(CacheConfig), /// Check a contract. @@ -59,9 +69,6 @@ enum Apis { /// Deploy a contract. #[command(alias = "d")] Deploy(DeployConfig), - /// Deploy a contract. - #[command(alias = "a")] - Activate(ActivateConfig), /// Build in a Docker container to ensure reproducibility. /// /// Specify the Rust version to use, followed by the cargo stylus subcommand. @@ -85,9 +92,6 @@ struct CommonConfig { /// Arbitrum RPC endpoint. #[arg(short, long, default_value = "https://sepolia-rollup.arbitrum.io/rpc")] endpoint: String, - /// Whether to use stable Rust. - #[arg(long)] - rust_stable: bool, /// Whether to print debug info. #[arg(long)] verbose: bool, @@ -110,28 +114,44 @@ pub struct CacheConfig { /// Wallet source to use. #[command(flatten)] auth: AuthOpts, - /// Deployed and activated program address to cache. + /// Deployed and activated contract address to cache. #[arg(long)] - program_address: H160, - /// Bid, in wei, to place on the desired program to cache + address: H160, + /// Bid, in wei, to place on the desired contract to cache #[arg(short, long, hide(true))] bid: Option, } #[derive(Args, Clone, Debug)] -pub struct CheckConfig { +pub struct ActivateConfig { #[command(flatten)] common_cfg: CommonConfig, - /// The WASM to check (defaults to any found in the current directory). + /// Wallet source to use. + #[command(flatten)] + auth: AuthOpts, + /// Deployed Stylus contract address to activate. #[arg(long)] - wasm_file: Option, - /// Where to deploy and activate the program (defaults to a random address). + address: H160, + /// Percent to bump the estimated activation data fee by. Default of 20% + #[arg(long, default_value = "20")] + data_fee_bump_percent: u64, +} + +#[derive(Args, Clone, Debug)] +pub struct ActivateWithoutPrivateKeyConfig { + /// Deployed Stylus contract address to activate. #[arg(long)] - program_address: Option, + address: H160, } #[derive(Args, Clone, Debug)] -struct ActivateConfig { +pub struct CheckConfig { + #[command(flatten)] + common_cfg: CommonConfig, + /// The WASM to check (defaults to any found in the current directory). + #[arg(long)] + wasm_file: Option, + /// Where to deploy and activate the contract (defaults to a random address). #[arg(long)] contract_address: Option, } @@ -148,16 +168,23 @@ struct DeployConfig { estimate_gas: bool, #[command(flatten)] tx_sending_opts: TxSendingOpts, + /// If specified, will not run the command in a reproducible docker container. Useful for local + /// builds, but at the risk of not having a reproducible contract for verification purposes. + #[arg(long)] + no_verify: bool, } #[derive(Args, Clone, Debug)] pub struct VerifyConfig { #[command(flatten)] common_cfg: CommonConfig, - /// Hash of the deployment transaction. #[arg(long)] deployment_tx: String, + #[arg(long)] + /// If specified, will not run the command in a reproducible docker container. Useful for local + /// builds, but at the risk of not having a reproducible contract for verification purposes. + no_verify: bool, } #[derive(Clone, Debug, Args)] @@ -191,6 +218,110 @@ pub struct TxSendingOpts { output_tx_data_to_dir: Option, } +impl fmt::Display for CommonConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Convert the vector of source files to a comma-separated string + let mut source_files: String = "".to_string(); + if !self.source_files_for_project_hash.is_empty() { + source_files = format!( + "--source-files-for-project-hash={}", + self.source_files_for_project_hash.join(", ") + ); + } + write!( + f, + "--endpoint={} {} {} {}", + self.endpoint, + match self.verbose { + true => "--verbose", + false => "", + }, + source_files, + match &self.max_fee_per_gas_gwei { + Some(fee) => format!("--max-fee-per-gas-gwei {}", fee), + None => "".to_string(), + } + ) + } +} + +impl fmt::Display for CheckConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{} {} {}", + self.common_cfg, + match &self.wasm_file { + Some(path) => format!("--wasm-file={}", path.display()), + None => "".to_string(), + }, + match &self.contract_address { + Some(addr) => format!("--contract-address={:?}", addr), + None => "".to_string(), + }, + ) + } +} + +impl fmt::Display for DeployConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{} {} {} {}", + self.check_config, + self.auth, + match self.estimate_gas { + true => "--estimate-gas".to_string(), + false => "".to_string(), + }, + match self.no_verify { + true => "--no-verify".to_string(), + false => "".to_string(), + }, + ) + } +} + +impl fmt::Display for AuthOpts { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{} {} {} {}", + match &self.private_key_path { + Some(path) => format!("--private-key-path={}", path.display()), + None => "".to_string(), + }, + match &self.private_key { + Some(key) => format!("--private-key={}", key.clone()), + None => "".to_string(), + }, + match &self.keystore_path { + Some(path) => format!("--keystore-path={}", path.clone()), + None => "".to_string(), + }, + match &self.keystore_password_path { + Some(path) => format!("--keystore-password-path={}", path.display()), + None => "".to_string(), + } + ) + } +} + +impl fmt::Display for VerifyConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{} --deployment-tx={} {}", + self.common_cfg, + self.deployment_tx, + match self.no_verify { + true => "--no-verify".to_string(), + false => "".to_string(), + } + ) + } +} + fn main() -> Result<()> { let args = Opts::parse(); let runtime = Builder::new_multi_thread().enable_all().build()?; @@ -208,32 +339,76 @@ async fn main_impl(args: Opts) -> Result<()> { Apis::New { name, minimal } => { run!(new::new(&name, minimal), "failed to open new project"); } + Apis::Init { minimal } => { + run!(new::init(minimal), "failed to initialize project"); + } Apis::ExportAbi { json, output } => { run!(export_abi::export_abi(output, json), "failed to export abi"); } + Apis::Activate(config) => { + run!(activate::activate(&config).await, "stylus activate failed"); + } Apis::Cache(config) => { - run!(cache::cache_program(&config).await, "stylus cache failed"); + run!(cache::cache_contract(&config).await, "stylus cache failed"); } Apis::Check(config) => { run!(check::check(&config).await, "stylus checks failed"); } Apis::Deploy(config) => { - run!(deploy::deploy(config).await, "failed to deploy"); - } - Apis::Activate(config) => { - run!(activate::activate(config).await, "failed to activate"); + if config.no_verify { + run!(deploy::deploy(config).await, "stylus deploy failed"); + } else { + println!( + "Running in a Docker container for reproducibility, this may take a while", + ); + println!("NOTE: You can opt out by doing --no-verify"); + let mut commands: Vec = + vec![String::from("deploy"), String::from("--no-verify")]; + let config_args = config + .to_string() + .split(' ') + .map(|s| s.to_string()) + .filter(|s| !s.is_empty()) + .collect::>(); + commands.extend(config_args); + run!( + docker::run_reproducible(&commands), + "failed reproducible run" + ); + } } Apis::Reproducible { rust_version, stylus, } => { + let mut commands: Vec = vec![rust_version]; + commands.extend(stylus); run!( - docker::run_reproducible(&rust_version, &stylus), + docker::run_reproducible(&commands), "failed reproducible run" ); } Apis::Verify(config) => { - run!(verify::verify(config).await, "failed to verify"); + if config.no_verify { + run!(verify::verify(config).await, "failed to verify"); + } else { + println!( + "Running in a Docker container for reproducibility, this may take a while", + ); + let mut commands: Vec = + vec![String::from("verify"), String::from("--no-verify")]; + let config_args = config + .to_string() + .split(' ') + .map(|s| s.to_string()) + .filter(|s| !s.is_empty()) + .collect::>(); + commands.extend(config_args); + run!( + docker::run_reproducible(&commands), + "failed reproducible run" + ); + } } } Ok(()) diff --git a/check/src/new.rs b/check/src/new.rs index 668df01..7fe0e1c 100644 --- a/check/src/new.rs +++ b/check/src/new.rs @@ -29,3 +29,31 @@ pub fn new(name: &Path, minimal: bool) -> Result<()> { println!("{GREY}new project at: {}", path.to_string_lossy().mint()); Ok(()) } + +pub fn init(minimal: bool) -> Result<()> { + let current_dir = current_dir().wrap_err("no current dir")?; + let repo = if minimal { + GITHUB_TEMPLATE_REPO_MINIMAL + } else { + GITHUB_TEMPLATE_REPO + }; + + let output = sys::new_command("git") + .arg("clone") + .arg("--depth") + .arg("1") + .arg(repo) + .arg(".") + .output() + .wrap_err("git clone failed")?; + + if !output.status.success() { + bail!("git clone command failed"); + } + + println!( + "{GREY}initialized project in: {}", + current_dir.to_string_lossy().mint() + ); + Ok(()) +} diff --git a/check/src/project.rs b/check/src/project.rs index 774499a..8ea07ab 100644 --- a/check/src/project.rs +++ b/check/src/project.rs @@ -2,7 +2,10 @@ // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md use crate::{ - constants::{BROTLI_COMPRESSION_LEVEL, EOF_PREFIX_NO_DICT, RUST_TARGET}, + constants::{ + BROTLI_COMPRESSION_LEVEL, EOF_PREFIX_NO_DICT, PROJECT_HASH_SECTION_NAME, RUST_TARGET, + TOOLCHAIN_FILE_NAME, + }, macros::*, }; use brotli2::read::BrotliEncoder; @@ -18,6 +21,7 @@ use std::{ process, }; use tiny_keccak::{Hasher, Keccak}; +use toml::Value; #[derive(Default, Clone, PartialEq)] pub enum OptLevel { @@ -53,10 +57,6 @@ pub fn build_dylib(cfg: BuildConfig) -> Result { let mut cmd = sys::new_command("cargo"); - if !cfg.stable { - cmd.arg("+nightly"); - } - cmd.arg("build"); cmd.arg("--lib"); @@ -107,7 +107,8 @@ pub fn build_dylib(cfg: BuildConfig) -> Result { }) .ok_or(BuildError::NoWasmFound { path: release_path })?; - let (wasm, code) = compress_wasm(&wasm_file_path).wrap_err("failed to compress WASM")?; + let (wasm, code) = + compress_wasm(&wasm_file_path, [0u8; 32]).wrap_err("failed to compress WASM")?; greyln!( "contract size: {}", @@ -161,12 +162,48 @@ fn all_paths(root_dir: &Path, source_file_patterns: Vec) -> Result Result { + let toolchain_file_contents = fs::read_to_string(toolchain_file_path).context( + "expected to find a rust-toolchain.toml file in project directory \ + to specify your Rust toolchain for reproducible verification. The channel in your project's rust-toolchain.toml's \ + toolchain section must be a specific version e.g., '1.80.0' or 'nightly-YYYY-MM-DD'. \ + To ensure reproducibility, it cannot be a generic channel like 'stable', 'nightly', or 'beta'. Read more about \ + the toolchain file in https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file or see \ + the file in https://github.com/OffchainLabs/stylus-hello-world for an example", + )?; + + let toolchain_toml: Value = + toml::from_str(&toolchain_file_contents).context("failed to parse rust-toolchain.toml")?; + + // Extract the channel from the toolchain section + let Some(toolchain) = toolchain_toml.get("toolchain") else { + bail!("toolchain section not found in rust-toolchain.toml"); + }; + let Some(channel) = toolchain.get("channel") else { + bail!("could not find channel in rust-toolchain.toml's toolchain section"); + }; + let Some(channel) = channel.as_str() else { + bail!("channel in rust-toolchain.toml's toolchain section is not a string"); + }; + + // Reject "stable" and "nightly" channels specified alone + if channel == "stable" || channel == "nightly" || channel == "beta" { + bail!("the channel in your project's rust-toolchain.toml's toolchain section must be a specific version e.g., '1.80.0' or 'nightly-YYYY-MM-DD'. \ + To ensure reproducibility, it cannot be a generic channel like 'stable', 'nightly', or 'beta'"); + } + + // Parse the Rust version from the toolchain project, only allowing alphanumeric chars and dashes. + let channel = channel + .chars() + .filter(|c| c.is_alphanumeric() || *c == '-' || *c == '.') + .collect(); + + Ok(channel) +} + pub fn hash_files(source_file_patterns: Vec, cfg: BuildConfig) -> Result<[u8; 32]> { let mut keccak = Keccak::v256(); let mut cmd = Command::new("cargo"); - if !cfg.stable { - cmd.arg("+nightly"); - } cmd.arg("--version"); let output = cmd .output() @@ -201,11 +238,20 @@ pub fn hash_files(source_file_patterns: Vec, cfg: BuildConfig) -> Result Ok(()) }; + // Fetch the Rust toolchain toml file from the project root. Assert that it exists and add it to the + // files in the directory to hash. + let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); + let _ = std::fs::metadata(&toolchain_file_path).wrap_err( + "expected to find a rust-toolchain.toml file in project directory \ + to specify your Rust toolchain for reproducible verification", + )?; + let mut paths = all_paths(PathBuf::from(".").as_path(), source_file_patterns)?; + paths.push(toolchain_file_path); paths.sort(); for filename in paths.iter() { - println!( + greyln!( "File used for deployment hash: {}", filename.as_os_str().to_string_lossy() ); @@ -214,8 +260,8 @@ pub fn hash_files(source_file_patterns: Vec, cfg: BuildConfig) -> Result let mut hash = [0u8; 32]; keccak.finalize(&mut hash); - println!( - "Project hash computed on deployment: {:?}", + greyln!( + "project metadata hash computed on deployment: {:?}", hex::encode(hash) ); Ok(hash) @@ -235,10 +281,12 @@ fn expand_glob_patterns(patterns: Vec) -> Result> { } /// Reads a WASM file at a specified path and returns its brotli compressed bytes. -pub fn compress_wasm(wasm: &PathBuf) -> Result<(Vec, Vec)> { +pub fn compress_wasm(wasm: &PathBuf, project_hash: [u8; 32]) -> Result<(Vec, Vec)> { let wasm = fs::read(wasm).wrap_err_with(|| eyre!("failed to read Wasm {}", wasm.to_string_lossy()))?; + let wasm = add_project_hash_to_wasm_file(&wasm, project_hash) + .wrap_err("failed to add project hash to wasm file as custom section")?; let wasm = wasmer::wat2wasm(&wasm).wrap_err("failed to parse Wasm")?; let mut compressor = BrotliEncoder::new(&*wasm, BROTLI_COMPRESSION_LEVEL); @@ -253,6 +301,44 @@ pub fn compress_wasm(wasm: &PathBuf) -> Result<(Vec, Vec)> { Ok((wasm.to_vec(), contract_code)) } +// Adds the hash of the project's source files to the wasm as a custom section +// if it does not already exist. This allows for reproducible builds by cargo stylus +// for all Rust stylus contracts. See `cargo stylus verify --help` for more information. +fn add_project_hash_to_wasm_file( + wasm_file_bytes: &[u8], + project_hash: [u8; 32], +) -> Result> { + let section_exists = has_project_hash_section(wasm_file_bytes)?; + if section_exists { + greyln!("Wasm file bytes already contains a custom section with a project hash, not overwriting'"); + return Ok(wasm_file_bytes.to_vec()); + } + Ok(add_custom_section(wasm_file_bytes, project_hash)) +} + +pub fn has_project_hash_section(wasm_file_bytes: &[u8]) -> Result { + let parser = wasmparser::Parser::new(0); + for payload in parser.parse_all(wasm_file_bytes) { + if let wasmparser::Payload::CustomSection(reader) = payload? { + if reader.name() == PROJECT_HASH_SECTION_NAME { + println!( + "Found the project hash custom section name {}", + hex::encode(reader.data()) + ); + return Ok(true); + } + } + } + Ok(false) +} + +fn add_custom_section(wasm_file_bytes: &[u8], project_hash: [u8; 32]) -> Vec { + let mut bytes = vec![]; + bytes.extend_from_slice(wasm_file_bytes); + wasm_gen::write_custom_section(&mut bytes, PROJECT_HASH_SECTION_NAME, &project_hash); + bytes +} + #[cfg(test)] mod test { use super::*; @@ -260,6 +346,49 @@ mod test { use std::io::Write; use tempfile::tempdir; + #[test] + fn test_extract_toolchain_channel() -> Result<()> { + let dir = tempdir()?; + let dir_path = dir.path(); + + let toolchain_file_path = dir_path.join(TOOLCHAIN_FILE_NAME); + let toolchain_contents = r#" + [toolchain] + "#; + std::fs::write(&toolchain_file_path, toolchain_contents)?; + + let channel = extract_toolchain_channel(&toolchain_file_path); + let Err(err_details) = channel else { + panic!("expected an error"); + }; + assert!(err_details.to_string().contains("could not find channel"),); + + let toolchain_contents = r#" + [toolchain] + channel = 32390293 + "#; + std::fs::write(&toolchain_file_path, toolchain_contents)?; + + let channel = extract_toolchain_channel(&toolchain_file_path); + let Err(err_details) = channel else { + panic!("expected an error"); + }; + assert!(err_details.to_string().contains("is not a string"),); + + let toolchain_contents = r#" + [toolchain] + channel = "nightly-2020-07-10" + components = [ "rustfmt", "rustc-dev" ] + targets = [ "wasm32-unknown-unknown", "thumbv2-none-eabi" ] + profile = "minimal" + "#; + std::fs::write(&toolchain_file_path, toolchain_contents)?; + + let channel = extract_toolchain_channel(&toolchain_file_path)?; + assert_eq!(channel, "nightly-2020-07-10"); + Ok(()) + } + #[test] fn test_all_paths() -> Result<()> { let dir = tempdir()?; diff --git a/check/src/verify.rs b/check/src/verify.rs index 9cb4faf..2cc0084 100644 --- a/check/src/verify.rs +++ b/check/src/verify.rs @@ -12,7 +12,13 @@ use ethers::types::H256; use serde::{Deserialize, Serialize}; -use crate::{check, deploy, project, CheckConfig, VerifyConfig}; +use crate::{ + check, + constants::TOOLCHAIN_FILE_NAME, + deploy::{self, extract_compressed_wasm, extract_contract_evm_deployment_prelude}, + project::{self, extract_toolchain_channel}, + CheckConfig, VerifyConfig, +}; use cargo_stylus_util::{color::Color, sys}; #[derive(Debug, Deserialize, Serialize)] @@ -26,6 +32,9 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { if hash.len() != 32 { bail!("Invalid hash"); } + let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); + let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; + let rust_stable = !toolchain_channel.contains("nightly"); let Some(result) = provider .get_transaction(H256::from_slice(&hash)) .await @@ -44,27 +53,48 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { let check_cfg = CheckConfig { common_cfg: cfg.common_cfg.clone(), wasm_file: None, - program_address: None, + contract_address: None, }; let _ = check::check(&check_cfg) .await .map_err(|e| eyre!("Stylus checks failed: {e}"))?; let build_cfg = project::BuildConfig { opt_level: project::OptLevel::default(), - stable: cfg.common_cfg.rust_stable, + stable: rust_stable, }; let wasm_file: PathBuf = project::build_dylib(build_cfg.clone()) .map_err(|e| eyre!("could not build project to WASM: {e}"))?; - let (_, init_code) = project::compress_wasm(&wasm_file)?; - let hash = project::hash_files(cfg.common_cfg.source_files_for_project_hash, build_cfg)?; - let deployment_data = deploy::program_deployment_calldata(&init_code, &hash); + let project_hash = + project::hash_files(cfg.common_cfg.source_files_for_project_hash, build_cfg)?; + let (_, init_code) = project::compress_wasm(&wasm_file, project_hash)?; + let deployment_data = deploy::contract_deployment_calldata(&init_code); if deployment_data == *result.input { - println!("Verified - program matches local project's file hashes"); + println!("Verified - contract matches local project's file hashes"); } else { + let tx_prelude = extract_contract_evm_deployment_prelude(&result.input); + let reconstructed_prelude = extract_contract_evm_deployment_prelude(&deployment_data); println!( - "{} - program deployment did not verify against local project's file hashes", + "{} - contract deployment did not verify against local project's file hashes", "FAILED".red() ); + if tx_prelude != reconstructed_prelude { + println!("Prelude mismatch"); + println!("Deployment tx prelude {}", hex::encode(tx_prelude)); + println!( + "Reconstructed prelude {}", + hex::encode(reconstructed_prelude) + ); + } else { + println!("Compressed WASM bytecode mismatch"); + } + println!( + "Compressed code length of locally reconstructed {}", + init_code.len() + ); + println!( + "Compressed code length of deployment tx {}", + extract_compressed_wasm(&result.input).len() + ); } Ok(()) } diff --git a/install.sh b/install.sh index 682f003..99aee25 100755 --- a/install.sh +++ b/install.sh @@ -3,3 +3,4 @@ cargo clippy --package cargo-stylus --package cargo-stylus-cgen --package cargo- cargo install --path main cargo install --path cgen cargo install --path check +cargo install --path replay diff --git a/main/src/main.rs b/main/src/main.rs index 2738d04..355e326 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -1,81 +1,88 @@ // Copyright 2023-2024, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md +// 라이선스 정보는 https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md에서 확인할 수 있습니다. -use cargo_stylus_util::{color::Color, sys}; -use clap::Parser; -use eyre::{bail, Result}; +use cargo_stylus_util::{color::Color, sys}; // 색상 및 시스템 명령어 관련 유틸리티 모듈을 가져옴 +use clap::{CommandFactory, Parser}; // CLI 명령어 파싱을 위한 clap 라이브러리 가져옴 +use eyre::{bail, Result}; // 오류 처리 및 결과 반환을 위한 eyre 라이브러리 가져옴 -// Conditional import for Unix-specific `CommandExt` +// Unix 계열 운영체제에서만 사용되는 `CommandExt`를 조건부로 가져옴 #[cfg(unix)] use std::{env, os::unix::process::CommandExt}; -// Conditional import for Windows +// Windows에서만 사용되는 모듈을 조건부로 가져옴 #[cfg(windows)] use std::env; -#[derive(Parser, Debug)] -#[command(name = "stylus")] -#[command(bin_name = "cargo stylus")] -#[command(author = "Offchain Labs, Inc.")] -#[command(about = "Cargo subcommand for developing Stylus projects", long_about = None)] -#[command(propagate_version = true)] -#[command(version)] +#[derive(Parser, Debug)] // 명령어 파서를 정의하고 디버그 모드 활성화 +#[command(name = "stylus")] // 명령어 이름을 설정 +#[command(bin_name = "cargo stylus")] // 이 바이너리가 실행될 때 사용할 명령어 이름 +#[command(author = "Offchain Labs, Inc.")] // 작성자 정보 +#[command(about = "Stylus 프로젝트를 개발하기 위한 Cargo 서브 명령어", long_about = None)] // 프로그램 설명 +#[command(propagate_version = true)] // 버전 정보를 전파하도록 설정 +#[command(version)] // 버전 정보를 포함하도록 설정 struct Opts { #[command(subcommand)] - command: Subcommands, + command: Subcommands, // 서브커맨드를 정의 } -#[derive(Parser, Debug, Clone)] +#[derive(Parser, Debug, Clone)] // 서브커맨드의 파서를 정의하고 디버그 모드 및 복제 가능 설정 enum Subcommands { #[command(alias = "n")] - /// Create a new Rust project. - New, + /// 새로운 Stylus 프로젝트를 생성합니다. + New, // 새로운 프로젝트를 생성하는 서브커맨드 + #[command(alias = "i")] + /// 현재 디렉토리에 Stylus 프로젝트를 초기화합니다. + Init, // 현재 디렉토리에 프로젝트를 초기화하는 서브커맨드 #[command(alias = "x")] - /// Export a Solidity ABI. - ExportAbi, - /// Cache a contract. + /// Solidity ABI를 내보냅니다. + ExportAbi, // Solidity ABI를 내보내는 서브커맨드 + /// 계약을 캐시합니다. + Cache, // 계약을 캐시하는 서브커맨드 + /// 계약을 검사합니다. #[command(alias = "c")] - Cache, - /// Check a contract. - #[command(alias = "c")] - Check, - /// Deploy a contract. + Check, // 계약을 검사하는 서브커맨드 + /// 이미 배포된 계약을 활성화합니다. + #[command(alias = "a")] + Activate, // 이미 배포된 계약을 활성화하는 서브커맨드 + /// 계약을 배포합니다. #[command(alias = "d")] - Deploy, - /// Replay a transaction in gdb. + Deploy, // 계약을 배포하는 서브커맨드 + /// gdb에서 트랜잭션을 재실행합니다. #[command(alias = "r")] - Replay, - /// Trace a transaction. + Replay, // 트랜잭션을 gdb에서 재실행하는 서브커맨드 + /// 트랜잭션을 추적합니다. #[command()] - Trace, - /// Verify the deployment of a Stylus program against a local project. + Trace, // 트랜잭션을 추적하는 서브커맨드 + /// Stylus 계약의 배포를 로컬 프로젝트와 검증합니다. #[command(alias = "v")] - Verify, - /// Run cargo stylus commands in a Docker container for reproducibility. - #[command()] - Reproducible, - /// Generate C code. + Verify, // Stylus 계약의 배포를 검증하는 서브커맨드 + /// C 코드를 생성합니다. #[command()] - CGen, + CGen, // C 코드를 생성하는 서브커맨드 } +// 명령어 정보 구조체 struct Binary<'a> { - name: &'a str, - apis: &'a [&'a str], - rust_flags: Option<&'a str>, + name: &'a str, // 바이너리 이름 + apis: &'a [&'a str], // API 명령어 목록 + rust_flags: Option<&'a str>, // Rust 플래그 옵션 } +// 명령어 목록을 상수로 정의 const COMMANDS: &[Binary] = &[ Binary { name: "cargo-stylus-check", apis: &[ "new", + "init", + "activate", "export-abi", "cache", "check", "deploy", "verify", - "reproducible", + "a", + "i", "n", "x", "c", @@ -102,55 +109,60 @@ const COMMANDS: &[Binary] = &[ }, ]; +// 도움말 메시지를 출력하고 프로그램을 종료 fn exit_with_help_msg() -> ! { - Opts::parse_from(["--help"]); - unreachable!() + Opts::command().print_help().unwrap(); + std::process::exit(0); } +// 버전 정보를 출력하고 프로그램을 종료 fn exit_with_version() -> ! { - Opts::parse_from(["--version"]); - unreachable!() + println!("{}", Opts::command().render_version()); + std::process::exit(0); } +// 메인 함수 fn main() -> Result<()> { - // skip the starting arguments passed from the OS and/or cargo. + // 운영체제와 Cargo에서 전달된 시작 인수를 건너뜁니다. let mut args = env::args().skip_while(|x| x == "cargo" || x == "stylus" || x.contains("cargo-stylus")); + // 첫 번째 명령어 인수를 가져옵니다. 없다면 도움말 메시지를 출력 let Some(arg) = args.next() else { exit_with_help_msg(); }; - // perform any builtins + // 내장된 명령어를 처리합니다. match arg.as_str() { "--help" | "-h" => exit_with_help_msg(), "--version" | "-V" => exit_with_version(), _ => {} }; + // 명령어가 COMMANDS 목록에 있는지 확인합니다. 없다면 커스텀 명령어를 확인 let Some(bin) = COMMANDS.iter().find(|x| x.apis.contains(&arg.as_str())) else { - // see if custom extension exists + // 커스텀 확장이 존재하는지 확인 let custom = format!("cargo-stylus-{arg}"); if sys::command_exists(&custom) { let mut command = sys::new_command(&custom); command.arg(arg).args(args); - // Execute command conditionally based on the platform + // 플랫폼에 따라 명령어 실행 #[cfg(unix)] - let err = command.exec(); // Unix-specific execution + let err = command.exec(); // Unix 전용 실행 방식 #[cfg(windows)] - let err = command.status(); // Windows-specific execution - bail!("failed to invoke {:?}: {:?}", custom.red(), err); + let err = command.status(); // Windows 전용 실행 방식 + bail!("failed to invoke {:?}: {:?}", custom.red(), err); // 오류 발생 시 메시지 출력 } eprintln!("Unknown subcommand {}.", arg.red()); eprintln!(); - exit_with_help_msg(); + exit_with_help_msg(); // 알 수 없는 서브커맨드일 경우 도움말 메시지를 출력하고 종료 }; let name = bin.name; - // not all subcommands are shipped with `cargo-stylus`. + // 해당 서브커맨드가 설치되지 않은 경우 설치 방법을 안내 if !sys::command_exists(name) { let flags = bin.rust_flags.map(|x| format!("{x} ")).unwrap_or_default(); let install = format!(" {flags}cargo install --force {name}"); @@ -162,14 +174,14 @@ fn main() -> Result<()> { return Ok(()); } - // should never return + // 명령어를 생성하고 인수를 추가 let mut command = sys::new_command(name); command.arg(arg).args(args); - // Execute command conditionally based on the platform + // 플랫폼에 따라 명령어 실행 #[cfg(unix)] - let err = command.exec(); // Unix-specific execution + let err = command.exec(); // Unix 전용 실행 방식 #[cfg(windows)] - let err = command.status(); // Windows-specific execution - bail!("failed to invoke {:?}: {:?}", name.red(), err); + let err = command.status(); // Windows 전용 실행 방식 + bail!("failed to invoke {:?}: {:?}", name.red(), err); // 오류 발생 시 메시지 출력 } diff --git a/replay/src/hostio.rs b/replay/src/hostio.rs index 1674ee4..d47b218 100644 --- a/replay/src/hostio.rs +++ b/replay/src/hostio.rs @@ -37,7 +37,7 @@ macro_rules! copy { }; } -/// Reads the program calldata. The semantics are equivalent to that of the EVM's +/// Reads the contract calldata. The semantics are equivalent to that of the EVM's /// [`CALLDATA_COPY`] opcode when requesting the entirety of the current call's calldata. /// /// [`CALLDATA_COPY`]: https://www.evm.codes/#37 @@ -48,16 +48,31 @@ pub unsafe extern "C" fn read_args(dest: *mut u8) { copy!(args, dest, args.len()); } -/// Writes the final return data. If not called before the program exists, the return data will -/// be 0 bytes long. Note that this hostio does not cause the program to exit, which happens +/// Writes the final return data. If not called before the contract exists, the return data will +/// be 0 bytes long. Note that this hostio does not cause the contract to exit, which happens /// naturally when `user_entrypoint` returns. #[named] #[no_mangle] -pub unsafe extern "C" fn write_result(data: *const u8, len: usize) { +pub unsafe extern "C" fn write_result(data: *const u8, len: u32) { frame!(WriteResult { result }); assert_eq!(read_bytes(data, len), &*result); } +/// Exits program execution early with the given status code. +/// If `0`, the program returns successfully with any data supplied by `write_result`. +/// Otherwise, the program reverts and treats any `write_result` data as revert data. +/// +/// The semantics are equivalent to that of the EVM's [`Return`] and [`Revert`] opcodes. +/// Note: this function just traces, it's up to the caller to actually perform the exit. +/// +/// [`Return`]: https://www.evm.codes/#f3 +/// [`Revert`]: https://www.evm.codes/#fd +#[named] +#[no_mangle] +pub unsafe extern "C" fn exit_early(status: u32) { + frame!(ExitEarly { status }); +} + /// Reads a 32-byte value from permanent storage. Stylus's storage format is identical to /// that of the EVM. This means that, under the hood, this hostio is accessing the 32-byte /// value stored in the EVM state trie at offset `key`, which will be `0` when not previously @@ -72,32 +87,61 @@ pub unsafe extern "C" fn storage_load_bytes32(key_ptr: *const u8, dest: *mut u8) copy!(value, dest); } -/// Stores a 32-byte value to permanent storage. Stylus's storage format is identical to that -/// of the EVM. This means that, under the hood, this hostio is storing a 32-byte value into -/// the EVM state trie at offset `key`. Furthermore, refunds are tabulated exactly as in the -/// EVM. The semantics, then, are equivalent to that of the EVM's [`SSTORE`] opcode. +/// Writes a 32-byte value to the permanent storage cache. Stylus's storage format is identical to that +/// of the EVM. This means that, under the hood, this hostio represents storing a 32-byte value into +/// the EVM state trie at offset `key`. Refunds are tabulated exactly as in the EVM. The semantics, then, +/// are equivalent to that of the EVM's [`SSTORE`] opcode. +/// +/// Note: because this value is cached, one must call `storage_flush_cache` to persist the value. +/// +/// Auditor's note: we require the [`SSTORE`] sentry per EVM rules. The `gas_cost` returned by the EVM API +/// may exceed this amount, but that's ok because the predominant cost is due to state bloat concerns. /// /// [`SSTORE`]: https://www.evm.codes/#55 #[named] #[no_mangle] -pub unsafe extern "C" fn storage_store_bytes32(key_ptr: *const u8, value_ptr: *const u8) { - frame!(StorageStoreBytes32 { key, value }); +pub unsafe extern "C" fn storage_cache_bytes32(key_ptr: *const u8, value_ptr: *const u8) { + frame!(StorageCacheBytes32 { key, value }); assert_eq!(read_fixed(key_ptr), key); assert_eq!(read_fixed(value_ptr), value); } +/// Persists any dirty values in the storage cache to the EVM state trie, dropping the cache entirely if requested. +/// Analogous to repeated invocations of [`SSTORE`]. +/// +/// [`SSTORE`]: https://www.evm.codes/#55 #[named] #[no_mangle] -pub unsafe extern "C" fn storage_cache_bytes32(key_ptr: *const u8, value_ptr: *const u8) { - frame!(StorageCacheBytes32 { key, value }); +pub unsafe extern "C" fn storage_flush_cache(clear: u32) { + frame!(StorageFlushCache { clear }); +} + +/// Reads a 32-byte value from transient storage. Stylus's storage format is identical to +/// that of the EVM. This means that, under the hood, this hostio is accessing the 32-byte +/// value stored in the EVM's transient state trie at offset `key`, which will be `0` when not previously +/// set. The semantics, then, are equivalent to that of the EVM's [`TLOAD`] opcode. +/// +/// [`TLOAD`]: https://www.evm.codes/#5c +#[named] +#[no_mangle] +pub unsafe extern "C" fn transient_load_bytes32(key_ptr: *const u8, dest: *mut u8) { + frame!(TransientLoadBytes32 { key, value }); assert_eq!(read_fixed(key_ptr), key); - assert_eq!(read_fixed(value_ptr), value); + copy!(value, dest); } +/// Writes a 32-byte value to transient storage. Stylus's storage format is identical to that +/// of the EVM. This means that, under the hood, this hostio represents storing a 32-byte value into +/// the EVM's transient state trie at offset `key`. The semantics, then, are equivalent to that of the +/// EVM's [`TSTORE`] opcode. +/// +/// [`TSTORE`]: https://www.evm.codes/#5d #[named] #[no_mangle] -pub unsafe extern "C" fn storage_flush_cache(clear: u32) { - frame!(StorageFlushCache { clear }); +pub unsafe extern "C" fn transient_store_bytes32(key_ptr: *const u8, value_ptr: *const u8) { + frame!(TransientStoreBytes32 { key, value }); + assert_eq!(read_fixed(key_ptr), key); + assert_eq!(read_fixed(value_ptr), value); } /// Gets the ETH balance in wei of the account at the given address. @@ -112,6 +156,45 @@ pub unsafe extern "C" fn account_balance(address_ptr: *const u8, dest: *mut u8) copy!(balance.to_be_bytes::<32>(), dest); } +/// Gets a subset of the code from the account at the given address. The semantics are identical to that +/// of the EVM's [`EXT_CODE_COPY`] opcode, aside from one small detail: the write to the buffer `dest` will +/// stop after the last byte is written. This is unlike the EVM, which right pads with zeros in this scenario. +/// The return value is the number of bytes written, which allows the caller to detect if this has occured. +/// +/// [`EXT_CODE_COPY`]: https://www.evm.codes/#3C +#[named] +#[no_mangle] +pub unsafe extern "C" fn account_code( + address_ptr: *const u8, + offset_recv: u32, + size_recv: u32, + dest: *mut u8, +) -> u32 { + frame!(AccountCode { + address, + offset, + size, + code + }); + assert_eq!(offset_recv, offset); + assert_eq!(size_recv, size); + assert_eq!(read_fixed(address_ptr), address); + copy!(code, dest); + code.len() as u32 +} + +/// Gets the size of the code in bytes at the given address. The semantics are equivalent +/// to that of the EVM's [`EXT_CODESIZE`]. +/// +/// [`EXT_CODESIZE`]: https://www.evm.codes/#3B +#[named] +#[no_mangle] +pub unsafe extern "C" fn account_code_size(address_ptr: *const u8) -> u32 { + frame!(AccountCodeSize { address, size }); + assert_eq!(read_fixed(address_ptr), address); + size +} + /// Gets the code hash of the account at the given address. The semantics are equivalent /// to that of the EVM's [`EXT_CODEHASH`] opcode. Note that the code hash of an account without /// code will be the empty hash @@ -215,10 +298,10 @@ pub unsafe extern "C" fn chainid() -> u64 { pub unsafe extern "C" fn call_contract( address_ptr: *const u8, calldata: *const u8, - calldata_len: usize, + calldata_len: u32, value_ptr: *const u8, gas_supplied: u64, - return_data_len: *mut usize, + return_data_len: *mut u32, ) -> u8 { frame!(CallContract { address, @@ -233,7 +316,7 @@ pub unsafe extern "C" fn call_contract( assert_eq!(read_bytes(calldata, calldata_len), &*data); assert_eq!(read_fixed(value_ptr), value.to_be_bytes::<32>()); assert_eq!(gas_supplied, gas); - *return_data_len = outs_len as usize; + *return_data_len = outs_len; status } @@ -256,9 +339,9 @@ pub unsafe extern "C" fn call_contract( pub unsafe extern "C" fn delegate_call_contract( address_ptr: *const u8, calldata: *const u8, - calldata_len: usize, + calldata_len: u32, gas_supplied: u64, - return_data_len: *mut usize, + return_data_len: *mut u32, ) -> u8 { frame!(DelegateCallContract { address, @@ -271,7 +354,7 @@ pub unsafe extern "C" fn delegate_call_contract( assert_eq!(read_fixed(address_ptr), address); assert_eq!(read_bytes(calldata, calldata_len), &*data); assert_eq!(gas_supplied, gas); - *return_data_len = outs_len as usize; + *return_data_len = outs_len; status } @@ -294,9 +377,9 @@ pub unsafe extern "C" fn delegate_call_contract( pub unsafe extern "C" fn static_call_contract( address_ptr: *const u8, calldata: *const u8, - calldata_len: usize, + calldata_len: u32, gas_supplied: u64, - return_data_len: *mut usize, + return_data_len: *mut u32, ) -> u8 { frame!(StaticCallContract { address, @@ -309,11 +392,11 @@ pub unsafe extern "C" fn static_call_contract( assert_eq!(read_fixed(address_ptr), address); assert_eq!(read_bytes(calldata, calldata_len), &*data); assert_eq!(gas_supplied, gas); - *return_data_len = outs_len as usize; + *return_data_len = outs_len; status } -/// Gets the address of the current program. The semantics are equivalent to that of the EVM's +/// Gets the address of the current contract. The semantics are equivalent to that of the EVM's /// [`ADDRESS`] opcode. /// /// [`ADDRESS`]: https://www.evm.codes/#30 @@ -326,9 +409,9 @@ pub unsafe extern "C" fn contract_address(dest: *mut u8) { /// Deploys a new contract using the init code provided, which the EVM executes to construct /// the code of the newly deployed contract. The init code must be written in EVM bytecode, but -/// the code it deploys can be that of a Stylus program. The code returned will be treated as +/// the code it deploys can be that of a Stylus contract. The code returned will be treated as /// WASM if it begins with the EOF-inspired header `0xEFF000`. Otherwise the code will be -/// interpreted as that of a traditional EVM-style contract. See [`Deploying Stylus Programs`] +/// interpreted as that of a traditional EVM-style contract. See [`Deploying Stylus Contracts`] /// for more information on writing init code. /// /// On success, this hostio returns the address of the newly created account whose address is @@ -337,16 +420,16 @@ pub unsafe extern "C" fn contract_address(dest: *mut u8) { /// `read_return_data` hostio. The semantics are equivalent to that of the EVM's [`CREATE`] /// opcode, which notably includes the exact address returned. /// -/// [`Deploying Stylus Programs`]: https://developer.arbitrum.io/TODO +/// [`Deploying Stylus Contracts`]: https://developer.arbitrum.io/TODO /// [`CREATE`]: https://www.evm.codes/#f0 #[named] #[no_mangle] pub unsafe extern "C" fn create1( code_ptr: *const u8, - code_len: usize, + code_len: u32, value: *const u8, contract: *mut u8, - revert_data_len_ptr: *mut usize, + revert_data_len_ptr: *mut u32, ) { frame!(Create1 { code, @@ -362,9 +445,9 @@ pub unsafe extern "C" fn create1( /// Deploys a new contract using the init code provided, which the EVM executes to construct /// the code of the newly deployed contract. The init code must be written in EVM bytecode, but -/// the code it deploys can be that of a Stylus program. The code returned will be treated as +/// the code it deploys can be that of a Stylus contract. The code returned will be treated as /// WASM if it begins with the EOF-inspired header `0xEFF000`. Otherwise the code will be -/// interpreted as that of a traditional EVM-style contract. See [`Deploying Stylus Programs`] +/// interpreted as that of a traditional EVM-style contract. See [`Deploying Stylus Contracts`] /// for more information on writing init code. /// /// On success, this hostio returns the address of the newly created account whose address is a @@ -373,17 +456,17 @@ pub unsafe extern "C" fn create1( /// via the `read_return_data` hostio. The semantics are equivalent to that of the EVM's /// `[CREATE2`] opcode, which notably includes the exact address returned. /// -/// [`Deploying Stylus Programs`]: https://developer.arbitrum.io/TODO +/// [`Deploying Stylus Contracts`]: https://developer.arbitrum.io/TODO /// [`CREATE2`]: https://www.evm.codes/#f5 #[named] #[no_mangle] pub unsafe extern "C" fn create2( code_ptr: *const u8, - code_len: usize, + code_len: u32, value_ptr: *const u8, salt_ptr: *const u8, contract: *mut u8, - revert_data_len_ptr: *mut usize, + revert_data_len_ptr: *mut u32, ) { frame!(Create2 { code, @@ -411,7 +494,7 @@ pub unsafe extern "C" fn create2( /// [`LOG4`]: https://www.evm.codes/#a4 #[named] #[no_mangle] -pub unsafe extern "C" fn emit_log(data_ptr: *const u8, len: usize, topic_count: usize) { +pub unsafe extern "C" fn emit_log(data_ptr: *const u8, len: u32, topic_count: u32) { frame!(EmitLog { data, topics }); assert_eq!(read_bytes(data_ptr, len), &*data); assert_eq!(topics, topic_count); @@ -442,7 +525,7 @@ pub unsafe extern "C" fn evm_ink_left() -> u64 { } /// The `entrypoint!` macro handles importing this hostio, which is required if the -/// program's memory grows. Otherwise compilation through the `ArbWasm` precompile will revert. +/// contract's memory grows. Otherwise compilation through the `ArbWasm` precompile will revert. /// Internally the Stylus VM forces calls to this hostio whenever new WASM pages are allocated. /// Calls made voluntarily will unproductively consume gas. #[named] @@ -452,6 +535,77 @@ pub unsafe extern "C" fn pay_for_memory_grow(new_pages: u16) { assert_eq!(new_pages, pages); } +/// Computes `value ÷ exponent` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`DIV`] opcode, which means that a `divisor` of `0` +/// writes `0` to `value`. +/// +/// [`DIV`]: https://www.evm.codes/#04 +#[named] +#[no_mangle] +pub unsafe fn math_div(value: *mut u8, divisor: *const u8) { + frame!(MathDiv { a, b, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(divisor), b.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + +/// Computes `value % exponent` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`MOD`] opcode, which means that a `modulus` of `0` +/// writes `0` to `value`. +/// +/// [`MOD`]: https://www.evm.codes/#06 +#[named] +#[no_mangle] +pub unsafe fn math_mod(value: *mut u8, modulus: *const u8) { + frame!(MathMod { a, b, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(modulus), b.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + +/// Computes `value ^ exponent` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`EXP`] opcode. +/// +/// [`EXP`]: https://www.evm.codes/#0A +#[named] +#[no_mangle] +pub unsafe fn math_pow(value: *mut u8, exponent: *const u8) { + frame!(MathPow { a, b, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(exponent), b.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + +/// Computes `(value + addend) % modulus` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`ADDMOD`] opcode, which means that a `modulus` of `0` +/// writes `0` to `value`. +/// +/// [`ADDMOD`]: https://www.evm.codes/#08 +#[named] +#[no_mangle] +pub unsafe fn math_add_mod(value: *mut u8, addend: *const u8, modulus: *const u8) { + frame!(MathAddMod { a, b, c, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(addend), b.to_be_bytes::<32>()); + assert_eq!(read_fixed(modulus), c.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + +/// Computes `(value * multiplier) % modulus` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`MULMOD`] opcode, which means that a `modulus` of `0` +/// writes `0` to `value`. +/// +/// [`MULMOD`]: https://www.evm.codes/#09 +#[named] +#[no_mangle] +pub unsafe fn math_mul_mod(value: *mut u8, multiplier: *const u8, modulus: *const u8) { + frame!(MathAddMod { a, b, c, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(multiplier), b.to_be_bytes::<32>()); + assert_eq!(read_fixed(modulus), c.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + /// Whether the current call is reentrant. #[named] #[no_mangle] @@ -460,7 +614,7 @@ pub unsafe extern "C" fn msg_reentrant() -> bool { reentrant } -/// Gets the address of the account that called the program. For normal L2-to-L2 transactions +/// Gets the address of the account that called the contract. For normal L2-to-L2 transactions /// the semantics are equivalent to that of the EVM's [`CALLER`] opcode, including in cases /// arising from [`DELEGATE_CALL`]. /// @@ -477,7 +631,7 @@ pub unsafe extern "C" fn msg_sender(dest: *mut u8) { copy!(sender, dest); } -/// Get the ETH value in wei sent to the program. The semantics are equivalent to that of the +/// Get the ETH value in wei sent to the contract. The semantics are equivalent to that of the /// EVM's [`CALLVALUE`] opcode. /// /// [`CALLVALUE`]: https://www.evm.codes/#34 @@ -495,7 +649,7 @@ pub unsafe extern "C" fn msg_value(dest: *mut u8) { /// [`SHA3`]: https://www.evm.codes/#20 #[named] #[no_mangle] -pub unsafe extern "C" fn native_keccak256(bytes: *const u8, len: usize, output: *mut u8) { +pub unsafe extern "C" fn native_keccak256(bytes: *const u8, len: u32, output: *mut u8) { frame!(NativeKeccak256 { preimage, digest }); assert_eq!(read_bytes(bytes, len), &*preimage); copy!(digest, output); @@ -510,24 +664,24 @@ pub unsafe extern "C" fn native_keccak256(bytes: *const u8, len: usize, output: #[no_mangle] pub unsafe extern "C" fn read_return_data( dest: *mut u8, - offset_value: usize, - size_value: usize, -) -> usize { + offset_value: u32, + size_value: u32, +) -> u32 { frame!(ReadReturnData { offset, size, data }); - assert_eq!(offset_value, offset as usize); - assert_eq!(size_value, size as usize); + assert_eq!(offset_value, offset); + assert_eq!(size_value, size); copy!(data, dest, data.len()); - data.len() + data.len() as u32 } /// Returns the length of the last EVM call or deployment return result, or `0` if neither have -/// happened during the program's execution. The semantics are equivalent to that of the EVM's +/// happened during the contract's execution. The semantics are equivalent to that of the EVM's /// [`RETURN_DATA_SIZE`] opcode. /// /// [`RETURN_DATA_SIZE`]: https://www.evm.codes/#3d #[named] #[no_mangle] -pub unsafe extern "C" fn return_data_size() -> usize { +pub unsafe extern "C" fn return_data_size() -> u32 { frame!(ReturnDataSize { size }); size } @@ -604,7 +758,7 @@ pub unsafe extern "C" fn log_i64(value: i64) { /// Prints a UTF-8 encoded string to the console. Only available in debug mode. #[named] #[no_mangle] -pub unsafe extern "C" fn log_txt(text_ptr: *const u8, len: usize) { +pub unsafe extern "C" fn log_txt(text_ptr: *const u8, len: u32) { frame!(ConsoleLogText { text }); assert_eq!(read_bytes(text_ptr, len), &*text); } @@ -615,7 +769,8 @@ unsafe fn read_fixed(ptr: *const u8) -> [u8; N] { value.assume_init() } -unsafe fn read_bytes(ptr: *const u8, len: usize) -> Vec { +unsafe fn read_bytes(ptr: *const u8, len: u32) -> Vec { + let len = len as usize; let mut data = Vec::with_capacity(len); memcpy(ptr, data.as_mut_ptr(), len); data.set_len(len); diff --git a/replay/src/main.rs b/replay/src/main.rs index e74b465..79fd1da 100644 --- a/replay/src/main.rs +++ b/replay/src/main.rs @@ -147,7 +147,7 @@ async fn replay(args: ReplayArgs) -> Result<()> { let provider = sys::new_provider(&args.endpoint)?; let trace = Trace::new(provider, args.tx).await?; - build_so(&args.project, args.stable_rust)?; + build_so(&args.project)?; let so = find_so(&args.project)?; // TODO: don't assume the contract is top-level @@ -169,12 +169,9 @@ async fn replay(args: ReplayArgs) -> Result<()> { Ok(()) } -pub fn build_so(path: &Path, stable: bool) -> Result<()> { +pub fn build_so(path: &Path) -> Result<()> { let mut cargo = sys::new_command("cargo"); - if !stable { - cargo.arg("+nightly"); - } cargo .current_dir(path) .arg("build") diff --git a/replay/src/trace.rs b/replay/src/trace.rs index fecd5c6..f7b9bb2 100644 --- a/replay/src/trace.rs +++ b/replay/src/trace.rs @@ -3,7 +3,7 @@ #![allow(clippy::redundant_closure_call)] -use alloy_primitives::{Address, FixedBytes, TxHash, B256, U256}; +use alloy_primitives::{Address, TxHash, B256, U256}; use cargo_stylus_util::color::{Color, DebugColor}; use ethers::{ providers::{JsonRpcClient, Middleware, Provider}, @@ -44,13 +44,13 @@ impl Trace { if let Value::Array(arr) = json.clone() { if arr.is_empty() { - bail!("No trace frames found, perhaps you are attempting to trace the program deployment transaction"); + bail!("No trace frames found, perhaps you are attempting to trace the contract deployment transaction"); } } let maybe_activation_trace: Result, _> = from_value(json.clone()); if maybe_activation_trace.is_ok() { - bail!("Your tx was a program activation transaction. It has no trace frames"); + bail!("Your tx was a contract activation transaction. It has no trace frames"); } let to = receipt.to.map(|x| Address::from(x.0)); @@ -205,11 +205,6 @@ impl TraceFrame { read_num!($src, u64) }; } - macro_rules! read_usize { - ($src:ident) => { - read_num!($src, usize) - }; - } macro_rules! frame { () => {{ @@ -241,14 +236,13 @@ impl TraceFrame { "write_result" => WriteResult { result: read_data!(args), }, + "exit_early" => ExitEarly { + status: read_u32!(args), + }, "storage_load_bytes32" => StorageLoadBytes32 { key: read_b256!(args), value: read_b256!(outs), }, - "storage_store_bytes32" => StorageStoreBytes32 { - key: read_b256!(args), - value: read_b256!(args), - }, "storage_cache_bytes32" => StorageCacheBytes32 { key: read_b256!(args), value: read_b256!(args), @@ -256,10 +250,28 @@ impl TraceFrame { "storage_flush_cache" => StorageFlushCache { clear: read_u8!(args), }, + "transient_load_bytes32" => TransientLoadBytes32 { + key: read_b256!(args), + value: read_b256!(outs), + }, + "transient_store_bytes32" => TransientStoreBytes32 { + key: read_b256!(args), + value: read_b256!(args), + }, "account_balance" => AccountBalance { address: read_address!(args), balance: read_u256!(outs), }, + "account_code" => AccountCode { + address: read_address!(args), + offset: read_u32!(args), + size: read_u32!(args), + code: read_data!(outs), + }, + "account_code_size" => AccountCodeSize { + address: read_address!(args), + size: read_u32!(outs), + }, "account_codehash" => AccountCodehash { address: read_address!(args), codehash: read_b256!(outs), @@ -291,6 +303,33 @@ impl TraceFrame { "evm_ink_left" => EvmInkLeft { ink_left: read_u64!(outs), }, + "math_div" => MathDiv { + a: read_u256!(args), + b: read_u256!(args), + result: read_u256!(outs), + }, + "math_mod" => MathMod { + a: read_u256!(args), + b: read_u256!(args), + result: read_u256!(outs), + }, + "math_pow" => MathPow { + a: read_u256!(args), + b: read_u256!(args), + result: read_u256!(outs), + }, + "math_add_mod" => MathAddMod { + a: read_u256!(args), + b: read_u256!(args), + c: read_u256!(args), + result: read_u256!(outs), + }, + "math_mul_mod" => MathMulMod { + a: read_u256!(args), + b: read_u256!(args), + c: read_u256!(args), + result: read_u256!(outs), + }, "msg_reentrant" => MsgReentrant { reentrant: read_u32!(outs) != 0, }, @@ -313,7 +352,7 @@ impl TraceFrame { "tx_origin" => TxOrigin { origin: read_address!(outs), }, - "memory_grow" => PayForMemoryGrow { + "pay_for_memory_grow" => PayForMemoryGrow { pages: read_u16!(args), }, "call_contract" => CallContract { @@ -345,17 +384,17 @@ impl TraceFrame { endowment: read_u256!(args), code: read_data!(args), address: read_address!(outs), - revert_data_len: read_usize!(outs), + revert_data_len: read_u32!(outs), }, "create2" => Create2 { endowment: read_u256!(args), salt: read_b256!(args), code: read_data!(args), address: read_address!(outs), - revert_data_len: read_usize!(outs), + revert_data_len: read_u32!(outs), }, "emit_log" => EmitLog { - topics: read_usize!(args), + topics: read_u32!(args), data: read_data!(args), }, "read_return_data" => ReadReturnData { @@ -364,7 +403,7 @@ impl TraceFrame { data: read_data!(outs), }, "return_data_size" => ReturnDataSize { - size: read_usize!(outs), + size: read_u32!(outs), }, "console_log_text" => ConsoleLogText { text: read_data!(args), @@ -410,25 +449,42 @@ pub enum HostioKind { WriteResult { result: Box<[u8]>, }, + ExitEarly { + status: u32, + }, StorageLoadBytes32 { key: B256, value: B256, }, - StorageStoreBytes32 { + StorageCacheBytes32 { key: B256, value: B256, }, - StorageCacheBytes32 { - key: FixedBytes<32>, - value: FixedBytes<32>, - }, StorageFlushCache { clear: u8, }, + TransientLoadBytes32 { + key: B256, + value: B256, + }, + TransientStoreBytes32 { + key: B256, + value: B256, + }, AccountBalance { address: Address, balance: U256, }, + AccountCode { + address: Address, + offset: u32, + size: u32, + code: Box<[u8]>, + }, + AccountCodeSize { + address: Address, + size: u32, + }, AccountCodehash { address: Address, codehash: B256, @@ -463,6 +519,33 @@ pub enum HostioKind { PayForMemoryGrow { pages: u16, }, + MathDiv { + a: U256, + b: U256, + result: U256, + }, + MathMod { + a: U256, + b: U256, + result: U256, + }, + MathPow { + a: U256, + b: U256, + result: U256, + }, + MathAddMod { + a: U256, + b: U256, + c: U256, + result: U256, + }, + MathMulMod { + a: U256, + b: U256, + c: U256, + result: U256, + }, MsgReentrant { reentrant: bool, }, @@ -520,18 +603,18 @@ pub enum HostioKind { code: Box<[u8]>, endowment: U256, address: Address, - revert_data_len: usize, + revert_data_len: u32, }, Create2 { code: Box<[u8]>, endowment: U256, salt: B256, address: Address, - revert_data_len: usize, + revert_data_len: u32, }, EmitLog { data: Box<[u8]>, - topics: usize, + topics: u32, }, ReadReturnData { offset: u32, @@ -539,7 +622,7 @@ pub enum HostioKind { data: Box<[u8]>, }, ReturnDataSize { - size: usize, + size: u32, }, } @@ -583,7 +666,7 @@ impl FrameReader { let kind = hostio.kind; let name = kind.name(); match name { - "memory_grow" | "user_entrypoint" | "user_returned" => continue, + "pay_for_memory_grow" | "user_entrypoint" | "user_returned" => continue, _ => { detected(self, expected); println!("However, onchain there's a call to {name}. Are you sure this the right contract?\n"); diff --git a/util/src/text.rs b/util/src/text.rs index c4dd11c..c4a7e3f 100644 --- a/util/src/text.rs +++ b/util/src/text.rs @@ -5,6 +5,7 @@ use eyre::Result; pub fn decode0x>(text: T) -> Result> { let text = text.as_ref(); + let text = text.trim(); let text = text.strip_prefix("0x").unwrap_or(text); Ok(hex::decode(text)?) }