diff --git a/Cargo.lock b/Cargo.lock index 45634ff..bc9b5c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,17 +109,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -269,9 +258,39 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "casper-client" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb4938b81a6ecd44628be6b87a43cfb70bb10a5abe549a2dd22b544e980f5bc9" +dependencies = [ + "base16", + "base64 0.22.1", + "bytes", + "casper-types", + "flate2", + "hex-buffer-serde 0.4.0", + "humantime", + "itertools 0.12.1", + "jsonrpc-lite", + "num-traits", + "once_cell", + "rand 0.8.5", + "reqwest", + "schemars 0.8.22", + "serde", + "serde-map-to-array", + "serde_json", + "tar", + "thiserror", + "tokio", + "toml 0.8.23", + "uint", +] [[package]] name = "casper-contract" @@ -285,9 +304,9 @@ dependencies = [ [[package]] name = "casper-contract-schema" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb2ec188665cd95c1c0a7af76873525b9831fe94b80d48a852968a3a7b346bcf" +checksum = "3895e20cb937a9bac83d8d8d6cade52d38ad1a1bb50e226e4eee9e0489586efa" dependencies = [ "casper-types", "schemars 0.9.0", @@ -295,6 +314,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "casper-eip-712" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02432d99d7db610c41cf2d8f503716809f41ac12da838451d506830d09a56fb3" +dependencies = [ + "sha3", +] + [[package]] name = "casper-engine-test-support" version = "8.1.1" @@ -455,9 +483,9 @@ dependencies = [ [[package]] name = "casper-types" -version = "6.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d67ed1e85b723e2565fa976c10b49085863f0429b7fe5a18776b69fd15d9240" +checksum = "f9e04cda524136cc94ca5d8a1eff0b33de4eb98914344c736abda370321e7e87" dependencies = [ "base16", "base64 0.13.1", @@ -576,7 +604,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -601,15 +629,6 @@ dependencies = [ "strsim", ] -[[package]] -name = "clap_complete" -version = "4.5.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d9501bd3f5f09f7bbee01da9a511073ed30a80cd7a509f1214bb74eadea71ad" -dependencies = [ - "clap", -] - [[package]] name = "clap_derive" version = "4.5.45" @@ -654,9 +673,12 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "convert_case" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "core-foundation" @@ -1080,6 +1102,23 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "futures-sink" version = "0.3.31" @@ -1099,9 +1138,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -1169,7 +1213,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.11.0", + "indexmap 2.14.0", "slab", "tokio", "tokio-util", @@ -1184,9 +1228,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -1528,12 +1572,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.17.1", ] [[package]] @@ -1545,17 +1589,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -1607,6 +1640,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" @@ -1645,6 +1687,15 @@ dependencies = [ "sha2", ] +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -1662,9 +1713,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libm" @@ -1779,13 +1830,13 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.4" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1911,9 +1962,9 @@ dependencies = [ [[package]] name = "odra" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41a118066c4e2e49c236e6c9c93c2329ec500cde476cbfaa9ef2445ff4bc3dc" +checksum = "f2f4d14dccb0ddcf8fe1808caef3fe2e7bb93a786d5bd3967b2c67a0a7af6c2f" dependencies = [ "odra-casper-wasm-env", "odra-core", @@ -1923,52 +1974,19 @@ dependencies = [ [[package]] name = "odra-build" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e146cd60b82c73368f2a3f133e621322be0a296c4f9fa9fd0a9670ea9dfaa53" +checksum = "4c5b91a79fa9a660b3a1237a719dd94e12813743f064ce129055b0c14bf89768" dependencies = [ "serde", "serde_json", ] -[[package]] -name = "odra-casper-client" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da35c66b640765f4740bf03be9e6e209e68ec9960d92c65c261e8c0f563ff1d1" -dependencies = [ - "async-trait", - "base16", - "base64 0.22.1", - "bytes", - "casper-types", - "clap", - "clap_complete", - "flate2", - "hex-buffer-serde 0.4.0", - "humantime", - "itertools 0.12.1", - "jsonrpc-lite", - "num-traits", - "once_cell", - "rand 0.8.5", - "reqwest", - "schemars 0.8.22", - "serde", - "serde-map-to-array", - "serde_json", - "tar", - "thiserror", - "tokio", - "toml 0.8.23", - "uint", -] - [[package]] name = "odra-casper-livenet-env" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7bac3dd90f1c6d4acd7ec5eecb5f8fb95cdcd6891b6533f5195904f09d784f" +checksum = "95469f8db21e6d91ff646562a760493aeb965a0156ea23857080adf5df282285" dependencies = [ "anyhow", "blake2 0.10.6", @@ -1983,30 +2001,33 @@ dependencies = [ [[package]] name = "odra-casper-rpc-client" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04702bcc41974e328a59656a727ef892eb68c245e1e7772dc5213a56180e4854" +checksum = "039a08f9e3815ffde428fc7d66ac9e47f8da87ebb0ba3264bb6cbadd25f3053c" dependencies = [ "base16", + "bytes", + "casper-client", "casper-types", "dotenv", - "itertools 0.10.5", - "odra-casper-client", + "futures-util", + "itertools 0.14.0", "odra-core", "prettycli", "project-root", - "rand 0.8.5", + "rand 0.9.2", + "reqwest", "serde_json", "thiserror", "tokio", - "toml 0.8.23", + "toml 0.9.12+spec-1.1.0", ] [[package]] name = "odra-casper-test-vm" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a02799c69533e98bfc7206b310f96afc962639755769eb8af399e9ee9096ecb" +checksum = "218a93ca6d729beb9a898b31d31f2bda29486453e6f4592fbabd8cd23cd5777a" dependencies = [ "casper-contract", "casper-engine-test-support", @@ -2017,9 +2038,9 @@ dependencies = [ [[package]] name = "odra-casper-wasm-env" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f90f926a273e44c8d11d64926866f0f0392ef88f536a7162573a68ec4527e1" +checksum = "67de2cddccb900998696a13967c59f2809b3a6b24b45d2ee6731a05de795c32c" dependencies = [ "casper-contract", "ink_allocator", @@ -2029,9 +2050,9 @@ dependencies = [ [[package]] name = "odra-cli" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe5442073d9619ec1f1ee69c40276d1c48573b01cb864127a6d9e31eb30572c" +checksum = "cfb07990e6615dd393d970b8bc35304ff46c570e646dc83607f7f7de0dc4cc96" dependencies = [ "anyhow", "chrono", @@ -2047,14 +2068,14 @@ dependencies = [ "serde_derive", "serde_json", "thiserror", - "toml 0.8.23", + "toml 0.9.12+spec-1.1.0", ] [[package]] name = "odra-core" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e65795a7e930891be6c08fb2aaf837c7ad6f17c01d558dc972734a13a9989a" +checksum = "940fef67dfa971d79fba7344844c9fe7c750e97258f08277797aa13a3fe7c439" dependencies = [ "anyhow", "casper-event-standard", @@ -2068,54 +2089,49 @@ dependencies = [ [[package]] name = "odra-macros" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ad4ea9f166bd6829abb3ef1e750056c8c42732d6b45ff1468e6b03e5ce3420" +checksum = "2e4d87eb0bc0d286c227a245c9c47fbca5c37e396a47c6ed6deb78eefe005259" dependencies = [ - "convert_case 0.5.0", + "convert_case 0.6.0", "derive-try-from-ref", - "derive_more", - "itertools 0.12.1", + "itertools 0.14.0", "proc-macro2", "quote", - "static_assertions", "syn 2.0.106", "syn_derive", ] [[package]] name = "odra-modules" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc5527060b7e564034c71afc307c3c70c57bbdfbd502ab833fd997968eff466" +checksum = "64ea5b0e8d4c36287a86a615db423f7ccaa2f870a11ce3bc6602986cfe23f912" dependencies = [ - "base16", "base64 0.22.1", + "casper-eip-712", "odra", "odra-build", - "serde", - "serde-json-wasm", - "serde_json", ] [[package]] name = "odra-schema" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e3a0408fb8d6355c7f688b1ee1e52e5b8531d3060ed333f1af80306487e6b3" +checksum = "42fcd0da8f46722a2204b4aa0a1adc52206c9d5ca2e8d8346d701b1dcb12c0bc" dependencies = [ "casper-contract-schema", "casper-types", - "convert_case 0.5.0", + "convert_case 0.6.0", "num-traits", "odra-core", ] [[package]] name = "odra-test" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8937cb8911c1560da620409ca2194c59ab72b980e9678b54ebcbfcd8918cc2" +checksum = "b57bce89f1e1ef65b84e0e633a3bdfe38370ed6e99926ce30dcb110cda469557" dependencies = [ "odra-casper-test-vm", "odra-core", @@ -2124,9 +2140,9 @@ dependencies = [ [[package]] name = "odra-vm" -version = "2.4.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48adbdf9f9f260919a97adaa23cd4aeee0206a560f3693a544d66d34679a24cf" +checksum = "c06d3dd16611a3901953c9c9e01f39c03d9ef6e11dbce9bce444fa147b895988" dependencies = [ "anyhow", "backtrace", @@ -2323,6 +2339,27 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", +] + [[package]] name = "proc-macro2" version = "1.0.101" @@ -2535,6 +2572,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-core", + "futures-util", "h2", "http", "http-body", @@ -2556,12 +2594,14 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-native-tls", + "tokio-util", "tower", "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", ] @@ -2783,10 +2823,11 @@ checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -2818,11 +2859,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -2846,7 +2896,7 @@ version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.14.0", "itoa", "memchr", "ryu", @@ -2862,6 +2912,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2885,6 +2944,16 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2915,12 +2984,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -3030,11 +3099,11 @@ dependencies = [ [[package]] name = "syn_derive" -version = "0.1.8" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +checksum = "cdb066a04799e45f5d582e8fc6ec8e6d6896040d00898eb4e6a835196815b219" dependencies = [ - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", "syn 2.0.106", @@ -3145,27 +3214,24 @@ dependencies = [ [[package]] name = "tokio" -version = "1.47.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "pin-project-lite", - "slab", "socket2", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -3221,11 +3287,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_edit 0.22.27", ] +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap 2.14.0", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.13", +] + [[package]] name = "toml_datetime" version = "0.6.11" @@ -3235,14 +3316,23 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ - "indexmap 2.11.0", - "toml_datetime", + "indexmap 2.14.0", + "toml_datetime 0.6.11", "winnow 0.5.40", ] @@ -3252,20 +3342,35 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.14.0", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_write", "winnow 0.7.13", ] +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.3", +] + [[package]] name = "toml_write" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tower" version = "0.5.2" @@ -3378,6 +3483,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + [[package]] name = "unicode-width" version = "0.2.1" @@ -3562,6 +3673,19 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wasmparser" version = "0.238.0" @@ -3569,7 +3693,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ad4ca2ecb86b79ea410cd970985665de1d05774b7107b214bc5852b1bcbad7" dependencies = [ "bitflags 2.9.4", - "indexmap 2.11.0", + "indexmap 2.14.0", "semver", ] @@ -3644,7 +3768,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", + "windows-link 0.1.3", "windows-result", "windows-strings", ] @@ -3677,13 +3801,19 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-registry" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows-result", "windows-strings", ] @@ -3694,7 +3824,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -3703,7 +3833,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -3733,6 +3863,15 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -3755,7 +3894,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -3880,6 +4019,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" + [[package]] name = "wit-bindgen" version = "0.45.0" diff --git a/Cargo.toml b/Cargo.toml index 63b8844..b831512 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,13 +7,13 @@ members = [ resolver = "2" [workspace.dependencies] -odra = { version = "2.4.0" } -odra-cli = { version = "2.4.0" } -odra-modules = { version = "2.4.0" } -odra-test = { version = "2.4.0" } -odra-build = { version = "2.4.0" } -odra-bdd = { version = "2.4.0" } -odra-casper-livenet-env = { version = "2.4.0" } +odra = { version = "2.8.1" } +odra-cli = { version = "2.8.1" } +odra-modules = { version = "2.8.1" } +odra-test = { version = "2.8.1" } +odra-build = { version = "2.8.1" } +odra-bdd = { version = "2.8.1" } +odra-casper-livenet-env = { version = "2.8.1" } [profile.release] codegen-units = 1 diff --git a/casper-name-cli/src/odra_cli.rs b/casper-name-cli/src/odra_cli.rs index 923d0d1..c1ba64c 100644 --- a/casper-name-cli/src/odra_cli.rs +++ b/casper-name-cli/src/odra_cli.rs @@ -6,6 +6,8 @@ use deploy::DeployScript; use odra_cli::OdraCli; use scenario::{CalculateSignature, CalculateTokenHash, RegisterTokenScenario, SetConfigScript, UpgradeReverseResolver, UpgradeNameToken}; +use crate::odra_cli::scenario::UpgradeRegistrar; + mod deploy; mod scenario; @@ -24,6 +26,7 @@ pub fn cli() { .scenario(CalculateSignature) .scenario(UpgradeReverseResolver) .scenario(UpgradeNameToken) + .scenario(UpgradeRegistrar) .build() .run(); } diff --git a/casper-name-cli/src/odra_cli/deploy.rs b/casper-name-cli/src/odra_cli/deploy.rs index 76c3745..ffbbd12 100644 --- a/casper-name-cli/src/odra_cli/deploy.rs +++ b/casper-name-cli/src/odra_cli/deploy.rs @@ -21,6 +21,7 @@ impl odra_cli::deploy::DeployScript for DeployScript { let token = NameToken::load_or_deploy_with_cfg( &env, + None, NameTokenInitArgs { name: "CSPR.name".to_string(), symbol: "NAME".to_string(), @@ -33,6 +34,7 @@ impl odra_cli::deploy::DeployScript for DeployScript { let _resolver = DefaultResolver::load_or_deploy_with_cfg( &env, + None, DefaultResolverInitArgs { name_token: token.address(), }, @@ -43,6 +45,7 @@ impl odra_cli::deploy::DeployScript for DeployScript { let registrar = Registrar::load_or_deploy_with_cfg( &env, + None, RegistrarInitArgs { name_token: token.address(), }, @@ -53,6 +56,7 @@ impl odra_cli::deploy::DeployScript for DeployScript { let _controller = Controller::load_or_deploy_with_cfg( &env, + None, ControllerInitArgs { registrar: registrar.address(), treasury: admin, @@ -65,6 +69,7 @@ impl odra_cli::deploy::DeployScript for DeployScript { let _reverse_resolver = ReverseResolver::load_or_deploy_with_cfg( &env, + None, ReverseResolverInitArgs { name_token: token.address(), }, diff --git a/casper-name-cli/src/odra_cli/scenario.rs b/casper-name-cli/src/odra_cli/scenario.rs index d2ced95..cadcfa1 100644 --- a/casper-name-cli/src/odra_cli/scenario.rs +++ b/casper-name-cli/src/odra_cli/scenario.rs @@ -264,16 +264,50 @@ impl Scenario for UpgradeNameToken { .unwrap(); env.set_gas(cspr!(400)); - let _result = NameToken::try_upgrade_with_cfg( + NameToken::try_upgrade_with_cfg( env, name_token_addr, NoArgs, UpgradeConfig { - package_named_key: String::from("NameToken_contract_package"), + package_named_key: NameToken::ident(), + force_create_upgrade_group: false, + allow_key_override: true, + }, + )?; + + Ok(()) + } +} + +pub struct UpgradeRegistrar; + +impl ScenarioMetadata for UpgradeRegistrar { + const NAME: &'static str = "upgrade-registrar"; + const DESCRIPTION: &'static str = "Upgrade the Registrar contract."; +} + +impl Scenario for UpgradeRegistrar { + fn run( + &self, + env: &HostEnv, + container: &DeployedContractsContainer, + _args: Args, + ) -> Result<(), ScenarioError> { + let registrar_addr = container + .address_by_name(&Registrar::ident()) + .unwrap(); + + env.set_gas(cspr!(400)); + Registrar::try_upgrade_with_cfg( + env, + registrar_addr, + NoArgs, + UpgradeConfig { + package_named_key: Registrar::ident(), force_create_upgrade_group: true, allow_key_override: true, }, - ); + )?; Ok(()) } diff --git a/casper-name-contracts/src/contracts/name_token.rs b/casper-name-contracts/src/contracts/name_token.rs index 3432838..48f87f0 100644 --- a/casper-name-contracts/src/contracts/name_token.rs +++ b/casper-name-contracts/src/contracts/name_token.rs @@ -110,11 +110,7 @@ impl NameToken { self.revert(NameTokenError::ExpiredTokenTransfer); } - let owner = self - .token - .owner_of(token_id) - .unwrap_or_revert_with(self, Cep95Error::ValueNotSet); - self.token.raw_transfer_from(owner, recipient, token_id); + let owner = self.token.raw_transfer(recipient, token_id); // if called by an operator if caller != owner { self.cleanup(token_id); diff --git a/casper-name-contracts/src/contracts/registrar.rs b/casper-name-contracts/src/contracts/registrar.rs index 57a0511..2ba6339 100644 --- a/casper-name-contracts/src/contracts/registrar.rs +++ b/casper-name-contracts/src/contracts/registrar.rs @@ -265,8 +265,11 @@ impl Registrar { fn prolong(&mut self, tokens: Vec) { let block_time = self.env().get_block_time(); for token in tokens { + // The offchain component may supply microsecond timestamps. + let token_expiration = + utils::trim_microseconds_to_milliseconds_if_needed(token.token_expiration); // verify the new expiration date is in the future - self.assert_token_expires_in_future(token.token_expiration, block_time); + self.assert_token_expires_in_future(token_expiration, block_time); // Compute token hash. let token_id = token.token_id; // get the token metadata @@ -274,7 +277,7 @@ impl Registrar { // check if the time for the renewal does not elapsed let expiration = metadata.expiration(); self.assert_in_renewal_period(expiration); - metadata.set_expiration(token.token_expiration); + metadata.set_expiration(token_expiration); self.name_token .set_token_metadata(token_id, metadata.to_vec()); @@ -284,13 +287,16 @@ impl Registrar { fn register(&mut self, names: Vec) { let block_time = self.env().get_block_time(); for info in names { - self.assert_token_expires_in_future(info.token_expiration, block_time); + // The offchain component may supply microsecond timestamps. + let token_expiration = + utils::trim_microseconds_to_milliseconds_if_needed(info.token_expiration); + self.assert_token_expires_in_future(token_expiration, block_time); if !utils::is_label_valid(&info.label) { self.revert(RegistrarError::TokenNameIsNotValid); } let metadata = NameTokenMetadata::with_resolver( &info.label, - info.token_expiration, + token_expiration, &info.asset_uri, self.name_token.get_default_resolver(), ); @@ -510,6 +516,90 @@ mod tests { ctx.expect_name_is_registered(alice, TOKEN_NAME); } + #[test] + fn register_with_microsecond_timestamps_stores_milliseconds() { + let mut ctx = TestContext::install_and_setup(); + let (admin, alice) = (ctx.admin, ctx.alice); + + // When Admin registers with microsecond timestamps. + let token_expiration = ctx.token_expiration_time(); + let voucher_expiration = ctx.voucher_expiration_time(); + ctx.try_name_register( + admin, + alice, + TOKEN_NAME, + token_expiration * 1000, + voucher_expiration * 1000, + ) + .unwrap(); + + // Then the token is minted with a millisecond expiration. + ctx.expect_name_is_registered(alice, TOKEN_NAME); + + // And the token is valid and not burned prematurely. + assert!(ctx.token.is_token_valid(generate_token_id(TOKEN_NAME))); + ctx.with_name_expired(TOKEN_NAME); + assert_eq!(ctx.token.balance_of(alice), U256::one()); + } + + #[test] + fn renew_with_microsecond_timestamps_stores_milliseconds() { + let mut ctx = TestContext::install_and_setup(); + let (admin, alice) = (ctx.admin, ctx.alice); + + // Given Alice has a token. + ctx.with_name_registered(admin, alice, TOKEN_NAME); + + // When Admin renews with microsecond timestamps. + let token_expiration = INIT_TIME + 2 * TOKEN_EXPIRATION; + let voucher_expiration = INIT_TIME + TOKEN_EXPIRATION + GRACE_PERIOD; + let tokens = vec![TokenRenewalInfo::new( + generate_token_id(TOKEN_NAME), + token_expiration * 1000, + )]; + let voucher = RenewalVoucher::new(tokens, voucher_expiration * 1000); + ctx.advance_block_time(TOKEN_EXPIRATION + GRACE_PERIOD - 1); + ctx.set_caller(admin); + ctx.registrar.controller_prolong(voucher); + + // Then the token expiration is stored in milliseconds. + let metadata = ctx.token.token_metadata(generate_token_id(TOKEN_NAME)); + let expected = NameTokenMetadata::with_resolver( + TOKEN_NAME, + token_expiration, + "", + ctx.default_resolver.address(), + ); + assert_eq!(metadata, expected.to_vec()); + } + + #[test] + fn legacy_microsecond_metadata_expires_correctly() { + let mut ctx = TestContext::install_and_setup(); + let (admin, alice) = (ctx.admin, ctx.alice); + + // Given Alice has a token with a legacy microsecond expiration stored on-chain. + ctx.with_name_registered(admin, alice, TOKEN_NAME); + let token_id = generate_token_id(TOKEN_NAME); + let expiration = ctx.token_expiration_time(); + ctx.set_caller(admin); + ctx.token.set_token_metadata( + token_id, + vec![ + ("asset_uri".to_string(), String::new()), + ("expiration".to_string(), (expiration * 1000).to_string()), + ("name".to_string(), TOKEN_NAME.to_string()), + ], + ); + + // When the grace period is over. + ctx.advance_block_time(TOKEN_EXPIRATION + GRACE_PERIOD + PENDING_DELETE_PERIOD + 1); + + // Then the token can be expired despite the microsecond value. + ctx.with_name_expired(TOKEN_NAME); + assert_eq!(ctx.token.balance_of(alice), U256::zero()); + } + #[test] fn register_the_same_name_before_expiration() { let mut ctx = TestContext::install_and_setup(); diff --git a/casper-name-contracts/src/contracts/utils.rs b/casper-name-contracts/src/contracts/utils.rs index 947f8f2..6f01d56 100644 --- a/casper-name-contracts/src/contracts/utils.rs +++ b/casper-name-contracts/src/contracts/utils.rs @@ -73,6 +73,23 @@ pub fn is_label_valid(label: &str) -> bool { is_valid_dns_label(label) && label != "cspr" && !label.contains('.') } +/// Convert microsecond timestamps to milliseconds if they exceed the threshold. +/// +/// The offchain component may supply timestamps in microseconds instead of +/// milliseconds. This helper is applied at every timestamp entry point +/// ([NameTokenMetadata](crate::data_structures::NameTokenMetadata) construction +/// and deserialization, voucher expiration reads, and registrar inputs) so all +/// time comparisons work in milliseconds, matching the block time. +pub fn trim_microseconds_to_milliseconds_if_needed(expiration: u64) -> u64 { + // Values above ~10^14 are microseconds: 10^14 ms is the year 5138, + // while any microsecond timestamp after 1973 exceeds it. + if expiration > 99_999_999_999_999 { + expiration / 1000 + } else { + expiration + } +} + #[cfg(test)] mod t { #[test] @@ -141,4 +158,10 @@ mod t { assert!(!super::is_label_valid("invalid.label")); assert!(super::is_label_valid("valid123")); } + + #[test] + fn test_trim_microseconds_to_milliseconds_if_needed() { + assert_eq!(super::trim_microseconds_to_milliseconds_if_needed(100_000_000_000_000), 100_000_000_000); + assert_eq!(super::trim_microseconds_to_milliseconds_if_needed(99_999_999_999_999), 99_999_999_999_999); + } } diff --git a/casper-name-contracts/src/data_structures.rs b/casper-name-contracts/src/data_structures.rs index e0ae578..8bdb210 100644 --- a/casper-name-contracts/src/data_structures.rs +++ b/casper-name-contracts/src/data_structures.rs @@ -4,6 +4,8 @@ use odra::{ }; use serde::{Deserialize, Serialize}; +use crate::contracts::utils::trim_microseconds_to_milliseconds_if_needed; + /// Errors that can occur while working with name tokens. #[odra::odra_error] #[derive(Debug)] @@ -31,7 +33,7 @@ impl NameTokenMetadata { pub fn with_resolver(name: &str, expiration: u64, asset_uri: &str, resolver: Address) -> Self { Self { name: String::from(name), - expiration, + expiration: trim_microseconds_to_milliseconds_if_needed(expiration), resolver: Some(resolver), asset_uri: String::from(asset_uri), } @@ -40,7 +42,7 @@ impl NameTokenMetadata { pub fn with_no_resolver(name: &str, expiration: u64, asset_uri: &str) -> Self { Self { name: String::from(name), - expiration, + expiration: trim_microseconds_to_milliseconds_if_needed(expiration), resolver: None, asset_uri: String::from(asset_uri), } @@ -78,7 +80,7 @@ impl NameTokenMetadata { } pub fn set_expiration(&mut self, expiration: u64) { - self.expiration = expiration; + self.expiration = trim_microseconds_to_milliseconds_if_needed(expiration); } } @@ -86,7 +88,10 @@ impl TryFrom for NameTokenMetadata { type Error = NameTokenError; fn try_from(value: String) -> Result { - serde_json_wasm::from_str(&value).map_err(|_| NameTokenError::DeserializationError) + let mut metadata: NameTokenMetadata = + serde_json_wasm::from_str(&value).map_err(|_| NameTokenError::DeserializationError)?; + metadata.expiration = trim_microseconds_to_milliseconds_if_needed(metadata.expiration); + Ok(metadata) } } @@ -107,6 +112,7 @@ impl TryFrom> for NameTokenMetadata { .ok_or(NameTokenError::DeserializationError)? .1 .parse() + .map(trim_microseconds_to_milliseconds_if_needed) .map_err(|_| NameTokenError::DeserializationError)?; let resolver = value @@ -321,18 +327,21 @@ impl Payment for SecondarySaleVoucher { } pub trait ExpirableVoucher { + /// Returns the voucher expiration time in milliseconds. fn expiration_time(&self) -> u64; } +// NOTE: Vouchers are signature-verified over their raw bytes, so the stored +// `voucher_expiration` must stay untouched; normalization happens on read. impl ExpirableVoucher for TokenizationVoucher { fn expiration_time(&self) -> u64 { - self.voucher_expiration + trim_microseconds_to_milliseconds_if_needed(self.voucher_expiration) } } impl ExpirableVoucher for RenewalVoucher { fn expiration_time(&self) -> u64 { - self.voucher_expiration + trim_microseconds_to_milliseconds_if_needed(self.voucher_expiration) } } @@ -382,4 +391,56 @@ mod tests { let deserialized: NameTokenMetadata = expected.try_into().unwrap(); assert_eq!(metadata, deserialized); } + + #[test] + fn test_metadata_normalizes_microsecond_expiration() { + // 2024-01-01T10:00:00Z in microseconds. + let micros: u64 = 1_704_103_200_000_000; + let millis: u64 = 1_704_103_200_000; + + // Constructors. + let metadata = NameTokenMetadata::with_no_resolver("test-label", micros, ""); + assert_eq!(metadata.expiration(), millis); + let resolver = + Address::new("hash-7ba9daac84bebee8111c186588f21ebca35550b6cf1244e71768bd871938be6a") + .unwrap(); + let metadata = NameTokenMetadata::with_resolver("test-label", micros, "", resolver); + assert_eq!(metadata.expiration(), millis); + + // Setter. + let mut metadata = NameTokenMetadata::with_no_resolver("test-label", millis, ""); + metadata.set_expiration(micros); + assert_eq!(metadata.expiration(), millis); + + // Deserialization from JSON (legacy on-chain data). + let json = format!( + r#"{{"name":"test-label","expiration":{},"resolver":null,"asset_uri":""}}"#, + micros + ); + let metadata: NameTokenMetadata = json.try_into().unwrap(); + assert_eq!(metadata.expiration(), millis); + + // Deserialization from key-value pairs (legacy on-chain data). + let pairs = vec![ + ("name".to_string(), "test-label".to_string()), + ("expiration".to_string(), micros.to_string()), + ]; + let metadata: NameTokenMetadata = pairs.try_into().unwrap(); + assert_eq!(metadata.expiration(), millis); + } + + #[test] + fn test_voucher_expiration_time_normalizes_microseconds() { + let micros: u64 = 1_704_103_200_000_000; + let millis: u64 = 1_704_103_200_000; + + let voucher = TokenizationVoucher::new(vec![], micros); + assert_eq!(voucher.expiration_time(), millis); + // The stored value stays untouched, as it is part of the signed bytes. + assert_eq!(voucher.voucher_expiration, micros); + + let voucher = RenewalVoucher::new(vec![], micros); + assert_eq!(voucher.expiration_time(), millis); + assert_eq!(voucher.voucher_expiration, micros); + } } diff --git a/rust-toolchain b/rust-toolchain index 09a243d..a0f4404 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2025-01-01 +nightly-2026-01-01 \ No newline at end of file