diff --git a/Cargo.lock b/Cargo.lock index 932c5f0c70..279536ae35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,33 +93,13 @@ dependencies = [ "alloc-no-stdlib", ] -[[package]] -name = "andrew" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" -dependencies = [ - "bitflags 1.3.2", - "line_drawing", - "rusttype 0.7.9", - "walkdir", - "xdg", - "xml-rs", -] - -[[package]] -name = "android_glue" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" - [[package]] name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -178,41 +158,197 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] -name = "approx" -version = "0.3.2" +name = "aquamarine" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a941c39708478e8eea39243b5983f1c42d2717b3620ee91f4a52115fd02ac43f" +dependencies = [ + "itertools 0.9.0", + "proc-macro-error", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 1.0.109", +] + +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-crypto-primitives" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-relations", + "ark-serialize", + "ark-snark", + "ark-std", + "blake2 0.10.6", + "derivative", + "digest 0.10.6", + "sha2", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", "num-traits", + "zeroize", ] [[package]] -name = "approx" -version = "0.5.1" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.6", + "itertools 0.10.5", + "num-bigint", "num-traits", + "paste", + "rustc_version", + "zeroize", ] [[package]] -name = "aquamarine" -version = "0.1.12" +name = "ark-ff-asm" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941c39708478e8eea39243b5983f1c42d2717b3620ee91f4a52115fd02ac43f" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "itertools 0.9.0", - "proc-macro-error", - "proc-macro2 1.0.56", - "quote 1.0.26", + "quote 1.0.35", "syn 1.0.109", ] [[package]] -name = "arc-swap" -version = "1.6.0" +name = "ark-ff-macros" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 1.0.109", +] + +[[package]] +name = "ark-groth16" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20ceafa83848c3e390f1cbf124bc3193b3e639b3f02009e0e290809a501b95fc" +dependencies = [ + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-relations", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-relations" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0" +dependencies = [ + "ark-ff", + "ark-std", + "tracing", + "tracing-subscriber 0.2.25", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.6", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 1.0.109", +] + +[[package]] +name = "ark-snark" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63" +dependencies = [ + "ark-ff", + "ark-relations", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] [[package]] name = "assert-json-diff" @@ -250,9 +386,9 @@ version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -272,7 +408,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi 0.1.19", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -297,6 +433,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "autotools" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8da1805e028a172334c3b680f93e71126f2327622faef2ec3d893c0a4ad77" +dependencies = [ + "cc", +] + [[package]] name = "backtrace" version = "0.3.67" @@ -374,9 +519,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "blake2" @@ -389,6 +534,15 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "blake2b" version = "0.8.0" @@ -397,12 +551,6 @@ dependencies = [ "casper-types", ] -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - [[package]] name = "block-buffer" version = "0.10.4" @@ -412,6 +560,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bonsai-sdk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e0f26687ed447c77b1a40a3665bf88e8327b6de65a74f521544bd225982f589" +dependencies = [ + "reqwest", + "risc0-groth16", + "serde", + "thiserror", +] + [[package]] name = "brotli" version = "3.3.4" @@ -462,9 +622,23 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" +dependencies = [ + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", +] [[package]] name = "byteorder" @@ -477,6 +651,9 @@ name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] [[package]] name = "call-contract" @@ -486,17 +663,6 @@ dependencies = [ "casper-types", ] -[[package]] -name = "calloop" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aa2097be53a00de9e8fc349fea6d76221f398f5c4fa550d420669906962d160" -dependencies = [ - "mio 0.6.23", - "mio-extras", - "nix", -] - [[package]] name = "casper-contract" version = "4.0.0" @@ -509,7 +675,7 @@ dependencies = [ [[package]] name = "casper-engine-test-support" -version = "7.0.0" +version = "7.0.1" dependencies = [ "casper-execution-engine", "casper-hashing", @@ -563,7 +729,7 @@ dependencies = [ [[package]] name = "casper-execution-engine" -version = "7.0.0" +version = "7.0.1" dependencies = [ "anyhow", "assert_matches", @@ -582,12 +748,13 @@ dependencies = [ "hostname", "humantime", "itertools 0.10.5", + "kairos-risc0-types", "libc", "linked-hash-map", "lmdb-rkv", "log", "num", - "num-derive", + "num-derive 0.3.3", "num-rational", "num-traits", "num_cpus", @@ -595,6 +762,7 @@ dependencies = [ "proptest", "rand", "rand_chacha", + "risc0-zkvm", "schemars", "serde", "serde_bytes", @@ -615,7 +783,7 @@ dependencies = [ "assert_matches", "base16", "bincode", - "blake2", + "blake2 0.9.2", "casper-types", "criterion", "datasize", @@ -653,7 +821,7 @@ dependencies = [ [[package]] name = "casper-node" -version = "1.5.5" +version = "1.5.6" dependencies = [ "ansi_term", "anyhow", @@ -691,7 +859,7 @@ dependencies = [ "lmdb-rkv", "log", "num", - "num-derive", + "num-derive 0.3.3", "num-rational", "num-traits", "num_cpus", @@ -736,7 +904,7 @@ dependencies = [ "tower", "tracing", "tracing-futures", - "tracing-subscriber", + "tracing-subscriber 0.3.17", "uint", "uuid", "vergen", @@ -752,7 +920,7 @@ dependencies = [ "base64 0.13.1", "bincode", "bitflags 1.3.2", - "blake2", + "blake2 0.9.2", "criterion", "datasize", "derp", @@ -763,7 +931,7 @@ dependencies = [ "humantime", "k256", "num", - "num-derive", + "num-derive 0.3.3", "num-integer", "num-rational", "num-traits", @@ -784,7 +952,7 @@ dependencies = [ "tempfile", "thiserror", "uint", - "untrusted", + "untrusted 0.7.1", "version-sync", ] @@ -887,15 +1055,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cgl" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" -dependencies = [ - "libc", -] - [[package]] name = "clap" version = "2.34.0" @@ -962,8 +1121,8 @@ checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -974,9 +1133,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -994,15 +1153,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "clru" version = "0.6.1" @@ -1018,21 +1168,6 @@ dependencies = [ "cc", ] -[[package]] -name = "cocoa" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29f7768b2d1be17b96158e3285951d366b40211320fb30826a76cb7a0da6400" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation 0.6.4", - "core-graphics 0.17.3", - "foreign-types", - "libc", - "objc", -] - [[package]] name = "colorchoice" version = "1.0.0" @@ -1075,91 +1210,22 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" -[[package]] -name = "core-foundation" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -dependencies = [ - "core-foundation-sys 0.6.2", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys 0.7.0", - "libc", -] - [[package]] name = "core-foundation" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "core-foundation-sys 0.8.4", + "core-foundation-sys", "libc", ] -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" - -[[package]] -name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - [[package]] name = "core-foundation-sys" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "core-graphics" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.6.4", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.7.0", - "foreign-types", - "libc", -] - -[[package]] -name = "core-video-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" -dependencies = [ - "cfg-if 0.1.10", - "core-foundation-sys 0.7.0", - "core-graphics 0.19.2", - "libc", - "objc", -] - [[package]] name = "counter-installer" version = "0.1.0" @@ -1456,16 +1522,10 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ - "quote 1.0.26", + "quote 1.0.35", "syn 1.0.109", ] -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - [[package]] name = "curve25519-dalek" version = "4.0.0" @@ -1489,9 +1549,9 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -1519,8 +1579,8 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b0415ec81945214410892a00d4b5dd4566f6263205184248e018a3fe384a61e" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -1542,6 +1602,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -1549,8 +1620,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "rustc_version", "syn 1.0.109", ] @@ -1561,7 +1632,7 @@ version = "0.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9b84cfd9b6fa437e498215e5625e9e3ae3bf9bb54d623028a181c40820db169" dependencies = [ - "untrusted", + "untrusted 0.7.1", ] [[package]] @@ -1641,25 +1712,10 @@ dependencies = [ ] [[package]] -name = "dispatch" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" - -[[package]] -name = "dlib" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76" +name = "do-nothing" +version = "0.1.0" dependencies = [ - "libloading 0.6.7", -] - -[[package]] -name = "do-nothing" -version = "0.1.0" -dependencies = [ - "casper-contract", + "casper-contract", ] [[package]] @@ -1748,8 +1804,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "079044df30bb07de7d846d41a184c4b00e66ebdac93ee459253474f3a47e50ae" dependencies = [ "enum-ordinalize", - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -1941,6 +1997,12 @@ dependencies = [ "serde", ] +[[package]] +name = "elf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" + [[package]] name = "elliptic-curve" version = "0.13.5" @@ -1999,8 +2061,8 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e94aa31f7c0dc764f57896dc615ddd76fc13b0d5dca7eb6cc5e018a5a09ec06" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -2012,8 +2074,8 @@ checksum = "a62bb1df8b45ecb7ffa78dca1c17a438fb193eb083db0b1b494d2a61bcb5096a" dependencies = [ "num-bigint", "num-traits", - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "rustc_version", "syn 1.0.109", ] @@ -2085,12 +2147,6 @@ dependencies = [ "instant", ] -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - [[package]] name = "faucet" version = "0.1.0" @@ -2130,7 +2186,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12d741e2415d4e2e5bd1c1d00409d1a8865a57892c2d689b504365655d237d43" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2153,6 +2209,12 @@ dependencies = [ "casper-types", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.26" @@ -2193,17 +2255,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "freetype-sys" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" -dependencies = [ - "cmake", - "libc", - "pkg-config", -] - [[package]] name = "fs2" version = "0.4.3" @@ -2211,7 +2262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2220,22 +2271,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags 1.3.2", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - [[package]] name = "futures" version = "0.3.28" @@ -2290,9 +2325,9 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -2416,10 +2451,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if 1.0.0", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -2592,9 +2625,9 @@ dependencies = [ [[package]] name = "gix-command" -version = "0.2.10" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c576cfbf577f72c097b5f88aedea502cd62952bdc1fb3adcab4531d5525a4c7" +checksum = "5f6141b70cfb21255223e42f3379855037cbbe8673b58dd8318d2f09b516fad1" dependencies = [ "bstr", ] @@ -2623,11 +2656,11 @@ dependencies = [ [[package]] name = "gix-config-value" -version = "0.12.5" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e874f41437441c02991dcea76990b9058fadfc54b02ab4dd06ab2218af43897" +checksum = "6f216df1c33e6e1555923eff0096858a879e8aaadd35b5d788641e4e8064c892" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "bstr", "gix-path", "libc", @@ -2721,7 +2754,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07c98204529ac3f24b34754540a852593d2a4c7349008df389240266627a72a" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "bstr", "gix-features", "gix-path", @@ -2729,9 +2762,9 @@ dependencies = [ [[package]] name = "gix-hash" -version = "0.11.4" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b422ff2ad9a0628baaad6da468cf05385bf3f5ab495ad5a33cce99b9f41092f" +checksum = "ee181c85d3955f54c4426e6bfaeeada4428692e1a39b8788c2ac7785fc301dd8" dependencies = [ "hex", "thiserror", @@ -2739,12 +2772,12 @@ dependencies = [ [[package]] name = "gix-hashtable" -version = "0.2.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385f4ce6ecf3692d313ca3aa9bd3b3d8490de53368d6d94bedff3af8b6d9c58d" +checksum = "bd259bd0d96e6153e357a8cdaca76c48e103fd34208b6c0ce77b1ad995834bd2" dependencies = [ "gix-hash", - "hashbrown 0.14.3", + "hashbrown 0.13.2", "parking_lot 0.12.1", ] @@ -2766,7 +2799,7 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f39c1ccc8f1912cbbd5191efc28dbc5f0d0598042aa56bc09427b7c34efab3ba" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "bstr", "btoi", "filetime", @@ -2865,12 +2898,11 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.8.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18609c8cbec8508ea97c64938c33cd305b75dfc04a78d0c3b78b8b3fd618a77c" +checksum = "c1226f2e50adeb4d76c754c1856c06f13a24cad1624801653fbf09b869e5b808" dependencies = [ "bstr", - "gix-trace", "home", "once_cell", "thiserror", @@ -2878,22 +2910,22 @@ dependencies = [ [[package]] name = "gix-prompt" -version = "0.5.5" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c22decaf4a063ccae2b2108820c8630c01bd6756656df3fe464b32b8958a5ea" +checksum = "e15fe57fa48572b7d3bf465d6a2a0351cd3c55cba74fd5f0b9c23689f9c1a31e" dependencies = [ "gix-command", "gix-config-value", "parking_lot 0.12.1", - "rustix 0.38.21", + "rustix 0.37.18", "thiserror", ] [[package]] name = "gix-quote" -version = "0.4.7" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "475c86a97dd0127ba4465fbb239abac9ea10e68301470c9791a6dd5351cdc905" +checksum = "29d59489bff95b06dcdabe763b7266d3dc0a628cac1ac1caf65a7ca0a43eeae0" dependencies = [ "bstr", "btoi", @@ -2950,11 +2982,11 @@ dependencies = [ [[package]] name = "gix-sec" -version = "0.8.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9615cbd6b456898aeb942cd75e5810c382fbfc48dbbff2fa23ebd2d33dcbe9c7" +checksum = "b2b7b38b766eb95dcc5350a9c450030b69892c0902fa35f4a6d0809273bd9dae" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "gix-path", "libc", "windows", @@ -2975,12 +3007,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "gix-trace" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b6d623a1152c3facb79067d6e2ecdae48130030cf27d6eb21109f13bd7b836" - [[package]] name = "gix-traverse" version = "0.25.0" @@ -3009,18 +3035,18 @@ dependencies = [ [[package]] name = "gix-utils" -version = "0.1.5" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b85d89dc728613e26e0ed952a19583744e7f5240fcd4aa30d6c824ffd8b52f0f" +checksum = "dbcfcb150c7ef553d76988467d223254045bdcad0dc6724890f32fbe96415da5" dependencies = [ - "fastrand 2.0.1", + "fastrand", ] [[package]] name = "gix-validate" -version = "0.7.7" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba9b3737b2cef3dcd014633485f0034b0f1a931ee54aeb7d8f87f177f3c89040" +checksum = "57ea5845b506c7728b9d89f4227cc369a5fc5a1d5b26c3add0f0d323413a3a60" dependencies = [ "bstr", "thiserror", @@ -3047,43 +3073,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "gl_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" -dependencies = [ - "khronos_api", - "log", - "xml-rs", -] - -[[package]] -name = "glium" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a46e88b2c64cfa63d54ed54dc2a0d25136470eb1721e10be49d857ab583f8663" -dependencies = [ - "backtrace", - "fnv", - "gl_generator", - "glutin", - "lazy_static", - "memoffset 0.5.6", - "smallvec", - "takeable-option", -] - -[[package]] -name = "glium_text_rusttype" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9445ad33b59789364fb2dac28e7e79e89d25203fc80bd77f553c2e75d7ede905" -dependencies = [ - "glium", - "rusttype 0.8.3", -] - [[package]] name = "glob" version = "0.2.11" @@ -3113,78 +3102,6 @@ dependencies = [ "toml", ] -[[package]] -name = "glutin" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf22d4e90c55d9be9f2ad52410e7a2c0d7e9c99d93a13df73a672e7ef4e8c7f7" -dependencies = [ - "android_glue", - "cgl", - "cocoa", - "core-foundation 0.6.4", - "core-graphics 0.17.3", - "glutin_egl_sys", - "glutin_emscripten_sys", - "glutin_gles2_sys", - "glutin_glx_sys", - "glutin_wgl_sys", - "lazy_static", - "libloading 0.5.2", - "log", - "objc", - "osmesa-sys", - "parking_lot 0.10.2", - "wayland-client", - "winapi 0.3.9", - "winit", -] - -[[package]] -name = "glutin_egl_sys" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68900f84b471f31ea1d1355567eb865a2cf446294f06cef8d653ed7bcf5f013d" -dependencies = [ - "gl_generator", - "winapi 0.3.9", -] - -[[package]] -name = "glutin_emscripten_sys" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80de4146df76e8a6c32b03007bc764ff3249dcaeb4f675d68a06caf1bac363f1" - -[[package]] -name = "glutin_gles2_sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094e708b730a7c8a1954f4f8a31880af00eb8a1c5b5bf85d28a0a3c6d69103" -dependencies = [ - "gl_generator", - "objc", -] - -[[package]] -name = "glutin_glx_sys" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93d0575865098580c5b3a423188cd959419912ea60b1e48e8b3b526f6d02468" -dependencies = [ - "gl_generator", - "x11-dl", -] - -[[package]] -name = "glutin_wgl_sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5951a1569dbab865c6f2a863efafff193a93caf05538d193e9e3816d21696" -dependencies = [ - "gl_generator", -] - [[package]] name = "group" version = "0.13.0" @@ -3235,6 +3152,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -3361,24 +3287,6 @@ dependencies = [ "serde", ] -[[package]] -name = "highway-state-grapher" -version = "0.1.0" -dependencies = [ - "bincode", - "casper-hashing", - "casper-node", - "casper-types", - "clap 4.2.7", - "flate2", - "freetype-sys", - "glium", - "glium_text_rusttype", - "libc", - "nalgebra", - "serde", -] - [[package]] name = "hmac" version = "0.12.1" @@ -3422,7 +3330,7 @@ checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ "libc", "match_cfg", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3489,6 +3397,19 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +dependencies = [ + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -3573,7 +3494,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3587,15 +3508,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - [[package]] name = "ipnet" version = "2.7.2" @@ -3669,28 +3581,33 @@ dependencies = [ ] [[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +name = "kairos-delta-tree" +version = "0.1.0" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "digest 0.10.6", + "serde", + "sha2", + "sha256", + "uint", ] [[package]] -name = "key-management-thresholds" +name = "kairos-risc0-types" version = "0.1.0" dependencies = [ - "casper-contract", "casper-types", + "kairos-delta-tree", + "serde", + "serde-json-wasm", ] [[package]] -name = "khronos_api" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +name = "key-management-thresholds" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", +] [[package]] name = "kstring" @@ -3707,12 +3624,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "leb128" version = "0.2.5" @@ -3721,29 +3632,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" - -[[package]] -name = "libloading" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" -dependencies = [ - "cc", - "winapi 0.3.9", -] - -[[package]] -name = "libloading" -version = "0.6.7" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" -dependencies = [ - "cfg-if 1.0.0", - "winapi 0.3.9", -] +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libm" @@ -3751,15 +3642,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" -[[package]] -name = "line_drawing" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9" -dependencies = [ - "num-traits", -] - [[package]] name = "linked-hash-map" version = "0.5.6" @@ -3774,9 +3656,9 @@ checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "list-authorization-keys" @@ -3817,15 +3699,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "lock_api" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] - [[package]] name = "lock_api" version = "0.4.9" @@ -3864,15 +3737,6 @@ dependencies = [ "casper-types", ] -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - [[package]] name = "manage-groups" version = "0.1.0" @@ -3896,16 +3760,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matrixmultiply" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77" -dependencies = [ - "autocfg", - "rawpointer", -] - [[package]] name = "maybe-uninit" version = "2.0.0" @@ -3926,16 +3780,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memmap" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -dependencies = [ - "libc", - "winapi 0.3.9", -] - [[package]] name = "memmap2" version = "0.5.10" @@ -4025,25 +3869,6 @@ dependencies = [ "casper-types", ] -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - [[package]] name = "mio" version = "0.8.6" @@ -4056,30 +3881,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "mio-extras" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" -dependencies = [ - "lazycell", - "log", - "mio 0.6.23", - "slab", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - [[package]] name = "multer" version = "2.1.0" @@ -4094,10 +3895,16 @@ dependencies = [ "log", "memchr", "mime", - "spin", + "spin 0.9.8", "version_check", ] +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + [[package]] name = "multisig-authorization" version = "0.1.0" @@ -4106,33 +3913,6 @@ dependencies = [ "casper-types", ] -[[package]] -name = "nalgebra" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" -dependencies = [ - "approx 0.5.1", - "matrixmultiply", - "nalgebra-macros", - "num-complex", - "num-rational", - "num-traits", - "simba", - "typenum", -] - -[[package]] -name = "nalgebra-macros" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" -dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 1.0.109", -] - [[package]] name = "named-dictionary-test" version = "0.1.0" @@ -4199,17 +3979,6 @@ dependencies = [ "casper-types", ] -[[package]] -name = "net2" -version = "0.2.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - [[package]] name = "new-named-uref" version = "0.1.0" @@ -4217,19 +3986,6 @@ dependencies = [ "casper-contract", ] -[[package]] -name = "nix" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" -dependencies = [ - "bitflags 1.3.2", - "cc", - "cfg-if 0.1.10", - "libc", - "void", -] - [[package]] name = "nom" version = "7.1.3" @@ -4255,7 +4011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ "overload", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -4298,11 +4054,22 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -4366,15 +4133,6 @@ dependencies = [ "libc", ] -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - [[package]] name = "object" version = "0.30.3" @@ -4423,9 +4181,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -4456,15 +4214,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "ordered-float" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3305af35278dd29f46fcdd139e0b1fbfae2153f0e5928b39b035542dd31e37b7" -dependencies = [ - "num-traits", -] - [[package]] name = "ordered-transforms" version = "0.1.0" @@ -4479,22 +4228,13 @@ version = "6.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" -[[package]] -name = "osmesa-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" -dependencies = [ - "shared_library", -] - [[package]] name = "output_vt100" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -4511,16 +4251,6 @@ dependencies = [ "casper-types", ] -[[package]] -name = "parking_lot" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" -dependencies = [ - "lock_api 0.3.4", - "parking_lot_core 0.7.3", -] - [[package]] name = "parking_lot" version = "0.11.2" @@ -4528,7 +4258,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", - "lock_api 0.4.9", + "lock_api", "parking_lot_core 0.8.6", ] @@ -4538,24 +4268,10 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "lock_api 0.4.9", + "lock_api", "parking_lot_core 0.9.8", ] -[[package]] -name = "parking_lot_core" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b93f386bb233083c799e6e642a9d73db98c24a5deeb95ffc85bf281255dffc98" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "smallvec", - "winapi 0.3.9", -] - [[package]] name = "parking_lot_core" version = "0.8.6" @@ -4567,7 +4283,7 @@ dependencies = [ "libc", "redox_syscall 0.2.16", "smallvec", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -4606,6 +4322,16 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.1.0", +] + [[package]] name = "pin-project" version = "1.0.12" @@ -4621,8 +4347,8 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -4718,7 +4444,7 @@ dependencies = [ "libc", "pnet_base", "pnet_sys", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -4727,8 +4453,8 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30490e0852e58402b8fae0d39897b08a24f493023a4d6cf56b2e30f31ed57548" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "regex", "syn 1.0.109", ] @@ -4761,7 +4487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9a3f32b0df45515befd19eed04616f6b56a488da92afc61164ef455e955f07f" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -4794,6 +4520,16 @@ dependencies = [ "output_vt100", ] +[[package]] +name = "prettyplease" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2 1.0.79", + "syn 2.0.52", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -4801,8 +4537,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", "version_check", ] @@ -4813,8 +4549,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "version_check", ] @@ -4829,9 +4565,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -4884,8 +4620,8 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa06db3abc95f048e0afa371db5569b24912bb98a8e2e2e89c75c5b43bc2aa8" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -4900,12 +4636,75 @@ dependencies = [ "syn 0.15.44", ] +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools 0.10.5", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.52", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + [[package]] name = "protobuf" version = "2.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +[[package]] +name = "protobuf-src" +version = "1.1.0+21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ac8852baeb3cc6fb83b93646fb93c0ffe5d14bf138c945ceb4b9948ee0e3c1" +dependencies = [ + "autotools", +] + [[package]] name = "pulldown-cmark" version = "0.8.0" @@ -4953,7 +4752,7 @@ dependencies = [ "mach", "once_cell", "raw-cpuid", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -4979,11 +4778,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ - "proc-macro2 1.0.56", + "proc-macro2 1.0.79", ] [[package]] @@ -5059,31 +4858,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "raw-window-handle" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76" -dependencies = [ - "libc", - "raw-window-handle 0.4.3", -] - -[[package]] -name = "raw-window-handle" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" -dependencies = [ - "cty", -] - -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - [[package]] name = "rayon" version = "1.7.0" @@ -5122,12 +4896,6 @@ dependencies = [ "casper-types", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.2.16" @@ -5314,6 +5082,14 @@ dependencies = [ "casper-types", ] +[[package]] +name = "regression_20240105" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", +] + [[package]] name = "remove-associated-key" version = "0.1.0" @@ -5326,57 +5102,225 @@ dependencies = [ name = "reqwest" version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" +checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" +dependencies = [ + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util 0.7.8", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "revert" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "risc0-binfmt" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae2939426c60756f910352184716a3538748208c9e11ade4a507db3b2757157" +dependencies = [ + "anyhow", + "elf", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", + "tracing", +] + +[[package]] +name = "risc0-circuit-recursion" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a43cade35f73ad81ba974fe1d5e1513331f87052af8377b26b00a838f39c6920" +dependencies = [ + "anyhow", + "bytemuck", + "hex", + "risc0-core", + "risc0-zkp", + "tracing", +] + +[[package]] +name = "risc0-circuit-rv32im" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31440989146b342a7d37c15079c9568c69b7f988f3b789f422c7d4ed76526ddb" +dependencies = [ + "anyhow", + "risc0-core", + "risc0-zkp", + "risc0-zkvm-platform", + "tracing", +] + +[[package]] +name = "risc0-core" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e0cbd09d03c23b572b66cd96a56143adb22bf895aca89c1a153ccebedaa0b4" +dependencies = [ + "bytemuck", + "rand_core", +] + +[[package]] +name = "risc0-groth16" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da1e9b8dae3f9c3862b6278b2812989a2f5a537975e5bd6a687f07cf1df68a36" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-groth16", + "ark-serialize", + "hex", + "num-bigint", + "num-derive 0.4.2", + "num-traits", + "risc0-zkp", + "serde", +] + +[[package]] +name = "risc0-zkp" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96b035f744ecaaa7e9809c699bc85cf669cbab6f297f141d918e9b4c8098b79" dependencies = [ - "base64 0.21.0", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", + "anyhow", + "blake2 0.10.6", + "bytemuck", + "digest 0.10.6", + "hex", + "paste", + "rand_core", + "risc0-core", + "risc0-zkvm-platform", "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "tokio-util 0.7.8", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "winreg", + "sha2", + "tracing", ] [[package]] -name = "revert" -version = "0.1.0" +name = "risc0-zkvm" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1275834c86176efc122a172c2b5f271a8a5d792de7efbc47dfbecaaaff9432" dependencies = [ - "casper-contract", - "casper-types", + "anyhow", + "bincode", + "bonsai-sdk", + "bytemuck", + "bytes", + "cfg-if 1.0.0", + "getrandom", + "hex", + "num-derive 0.4.2", + "num-traits", + "prost", + "prost-build", + "protobuf-src", + "risc0-binfmt", + "risc0-circuit-recursion", + "risc0-circuit-rv32im", + "risc0-core", + "risc0-groth16", + "risc0-zkp", + "risc0-zkvm-platform", + "rrs-lib", + "semver", + "serde", + "sha2", + "tempfile", + "tracing", ] [[package]] -name = "rfc6979" -version = "0.4.0" +name = "risc0-zkvm-platform" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "03b6378c9e407be18a1560ed030fd87fb6056293c56263efac46c507ae97e0d7" dependencies = [ - "hmac", - "subtle", + "bytemuck", + "getrandom", + "libm", ] [[package]] @@ -5401,6 +5345,16 @@ dependencies = [ "serde", ] +[[package]] +name = "rrs-lib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4382d3af3a4ebdae7f64ba6edd9114fff92c89808004c4943b393377a25d001" +dependencies = [ + "downcast-rs", + "paste", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -5432,44 +5386,36 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.10", + "linux-raw-sys 0.4.13", "windows-sys 0.48.0", ] [[package]] -name = "rustls-pemfile" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" -dependencies = [ - "base64 0.21.0", -] - -[[package]] -name = "rusttype" -version = "0.7.9" +name = "rustls" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310942406a39981bed7e12b09182a221a29e0990f3e7e0c971f131922ed135d5" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ - "rusttype 0.8.3", + "log", + "ring 0.16.20", + "sct", + "webpki", ] [[package]] -name = "rusttype" -version = "0.8.3" +name = "rustls-pemfile" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f61411055101f7b60ecf1041d87fb74205fb20b0c7a723f07ef39174cf6b4c0" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "approx 0.3.2", - "ordered-float", - "stb_truetype", + "base64 0.21.0", ] [[package]] @@ -5496,15 +5442,6 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" -[[package]] -name = "safe_arch" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" -dependencies = [ - "bytemuck", -] - [[package]] name = "same-file" version = "1.0.6" @@ -5542,8 +5479,8 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791c2c848cff1abaeae34fef7e70da5f93171d9eea81ce0fe969a1df627a61a8" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "serde_derive_internals", "syn 1.0.109", ] @@ -5560,6 +5497,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.3", + "untrusted 0.9.0", +] + [[package]] name = "sec1" version = "0.7.3" @@ -5580,8 +5527,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.3", - "core-foundation-sys 0.8.4", + "core-foundation", + "core-foundation-sys", "libc", "security-framework-sys", ] @@ -5592,7 +5539,7 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ - "core-foundation-sys 0.8.4", + "core-foundation-sys", "libc", ] @@ -5604,9 +5551,9 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.160" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -5620,6 +5567,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.9" @@ -5641,13 +5597,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -5656,8 +5612,8 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -5679,9 +5635,9 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -5742,22 +5698,25 @@ dependencies = [ ] [[package]] -name = "sharded-slab" -version = "0.1.4" +name = "sha256" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" dependencies = [ - "lazy_static", + "async-trait", + "bytes", + "hex", + "sha2", + "tokio", ] [[package]] -name = "shared_library" -version = "0.1.9" +name = "sharded-slab" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ "lazy_static", - "libc", ] [[package]] @@ -5801,19 +5760,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "simba" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" -dependencies = [ - "approx 0.5.1", - "num-complex", - "num-traits", - "paste", - "wide", -] - [[package]] name = "simple-transfer" version = "0.1.0" @@ -5840,22 +5786,6 @@ dependencies = [ "serde", ] -[[package]] -name = "smithay-client-toolkit" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421c8dc7acf5cb205b88160f8b4cc2c5cfabe210e43b2f80f009f4c1ef910f1d" -dependencies = [ - "andrew", - "bitflags 1.3.2", - "dlib", - "lazy_static", - "memmap", - "nix", - "wayland-client", - "wayland-protocols", -] - [[package]] name = "socket2" version = "0.4.9" @@ -5863,9 +5793,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spin" version = "0.9.8" @@ -5908,15 +5844,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c0e04424e733e69714ca1bbb9204c1a57f09f5493439520f9f68c132ad25eec" -[[package]] -name = "stb_truetype" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" -dependencies = [ - "byteorder", -] - [[package]] name = "storage-costs" version = "0.1.0" @@ -5956,8 +5883,8 @@ checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck 0.3.3", "proc-macro-error", - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -5977,8 +5904,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "rustversion", "syn 1.0.109", ] @@ -6006,19 +5933,19 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.15" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "unicode-ident", ] @@ -6040,12 +5967,6 @@ dependencies = [ "casper-types", ] -[[package]] -name = "takeable-option" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ae8932fcfea38b7d3883ae2ab357b0d57a02caaa18ebb4f5ece08beaec4aa0" - [[package]] name = "tempfile" version = "3.5.0" @@ -6053,7 +5974,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if 1.0.0", - "fastrand 1.9.0", + "fastrand", "redox_syscall 0.3.5", "rustix 0.37.18", "windows-sys 0.45.0", @@ -6116,9 +6037,9 @@ version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -6187,14 +6108,15 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.0" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", + "backtrace", "bytes", "libc", - "mio 0.8.6", + "mio", "num_cpus", "pin-project-lite", "socket2", @@ -6208,9 +6130,9 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -6235,6 +6157,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + [[package]] name = "tokio-serde" version = "0.8.0" @@ -6357,9 +6290,9 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] [[package]] @@ -6403,6 +6336,15 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.17" @@ -6671,6 +6613,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "update-associated-key" version = "0.1.0" @@ -6758,7 +6706,7 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d0801cec07737d88cb900e6419f6f68733867f90b3faaa837e84692e101bf0" dependencies = [ - "proc-macro2 1.0.56", + "proc-macro2 1.0.79", "pulldown-cmark", "regex", "semver", @@ -6773,12 +6721,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "wabt" version = "0.10.0" @@ -6844,8 +6786,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a6e5bd22c71e77d60140b0bd5be56155a37e5bd14e24f5f87298040d0cc40d7" dependencies = [ "heck 0.3.3", - "proc-macro2 1.0.56", - "quote 1.0.26", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -6916,9 +6858,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", "wasm-bindgen-shared", ] @@ -6940,7 +6882,7 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ - "quote 1.0.26", + "quote 1.0.35", "wasm-bindgen-macro-support", ] @@ -6950,9 +6892,9 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.26", - "syn 2.0.15", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7022,73 +6964,32 @@ dependencies = [ ] [[package]] -name = "wayland-client" -version = "0.23.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda" -dependencies = [ - "bitflags 1.3.2", - "calloop", - "downcast-rs", - "libc", - "mio 0.6.23", - "nix", - "wayland-commons", - "wayland-scanner", - "wayland-sys", -] - -[[package]] -name = "wayland-commons" -version = "0.23.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb" -dependencies = [ - "nix", - "wayland-sys", -] - -[[package]] -name = "wayland-protocols" -version = "0.23.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9" -dependencies = [ - "bitflags 1.3.2", - "wayland-client", - "wayland-commons", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.23.6" +name = "web-sys" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "xml-rs", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "wayland-sys" -version = "0.23.6" +name = "webpki" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "dlib", - "lazy_static", + "ring 0.17.3", + "untrusted 0.9.0", ] [[package]] -name = "web-sys" -version = "0.3.64" +name = "webpki-roots" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ - "js-sys", - "wasm-bindgen", + "webpki", ] [[package]] @@ -7100,7 +7001,7 @@ dependencies = [ "cfg-if 0.1.10", "libc", "memory_units", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -7110,21 +7011,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945bc99a6a121cb2759c7bfa7b779ddf0e69b68bb35a9b23ab72276cfdcd3c" [[package]] -name = "wide" -version = "0.7.11" +name = "which" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa469ffa65ef7e0ba0f164183697b89b854253fd31aeb92358b7b6155177d62f" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ - "bytemuck", - "safe_arch", + "either", + "home", + "once_cell", + "rustix 0.38.25", ] -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -7135,12 +7032,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -7153,7 +7044,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -7303,42 +7194,13 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" -[[package]] -name = "winit" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65a5c1a5ef76ac31cc97ad29489acdbed2178f3fc12ca00ee6cb11d60adb5a3a" -dependencies = [ - "android_glue", - "bitflags 1.3.2", - "cocoa", - "core-foundation 0.6.4", - "core-graphics 0.17.3", - "core-video-sys", - "dispatch", - "instant", - "lazy_static", - "libc", - "log", - "mio 0.6.23", - "mio-extras", - "objc", - "parking_lot 0.10.2", - "percent-encoding", - "raw-window-handle 0.3.4", - "smithay-client-toolkit", - "wayland-client", - "winapi 0.3.9", - "x11-dl", -] - [[package]] name = "winreg" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -7350,40 +7212,21 @@ dependencies = [ ] [[package]] -name = "ws2_32-sys" -version = "0.2.1" +name = "zeroize" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "zeroize_derive", ] [[package]] -name = "x11-dl" -version = "2.21.0" +name = "zeroize_derive" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "libc", - "once_cell", - "pkg-config", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.52", ] - -[[package]] -name = "xdg" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" - -[[package]] -name = "xml-rs" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" - -[[package]] -name = "zeroize" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/Cargo.toml b/Cargo.toml index 2dac867eba..fbd748d22d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,6 @@ members = [ "utils/global-state-update-gen", "utils/validation", "utils/highway-rewards-analysis", - "utils/highway-state-grapher", ] default-members = [ @@ -28,7 +27,6 @@ default-members = [ "utils/global-state-update-gen", "utils/validation", "utils/highway-rewards-analysis", - "utils/highway-state-grapher", ] exclude = ["utils/nctl/remotes/casper-client-rs"] diff --git a/Makefile b/Makefile index f398247571..a481629c40 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,11 @@ test: test-rs-no-default-features test-rs test-as .PHONY: test-contracts-rs test-contracts-rs: build-contracts-rs - $(DISABLE_LOGGING) $(CARGO) test $(CARGO_FLAGS) -p casper-engine-tests -- --ignored + $(DISABLE_LOGGING) $(CARGO) test $(CARGO_FLAGS) -p casper-engine-tests -- --ignored --skip repeated_ffi_call_should_gas_out_quickly + +.PHONY: test-contracts-timings +test-contracts-timings: build-contracts-rs + $(DISABLE_LOGGING) $(CARGO) test --release $(filter-out --release, $(CARGO_FLAGS)) -p casper-engine-tests -- --ignored --test-threads=1 repeated_ffi_call_should_gas_out_quickly .PHONY: test-contracts-as test-contracts-as: build-contracts-rs build-contracts-as @@ -101,10 +105,6 @@ test-contracts-as: build-contracts-rs build-contracts-as .PHONY: test-contracts test-contracts: test-contracts-rs -.PHONY: check-no-default-features -check-no-default-features: - cd types && $(CARGO) check --all-targets --no-default-features - .PHONY: check-std-features check-std-features: cd types && $(CARGO) check --all-targets --no-default-features --features=std @@ -161,7 +161,6 @@ check-rs: \ doc \ lint \ audit \ - check-no-default-features \ check-std-features \ test-rs \ test-rs-no-default-features \ diff --git a/README.md b/README.md index cf237a65eb..1cef026852 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # casper-node -Reference node for the Casper Blockchain Protocol. +This is the core application for the Casper blockchain. ## Casper Blockchain diff --git a/execution_engine/CHANGELOG.md b/execution_engine/CHANGELOG.md index d65a4ba31b..f00d5a2dbc 100644 --- a/execution_engine/CHANGELOG.md +++ b/execution_engine/CHANGELOG.md @@ -9,6 +9,21 @@ All notable changes to this project will be documented in this file. The format [comment]: <> (Fixed: any bug fixes) [comment]: <> (Security: in case of vulnerabilities) +## 7.0.1 + +### Changed +* Change the cost of `wasm.storage_costs.gas_per_byte` and `shared::storage_costs::DEFAULT_GAS_PER_BYTE_COST` from `630_000` to `1_117_587`. +* Change the cost of the host function `casper_add_associated_key` from `9_000` to `1_200_000`. +* Change the cost of the argument `entry_points_size` of host function `casper_add_contract_version` from `0` to `120_000`. +* Change the cost of the host function `casper_blake2b`and its argument `in_size` from `200` and `0` respectively to `1_200_000` to `120_000`. +* Change the cost of the host function `casper_call_contract` and its arguments `entry_point_name_size` and `runtime_args_size` from `4_500`, `0` and `420` respectively to `300_000_000`, `120_000` and `120_000`. +* Change the cost of the host function `casper_call_versioned_contract` and the arguments `entry_point_name_size` and `runtime_args_size` from `4_500`, `0` and `420` respectively to `300_000_000`, `120_000` and `120_000`. +* Change the cost of the host function `casper_get_balance` from `3_800` to `3_000_000`. +* Change the cost of arguments `name_size` and `dest_size` of host function `casper_get_named_arg` from `0` to `120_000`. +* Change the cost of the host function `casper_put_key` and its arguments `name_size` and `key_size` from `38_000`, `1_100` and `0` respectively to `100_000_000`, `120_000` and `120_000`. +* Change the cost of the host function `casper_read_value` and its argument `key_size` from `6_000` and `0` respectively to `60_000` and `120_000`. +* Change the cost of the argument `urefs_size` of host function `casper_remove_contract_user_group_urefs` from `0` to `120_000`. +* Change the cost of the host function `casper_transfer_from_purse_to_purse` from `82_000` to `82_000_000`. diff --git a/execution_engine/Cargo.toml b/execution_engine/Cargo.toml index 0d4a633afe..1578c6ba85 100644 --- a/execution_engine/Cargo.toml +++ b/execution_engine/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "casper-execution-engine" -version = "7.0.0" # when updating, also update 'html_root_url' in lib.rs +version = "7.0.1" # when updating, also update 'html_root_url' in lib.rs authors = ["Henry Till ", "Ed Hastings "] edition = "2021" description = "Casper execution engine crates." @@ -13,7 +13,7 @@ license = "Apache-2.0" [dependencies] anyhow = "1.0.33" base16 = "0.2.1" -bincode = "1.3.1" +#bincode = "1.3.1" casper-hashing = { version = "3.0.0", path = "../hashing" } casper-types = { version = "4.0.1", path = "../types", default-features = false, features = ["datasize", "gens", "json-schema"] } casper-wasm = { version = "0.46.0", default-features = false } @@ -48,6 +48,9 @@ thiserror = "1.0.18" tracing = "0.1.18" uint = "0.9.0" uuid = { version = "0.8.1", features = ["serde", "v4"] } +risc0-zkvm = { version="0.21.0" } +kairos-risc0-types = { path="../kairos-risc0-types" } +bincode = "1.3.3" [dev-dependencies] assert_matches = "1.3.0" diff --git a/execution_engine/src/core/engine_state/engine_config.rs b/execution_engine/src/core/engine_state/engine_config.rs index 40d6afaf63..1801775fa3 100644 --- a/execution_engine/src/core/engine_state/engine_config.rs +++ b/execution_engine/src/core/engine_state/engine_config.rs @@ -212,6 +212,12 @@ impl EngineConfig { pub fn fee_handling(&self) -> FeeHandling { self.fee_handling } + + /// Sets the `wasm_config.max_memory` to `new_value`. + #[cfg(feature = "test-support")] + pub fn set_max_memory(&mut self, new_value: u32) { + self.wasm_config.max_memory = new_value; + } } /// A builder for an [`EngineConfig`]. diff --git a/execution_engine/src/core/resolvers/v1_function_index.rs b/execution_engine/src/core/resolvers/v1_function_index.rs index 5c4c83842e..6305d3c887 100644 --- a/execution_engine/src/core/resolvers/v1_function_index.rs +++ b/execution_engine/src/core/resolvers/v1_function_index.rs @@ -58,6 +58,7 @@ pub(crate) enum FunctionIndex { RandomBytes, DictionaryReadFuncIndex, EnableContractVersion, + RiscZeroVerifier } impl From for usize { diff --git a/execution_engine/src/core/resolvers/v1_resolver.rs b/execution_engine/src/core/resolvers/v1_resolver.rs index 29b4b1cb1c..c720e87753 100644 --- a/execution_engine/src/core/resolvers/v1_resolver.rs +++ b/execution_engine/src/core/resolvers/v1_resolver.rs @@ -245,6 +245,10 @@ impl ModuleImportResolver for RuntimeModuleImportResolver { Signature::new(&[ValueType::I32; 4][..], Some(ValueType::I32)), FunctionIndex::EnableContractVersion.into(), ), + "casper_risc_zero_verifier" => FuncInstance::alloc_host( + Signature::new(&[ValueType::I32; 4][..], Some(ValueType::I32)), + FunctionIndex::RiscZeroVerifier.into(), + ), _ => { return Err(InterpreterError::Function(format!( "host module doesn't export function with name {}", diff --git a/execution_engine/src/core/runtime/externals.rs b/execution_engine/src/core/runtime/externals.rs index b48f63e619..350f09643d 100644 --- a/execution_engine/src/core/runtime/externals.rs +++ b/execution_engine/src/core/runtime/externals.rs @@ -15,8 +15,8 @@ use casper_types::{ use super::{args::Args, Error, Runtime}; use crate::{ - core::resolvers::v1_function_index::FunctionIndex, - shared::host_function_costs::{Cost, HostFunction, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY}, + core::{resolvers::v1_function_index::FunctionIndex, runtime::risc0_verifier}, + shared::host_function_costs::{Cost, HostFunction}, storage::global_state::StateReader, }; @@ -562,6 +562,9 @@ where existing_urefs_size, output_size_ptr, ) = Args::parse(args)?; + + // TODO - use `num_new_urefs` * costs for unit uref, assuming these aren't + // already charged. self.charge_host_function_call( &host_function_costs.create_contract_user_group, [ @@ -837,6 +840,7 @@ where // args(4) = output of size value of host bytes data let (package_ptr, package_size, label_ptr, label_size, value_size_ptr) = Args::parse(args)?; + // TODO - add cost for 1x unit uref, assuming this isn't already charged self.charge_host_function_call( &host_function_costs.provision_contract_user_group_uref, [ @@ -954,10 +958,9 @@ where // args(0) = pointer to output size (output param) let (output_size_ptr,): (u32,) = Args::parse(args)?; - self.charge_host_function_call( - &DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, - [output_size_ptr], - )?; + // TODO - dynamically calculate the size of the new data. Currently using + // hard-coded 33 which is correct as of now. + self.charge_host_function_call(&host_function_costs.new_uref, [0, 0, 33])?; let ret = self.new_dictionary(output_size_ptr)?; Ok(Some(RuntimeValue::I32(api_error::i32_from(ret)))) } @@ -1097,6 +1100,32 @@ where Ok(Some(RuntimeValue::I32(api_error::i32_from(result)))) } + FunctionIndex::RiscZeroVerifier => { + let ( + proof_ptr, + proof_size, + out_ptr, + out_size + ) = + Args::parse(args)?; + self.charge_host_function_call( + &host_function_costs.risc0_verifier, + [ + proof_ptr, + proof_size, + out_ptr, + out_size + ] + )?; + let result: [u8; 1] = + self.checked_memory_slice(proof_ptr as usize, proof_size as usize, |proof| { + risc0_verifier::verify(proof) + })?; + self.try_get_memory().unwrap() + .set(out_ptr, &result) + .map_err(|error| Error::Interpreter(error.into()))?; + Ok(Some(RuntimeValue::I32(0))) + } } } } diff --git a/execution_engine/src/core/runtime/mod.rs b/execution_engine/src/core/runtime/mod.rs index ffbdc70207..d0efde9235 100644 --- a/execution_engine/src/core/runtime/mod.rs +++ b/execution_engine/src/core/runtime/mod.rs @@ -6,6 +6,7 @@ mod handle_payment_internal; mod host_function_flag; mod mint_internal; pub mod stack; +pub mod risc0_verifier; mod standard_payment_internal; mod utils; diff --git a/execution_engine/src/core/runtime/risc0_verifier.rs b/execution_engine/src/core/runtime/risc0_verifier.rs new file mode 100644 index 0000000000..7cecb160dd --- /dev/null +++ b/execution_engine/src/core/runtime/risc0_verifier.rs @@ -0,0 +1,17 @@ +use risc0_zkvm::{default_prover, ExecutorEnv, Receipt}; +use kairos_risc0_types::RiscZeroProof; +use serde_json; +use bincode; + +#[doc(hidden)] +pub fn verify>( + proof_serialized: T +) -> [u8;1]{ + let risc0_proof: RiscZeroProof = bincode::deserialize(&proof_serialized.as_ref()).unwrap(); + let receipt: Receipt = bincode::deserialize(&risc0_proof.receipt_serialized).unwrap(); + let program_id: [u32;8] = risc0_proof.program_id.try_into().unwrap(); + match receipt.verify(program_id){ + Ok(_) => [1], + Err(_) => [0] + } +} \ No newline at end of file diff --git a/execution_engine/src/lib.rs b/execution_engine/src/lib.rs index 9b54784861..23a5fc0e64 100644 --- a/execution_engine/src/lib.rs +++ b/execution_engine/src/lib.rs @@ -1,6 +1,6 @@ //! The engine which executes smart contracts on the Casper network. -#![doc(html_root_url = "https://docs.rs/casper-execution-engine/7.0.0")] +#![doc(html_root_url = "https://docs.rs/casper-execution-engine/7.0.1")] #![doc( html_favicon_url = "https://raw.githubusercontent.com/casper-network/casper-node/blob/dev/images/Casper_Logo_Favicon_48.png", html_logo_url = "https://raw.githubusercontent.com/casper-network/casper-node/blob/dev/images/Casper_Logo_Favicon.png", diff --git a/execution_engine/src/shared/host_function_costs.rs b/execution_engine/src/shared/host_function_costs.rs index 83ed7b7c8d..a9dd723719 100644 --- a/execution_engine/src/shared/host_function_costs.rs +++ b/execution_engine/src/shared/host_function_costs.rs @@ -8,6 +8,8 @@ use casper_types::{ Gas, }; +use crate::core::runtime::risc0_verifier; + /// Representation of argument's cost. pub type Cost = u32; @@ -20,13 +22,12 @@ const NOT_USED: Cost = 0; const DEFAULT_FIXED_COST: Cost = 200; const DEFAULT_ADD_COST: u32 = 5_800; -const DEFAULT_ADD_ASSOCIATED_KEY_COST: u32 = 9_000; +const DEFAULT_ADD_ASSOCIATED_KEY_COST: u32 = 1_200_000; -const DEFAULT_CALL_CONTRACT_COST: u32 = 4_500; -const DEFAULT_CALL_CONTRACT_ARGS_SIZE_WEIGHT: u32 = 420; +const DEFAULT_CALL_CONTRACT_COST: u32 = 300_000_000; const DEFAULT_CREATE_PURSE_COST: u32 = 2_500_000_000; -const DEFAULT_GET_BALANCE_COST: u32 = 3_800; +const DEFAULT_GET_BALANCE_COST: u32 = 3_000_000; const DEFAULT_GET_BLOCKTIME_COST: u32 = 330; const DEFAULT_GET_CALLER_COST: u32 = 380; const DEFAULT_GET_KEY_COST: u32 = 2_000; @@ -44,13 +45,13 @@ const DEFAULT_NEW_UREF_VALUE_SIZE_WEIGHT: u32 = 590; const DEFAULT_PRINT_COST: u32 = 20_000; const DEFAULT_PRINT_TEXT_SIZE_WEIGHT: u32 = 4_600; -const DEFAULT_PUT_KEY_COST: u32 = 38_000; -const DEFAULT_PUT_KEY_NAME_SIZE_WEIGHT: u32 = 1_100; +const DEFAULT_PUT_KEY_COST: u32 = 100_000_000; +const DEFAULT_PUT_KEY_NAME_SIZE_WEIGHT: u32 = 120_000; const DEFAULT_READ_HOST_BUFFER_COST: u32 = 3_500; const DEFAULT_READ_HOST_BUFFER_DEST_SIZE_WEIGHT: u32 = 310; -const DEFAULT_READ_VALUE_COST: u32 = 6_000; +const DEFAULT_READ_VALUE_COST: u32 = 60_000; const DEFAULT_DICTIONARY_GET_COST: u32 = 5_500; const DEFAULT_DICTIONARY_GET_KEY_SIZE_WEIGHT: u32 = 590; @@ -65,21 +66,19 @@ const DEFAULT_RET_VALUE_SIZE_WEIGHT: u32 = 420_000; const DEFAULT_REVERT_COST: u32 = 500; const DEFAULT_SET_ACTION_THRESHOLD_COST: u32 = 74_000; const DEFAULT_TRANSFER_FROM_PURSE_TO_ACCOUNT_COST: u32 = 2_500_000_000; -const DEFAULT_TRANSFER_FROM_PURSE_TO_PURSE_COST: u32 = 82_000; +const DEFAULT_TRANSFER_FROM_PURSE_TO_PURSE_COST: u32 = 82_000_000; const DEFAULT_TRANSFER_TO_ACCOUNT_COST: u32 = 2_500_000_000; const DEFAULT_UPDATE_ASSOCIATED_KEY_COST: u32 = 4_200; const DEFAULT_WRITE_COST: u32 = 14_000; const DEFAULT_WRITE_VALUE_SIZE_WEIGHT: u32 = 980; +const DEFAULT_ARG_CHARGE: u32 = 120_000; + const DEFAULT_DICTIONARY_PUT_COST: u32 = 9_500; const DEFAULT_DICTIONARY_PUT_KEY_BYTES_SIZE_WEIGHT: u32 = 1_800; const DEFAULT_DICTIONARY_PUT_VALUE_SIZE_WEIGHT: u32 = 520; - -const DEFAULT_NEW_DICTIONARY_COST: u32 = DEFAULT_NEW_UREF_COST; - -pub(crate) const DEFAULT_HOST_FUNCTION_NEW_DICTIONARY: HostFunction<[Cost; 1]> = - HostFunction::new(DEFAULT_NEW_DICTIONARY_COST, [NOT_USED]); +const DEFAULT_BLAKE2B_COST: u32 = 1_200_000; /// Representation of a host function cost. /// @@ -290,12 +289,17 @@ pub struct HostFunctionCosts { pub random_bytes: HostFunction<[Cost; 2]>, /// Cost of calling the `enable_contract_version` host function. pub enable_contract_version: HostFunction<[Cost; 4]>, + /// Cost of calling the `risc0_verifier` host function. + pub risc0_verifier: HostFunction<[Cost; 4]>, } impl Default for HostFunctionCosts { fn default() -> Self { Self { - read_value: HostFunction::fixed(DEFAULT_READ_VALUE_COST), + read_value: HostFunction::new( + DEFAULT_READ_VALUE_COST, + [NOT_USED, DEFAULT_ARG_CHARGE, NOT_USED], + ), dictionary_get: HostFunction::new( DEFAULT_DICTIONARY_GET_COST, [NOT_USED, DEFAULT_DICTIONARY_GET_KEY_SIZE_WEIGHT, NOT_USED], @@ -345,7 +349,7 @@ impl Default for HostFunctionCosts { NOT_USED, DEFAULT_PUT_KEY_NAME_SIZE_WEIGHT, NOT_USED, - NOT_USED, + DEFAULT_ARG_CHARGE, ], ), remove_key: HostFunction::new( @@ -382,7 +386,21 @@ impl Default for HostFunctionCosts { ), create_contract_package_at_hash: HostFunction::default(), create_contract_user_group: HostFunction::default(), - add_contract_version: HostFunction::default(), + add_contract_version: HostFunction::new( + 200, + [ + NOT_USED, + NOT_USED, + NOT_USED, + NOT_USED, + DEFAULT_ARG_CHARGE, + NOT_USED, + NOT_USED, + NOT_USED, + NOT_USED, + NOT_USED, + ], + ), disable_contract_version: HostFunction::default(), call_contract: HostFunction::new( DEFAULT_CALL_CONTRACT_COST, @@ -390,9 +408,9 @@ impl Default for HostFunctionCosts { NOT_USED, NOT_USED, NOT_USED, + DEFAULT_ARG_CHARGE, NOT_USED, - NOT_USED, - DEFAULT_CALL_CONTRACT_ARGS_SIZE_WEIGHT, + DEFAULT_ARG_CHARGE, NOT_USED, ], ), @@ -404,24 +422,41 @@ impl Default for HostFunctionCosts { NOT_USED, NOT_USED, NOT_USED, + DEFAULT_ARG_CHARGE, NOT_USED, - NOT_USED, - DEFAULT_CALL_CONTRACT_ARGS_SIZE_WEIGHT, + DEFAULT_ARG_CHARGE, NOT_USED, ], ), get_named_arg_size: HostFunction::default(), - get_named_arg: HostFunction::default(), + get_named_arg: HostFunction::new( + 200, + [NOT_USED, DEFAULT_ARG_CHARGE, NOT_USED, DEFAULT_ARG_CHARGE], + ), remove_contract_user_group: HostFunction::default(), provision_contract_user_group_uref: HostFunction::default(), - remove_contract_user_group_urefs: HostFunction::default(), + remove_contract_user_group_urefs: HostFunction::new( + 200, + [ + NOT_USED, + NOT_USED, + NOT_USED, + NOT_USED, + NOT_USED, + DEFAULT_ARG_CHARGE, + ], + ), print: HostFunction::new( DEFAULT_PRINT_COST, [NOT_USED, DEFAULT_PRINT_TEXT_SIZE_WEIGHT], ), - blake2b: HostFunction::default(), + blake2b: HostFunction::new( + DEFAULT_BLAKE2B_COST, + [NOT_USED, DEFAULT_ARG_CHARGE, NOT_USED, NOT_USED], + ), random_bytes: HostFunction::default(), enable_contract_version: HostFunction::default(), + risc0_verifier: HostFunction::default() } } } @@ -473,6 +508,7 @@ impl ToBytes for HostFunctionCosts { ret.append(&mut self.blake2b.to_bytes()?); ret.append(&mut self.random_bytes.to_bytes()?); ret.append(&mut self.enable_contract_version.to_bytes()?); + ret.append(&mut self.risc0_verifier.to_bytes()?); Ok(ret) } @@ -521,6 +557,7 @@ impl ToBytes for HostFunctionCosts { + self.blake2b.serialized_length() + self.random_bytes.serialized_length() + self.enable_contract_version.serialized_length() + + self.risc0_verifier.serialized_length() } } @@ -570,6 +607,7 @@ impl FromBytes for HostFunctionCosts { let (blake2b, rem) = FromBytes::from_bytes(rem)?; let (random_bytes, rem) = FromBytes::from_bytes(rem)?; let (enable_contract_version, rem) = FromBytes::from_bytes(rem)?; + let (risc0_verifier, rem) = FromBytes::from_bytes(rem)?; Ok(( HostFunctionCosts { read_value, @@ -616,6 +654,7 @@ impl FromBytes for HostFunctionCosts { blake2b, random_bytes, enable_contract_version, + risc0_verifier }, rem, )) @@ -669,6 +708,7 @@ impl Distribution for Standard { blake2b: rng.gen(), random_bytes: rng.gen(), enable_contract_version: rng.gen(), + risc0_verifier: rng.gen() } } } @@ -730,6 +770,7 @@ pub mod gens { blake2b in host_function_cost_arb(), random_bytes in host_function_cost_arb(), enable_contract_version in host_function_cost_arb(), + risc0_verifier in host_function_cost_arb() ) -> HostFunctionCosts { HostFunctionCosts { read_value, @@ -776,6 +817,7 @@ pub mod gens { blake2b, random_bytes, enable_contract_version, + risc0_verifier } } } diff --git a/execution_engine/src/shared/storage_costs.rs b/execution_engine/src/shared/storage_costs.rs index 5ac777db7b..eff4b77a97 100644 --- a/execution_engine/src/shared/storage_costs.rs +++ b/execution_engine/src/shared/storage_costs.rs @@ -9,7 +9,7 @@ use casper_types::{ }; /// Default gas cost per byte stored. -pub const DEFAULT_GAS_PER_BYTE_COST: u32 = 630_000; +pub const DEFAULT_GAS_PER_BYTE_COST: u32 = 1_117_587; /// Represents a cost table for storage costs. #[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug, DataSize)] diff --git a/execution_engine_testing/test_support/CHANGELOG.md b/execution_engine_testing/test_support/CHANGELOG.md index d780fc96a3..e2fb36747c 100644 --- a/execution_engine_testing/test_support/CHANGELOG.md +++ b/execution_engine_testing/test_support/CHANGELOG.md @@ -11,6 +11,16 @@ All notable changes to this project will be documented in this file. The format +## 7.0.1 + +### Added +* Provide `from_chainspec_path` and `max_associated_keys` helper methods on `ChainspecConfig`. +* Provide functions for converting from `ChainspecConfig` to `EngineConfig`. +* Provide `try_exec` method on `WamTestBuilder` for fallible contract execution. +* Provide `PRODUCTION_CHAINSPEC_PATH`: a lazy static defining the path to the production chainspec.toml file. + + + ## 7.0.0 ### Added diff --git a/execution_engine_testing/test_support/Cargo.toml b/execution_engine_testing/test_support/Cargo.toml index dcff62453c..ec7dc440f0 100644 --- a/execution_engine_testing/test_support/Cargo.toml +++ b/execution_engine_testing/test_support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "casper-engine-test-support" -version = "7.0.0" # when updating, also update 'html_root_url' in lib.rs +version = "7.0.1" # when updating, also update 'html_root_url' in lib.rs authors = ["Fraser Hutchison "] edition = "2021" description = "Library to support testing of Wasm smart contracts for use on the Casper network." @@ -11,7 +11,7 @@ repository = "https://github.com/CasperLabs/casper-node/tree/master/execution_en license = "Apache-2.0" [dependencies] -casper-execution-engine = { version = "7.0.0", path = "../../execution_engine", features = ["test-support"] } +casper-execution-engine = { version = "7.0.1", path = "../../execution_engine", features = ["test-support"] } casper-hashing = { version = "3.0.0", path = "../../hashing" } casper-types = { version = "4.0.1", path = "../../types" } humantime = "2" diff --git a/execution_engine_testing/test_support/src/chainspec_config.rs b/execution_engine_testing/test_support/src/chainspec_config.rs index 38f0d6919f..8622fddb7e 100644 --- a/execution_engine_testing/test_support/src/chainspec_config.rs +++ b/execution_engine_testing/test_support/src/chainspec_config.rs @@ -11,7 +11,9 @@ use serde::{Deserialize, Serialize}; use casper_execution_engine::{ core::engine_state::{ - engine_config::{FeeHandling, RefundHandling}, + engine_config::{ + EngineConfig, EngineConfigBuilder, FeeHandling, RefundHandling, DEFAULT_MAX_QUERY_DEPTH, + }, genesis::ExecConfigBuilder, run_genesis_request::RunGenesisRequest, ExecConfig, GenesisAccount, @@ -29,7 +31,7 @@ use crate::{ pub const CHAINSPEC_NAME: &str = "chainspec.toml"; /// Path to the production chainspec used in the Casper mainnet. -pub static PRODUCTION_PATH: Lazy = Lazy::new(|| { +pub static PRODUCTION_CHAINSPEC_PATH: Lazy = Lazy::new(|| { PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("resources/") .join(CHAINSPEC_NAME) @@ -114,7 +116,8 @@ impl ChainspecConfig { ChainspecConfig::from_bytes(&bytes) } - pub(crate) fn from_chainspec_path>(filename: P) -> Result { + /// Returns a new `ChainspecConfig` parsed from the TOML-encoded chainspec file at `filename`. + pub fn from_chainspec_path>(filename: P) -> Result { Self::from_path(filename) } @@ -188,11 +191,41 @@ impl ChainspecConfig { protocol_version: ProtocolVersion, ) -> Result { Self::create_genesis_request_from_chainspec( - &*PRODUCTION_PATH, + &*PRODUCTION_CHAINSPEC_PATH, genesis_accounts, protocol_version, ) } + + /// Returns the `max_associated_keys` setting from the core config. + pub fn max_associated_keys(&self) -> u32 { + self.core_config.max_associated_keys + } +} + +impl From for EngineConfig { + fn from(chainspec_config: ChainspecConfig) -> Self { + EngineConfigBuilder::new() + .with_max_query_depth(DEFAULT_MAX_QUERY_DEPTH) + .with_max_associated_keys(chainspec_config.core_config.max_associated_keys) + .with_max_runtime_call_stack_height( + chainspec_config.core_config.max_runtime_call_stack_height, + ) + .with_minimum_delegation_amount(chainspec_config.core_config.minimum_delegation_amount) + .with_strict_argument_checking(chainspec_config.core_config.strict_argument_checking) + .with_vesting_schedule_period_millis( + chainspec_config + .core_config + .vesting_schedule_period + .millis(), + ) + .with_max_delegators_per_validator( + chainspec_config.core_config.max_delegators_per_validator, + ) + .with_wasm_config(chainspec_config.wasm_config) + .with_system_config(chainspec_config.system_costs_config) + .build() + } } impl TryFrom for ExecConfig { diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index 1861038f13..4458b42a7b 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -1,6 +1,6 @@ //! A library to support testing of Wasm smart contracts for use on the Casper Platform. -#![doc(html_root_url = "https://docs.rs/casper-engine-test-support/7.0.0")] +#![doc(html_root_url = "https://docs.rs/casper-engine-test-support/7.0.1")] #![doc( html_favicon_url = "https://raw.githubusercontent.com/casper-network/casper-node/blob/dev/images/Casper_Logo_Favicon_48.png", html_logo_url = "https://raw.githubusercontent.com/casper-network/casper-node/blob/dev/images/Casper_Logo_Favicon.png", @@ -40,9 +40,8 @@ use casper_execution_engine::{ use casper_hashing::Digest; use casper_types::{account::AccountHash, Motes, ProtocolVersion, PublicKey, SecretKey, U512}; -use crate::chainspec_config::PRODUCTION_PATH; pub use additive_map_diff::AdditiveMapDiff; -pub use chainspec_config::ChainspecConfig; +pub use chainspec_config::{ChainspecConfig, PRODUCTION_CHAINSPEC_PATH}; pub use deploy_item_builder::DeployItemBuilder; pub use execute_request_builder::ExecuteRequestBuilder; pub use step_request_builder::StepRequestBuilder; @@ -129,7 +128,7 @@ pub static DEFAULT_ACCOUNTS: Lazy> = Lazy::new(|| { /// Default [`ProtocolVersion`]. pub static DEFAULT_PROTOCOL_VERSION: Lazy = Lazy::new(|| ProtocolVersion::V1_0_0); /// Default payment. -pub static DEFAULT_PAYMENT: Lazy = Lazy::new(|| U512::from(1_500_000_000_000u64)); +pub static DEFAULT_PAYMENT: Lazy = Lazy::new(|| U512::from(2_500_000_000_000u64)); /// Default [`WasmConfig`]. pub static DEFAULT_WASM_CONFIG: Lazy = Lazy::new(WasmConfig::default); /// Default [`SystemConfig`]. @@ -192,7 +191,7 @@ pub static PRODUCTION_RUN_GENESIS_REQUEST: Lazy = Lazy::new(| }); /// Round seigniorage rate from the production chainspec. pub static PRODUCTION_ROUND_SEIGNIORAGE_RATE: Lazy> = Lazy::new(|| { - let chainspec = ChainspecConfig::from_chainspec_path(&*PRODUCTION_PATH) + let chainspec = ChainspecConfig::from_chainspec_path(&*PRODUCTION_CHAINSPEC_PATH) .expect("must create chainspec_config"); chainspec.core_config.round_seigniorage_rate }); @@ -205,7 +204,7 @@ mod tests { #[test] fn defaults_should_match_production_chainspec_values() { - let production = ChainspecConfig::from_chainspec_path(&*PRODUCTION_PATH).unwrap(); + let production = ChainspecConfig::from_chainspec_path(&*PRODUCTION_CHAINSPEC_PATH).unwrap(); // No need to test `CoreConfig::validator_slots`. assert_eq!(production.core_config.auction_delay, DEFAULT_AUCTION_DELAY); assert_eq!( diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 1b190b8957..f1da45b5a6 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -74,7 +74,7 @@ use casper_types::{ }; use crate::{ - chainspec_config::{ChainspecConfig, CoreConfig, PRODUCTION_PATH}, + chainspec_config::{ChainspecConfig, CoreConfig, PRODUCTION_CHAINSPEC_PATH}, utils, ExecuteRequestBuilder, StepRequestBuilder, DEFAULT_GAS_PRICE, DEFAULT_PROPOSER_ADDR, DEFAULT_PROTOCOL_VERSION, SYSTEM_ADDR, }; @@ -130,7 +130,7 @@ impl WasmTestBuilder { impl Default for InMemoryWasmTestBuilder { fn default() -> Self { - Self::new_with_chainspec(&*PRODUCTION_PATH, None) + Self::new_with_chainspec(&*PRODUCTION_CHAINSPEC_PATH, None) } } @@ -352,35 +352,13 @@ impl LmdbWasmTestBuilder { ) -> Self { let chainspec_config = ChainspecConfig::from_chainspec_path(chainspec_path) .expect("must build chainspec configuration"); - - let engine_config = EngineConfigBuilder::new() - .with_max_query_depth(DEFAULT_MAX_QUERY_DEPTH) - .with_max_associated_keys(chainspec_config.core_config.max_associated_keys) - .with_max_runtime_call_stack_height( - chainspec_config.core_config.max_runtime_call_stack_height, - ) - .with_minimum_delegation_amount(chainspec_config.core_config.minimum_delegation_amount) - .with_strict_argument_checking(chainspec_config.core_config.strict_argument_checking) - .with_vesting_schedule_period_millis( - chainspec_config - .core_config - .vesting_schedule_period - .millis(), - ) - .with_max_delegators_per_validator( - chainspec_config.core_config.max_delegators_per_validator, - ) - .with_wasm_config(chainspec_config.wasm_config) - .with_system_config(chainspec_config.system_costs_config) - .build(); - - Self::new_with_config(data_dir, engine_config) + Self::new_with_config(data_dir, EngineConfig::from(chainspec_config)) } /// Returns an [`LmdbWasmTestBuilder`] with configuration and values from /// the production chainspec. pub fn new_with_production_chainspec + ?Sized>(data_dir: &T) -> Self { - Self::new_with_chainspec(data_dir, &*PRODUCTION_PATH) + Self::new_with_chainspec(data_dir, &*PRODUCTION_CHAINSPEC_PATH) } /// Flushes the LMDB environment to disk. @@ -734,33 +712,30 @@ where } /// Runs an [`ExecuteRequest`]. - pub fn exec(&mut self, mut exec_request: ExecuteRequest) -> &mut Self { + pub fn exec(&mut self, exec_request: ExecuteRequest) -> &mut Self { + self.try_exec(exec_request).expect("should execute") + } + + /// Tries to run an [`ExecuteRequest`]. + pub fn try_exec(&mut self, mut exec_request: ExecuteRequest) -> Result<&mut Self, Error> { let exec_request = { let hash = self.post_state_hash.expect("expected post_state_hash"); exec_request.parent_state_hash = hash; exec_request }; - let maybe_exec_results = self + let execution_results = self .engine_state - .run_execute(CorrelationId::new(), exec_request); - assert!(maybe_exec_results.is_ok()); - // Parse deploy results - let execution_results = maybe_exec_results.as_ref().unwrap(); + .run_execute(CorrelationId::new(), exec_request)?; // Cache transformations self.transforms.extend( execution_results .iter() .map(|res| res.execution_journal().clone()), ); - self.exec_results.push( - maybe_exec_results - .unwrap() - .into_iter() - .map(Rc::new) - .collect(), - ); - self + self.exec_results + .push(execution_results.into_iter().map(Rc::new).collect()); + Ok(self) } /// Commit effects of previous exec call on the latest post-state hash. diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index f9b0b2cb91..ea040f0433 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -908,10 +908,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 82_537_580_930; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 101_530_510; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_630_671_980; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_604_081_250; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 144_886_340_756; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 135_605_050; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_702_500_513; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_637_119_046; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); diff --git a/execution_engine_testing/tests/src/test/regression/ee_468.rs b/execution_engine_testing/tests/src/test/regression/ee_468.rs index 4c7bee0631..16bbad61d9 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_468.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_468.rs @@ -2,7 +2,8 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_types::RuntimeArgs; +use casper_execution_engine::core::{engine_state, execution}; +use casper_types::{bytesrepr, RuntimeArgs}; const CONTRACT_DESERIALIZE_ERROR: &str = "deserialize_error.wasm"; @@ -15,11 +16,20 @@ fn should_not_fail_deserializing() { RuntimeArgs::new(), ) .build(); - let is_error = InMemoryWasmTestBuilder::default() + let error = InMemoryWasmTestBuilder::default() .run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST) .exec(exec_request) .commit() - .is_error(); + .get_error(); - assert!(is_error); + assert!( + matches!( + error, + Some(engine_state::Error::Exec(execution::Error::BytesRepr( + bytesrepr::Error::EarlyEndOfStream + ))) + ), + "{:?}", + error + ); } diff --git a/execution_engine_testing/tests/src/test/regression/gh_2280.rs b/execution_engine_testing/tests/src/test/regression/gh_2280.rs index 5e46dff1cd..868002ca7b 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_2280.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_2280.rs @@ -165,7 +165,7 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { .with_address(account_hash) .with_session_code(session_file, faucet_args_3) .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE + ARG_AMOUNT => U512::from(3_000_000_000u64) }) .with_authorization_keys(&[account_hash]) .with_deploy_hash(deploy_hash) @@ -183,12 +183,6 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { assert!(gas_cost_3 > gas_cost_1); assert!(gas_cost_3 > gas_cost_2); - - let gas_cost_diff = gas_cost_3.checked_sub(gas_cost_2).unwrap_or_default(); - assert_eq!( - gas_cost_diff, - Gas::new(U512::from(HOST_FUNCTION_COST_CHANGE)) - ); } #[ignore] @@ -418,7 +412,7 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { .with_address(account_hash) .with_session_code(session_file, faucet_args_3) .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE + ARG_AMOUNT => U512::from(3_000_000_000u64) }) .with_authorization_keys(&[account_hash]) .with_deploy_hash(deploy_hash) @@ -436,12 +430,6 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { assert!(gas_cost_3 > gas_cost_1); assert!(gas_cost_3 > gas_cost_2); - - let gas_cost_diff = gas_cost_3.checked_sub(gas_cost_2).unwrap_or_default(); - assert_eq!( - gas_cost_diff, - Gas::new(U512::from(HOST_FUNCTION_COST_CHANGE)) - ); } #[ignore] @@ -547,7 +535,7 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { .with_address(account_hash) .with_stored_session_hash(gh_2280_regression, entry_point, faucet_args_3) .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE + ARG_AMOUNT => U512::from(3_000_000_000u64) }) .with_authorization_keys(&[account_hash]) .with_deploy_hash(deploy_hash) @@ -565,12 +553,6 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { assert!(gas_cost_3 > gas_cost_1, "{} <= {}", gas_cost_3, gas_cost_1); assert!(gas_cost_3 > gas_cost_2); - - let gas_cost_diff = gas_cost_3.checked_sub(gas_cost_2).unwrap_or_default(); - assert_eq!( - gas_cost_diff, - Gas::new(U512::from(HOST_FUNCTION_COST_CHANGE)) - ); } #[ignore] @@ -674,7 +656,7 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { .with_address(account_hash) .with_session_code(session_file, faucet_args_3) .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE + ARG_AMOUNT => U512::from(4_000_000_000u64) }) .with_authorization_keys(&[account_hash]) .with_deploy_hash(deploy_hash) @@ -692,12 +674,6 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { assert!(gas_cost_3 > gas_cost_1, "{} <= {}", gas_cost_3, gas_cost_1); assert!(gas_cost_3 > gas_cost_2); - - let gas_cost_diff = gas_cost_3.checked_sub(gas_cost_2).unwrap_or_default(); - assert_eq!( - gas_cost_diff, - Gas::new(U512::from(HOST_FUNCTION_COST_CHANGE)) - ); } struct TestContext { diff --git a/execution_engine_testing/tests/src/test/regression/mod.rs b/execution_engine_testing/tests/src/test/regression/mod.rs index cb37b8b74d..6cc2c98759 100644 --- a/execution_engine_testing/tests/src/test/regression/mod.rs +++ b/execution_engine_testing/tests/src/test/regression/mod.rs @@ -60,6 +60,7 @@ mod regression_20220223; mod regression_20220224; mod regression_20220303; mod regression_20220727; +mod regression_20240105; mod slow_input; pub(crate) mod test_utils; mod transforms_must_be_ordered; diff --git a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs index 8eff6e23e3..c5a8e61bcb 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs @@ -18,7 +18,7 @@ const CONTRACT_HASH_NAME: &str = "regression-contract-hash"; const REGRESSION_20211110_CONTRACT: &str = "regression_20211110.wasm"; const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([111; 32]); -const INSTALL_COST: u64 = 30_000_000_000; +const INSTALL_COST: u64 = 40_000_000_000; const STARTING_BALANCE: u64 = 100_000_000_000; #[ignore] diff --git a/execution_engine_testing/tests/src/test/regression/regression_20240105.rs b/execution_engine_testing/tests/src/test/regression/regression_20240105.rs new file mode 100644 index 0000000000..c555430f45 --- /dev/null +++ b/execution_engine_testing/tests/src/test/regression/regression_20240105.rs @@ -0,0 +1,1373 @@ +mod repeated_ffi_call_should_gas_out_quickly { + use std::{ + env, + sync::mpsc::{self, RecvTimeoutError}, + thread, + time::{Duration, Instant}, + }; + + use rand::Rng; + use tempfile::TempDir; + + use casper_engine_test_support::{ + ChainspecConfig, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, + DEFAULT_ACCOUNT_ADDR, PRODUCTION_CHAINSPEC_PATH, PRODUCTION_RUN_GENESIS_REQUEST, + }; + use casper_execution_engine::core::{ + engine_state::{EngineConfig, Error}, + execution::Error as ExecError, + }; + use casper_types::{ + account::AccountHash, runtime_args, testing::TestRng, RuntimeArgs, + DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, + }; + + const CONTRACT: &str = "regression_20240105.wasm"; + const TIMEOUT: Duration = Duration::from_secs(4); + const PAYMENT_AMOUNT: u64 = 1_000_000_000_000_u64; + + fn production_max_associated_keys() -> u8 { + let chainspec_config = + ChainspecConfig::from_chainspec_path(&*PRODUCTION_CHAINSPEC_PATH).unwrap(); + chainspec_config.max_associated_keys().try_into().unwrap() + } + + struct Fixture { + builder: LmdbWasmTestBuilder, + data_dir: TempDir, + rng: TestRng, + } + + impl Fixture { + fn new() -> Self { + let data_dir = TempDir::new().unwrap(); + let mut builder = LmdbWasmTestBuilder::new_with_production_chainspec(data_dir.path()); + builder + .run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST) + .commit(); + let rng = TestRng::new(); + Fixture { + builder, + data_dir, + rng, + } + } + + /// Calls regression_20240105.wasm with some setup function. Execution is expected to + /// succeed. + fn execute_setup(&mut self, session_args: RuntimeArgs) { + let payment_args = runtime_args! { "amount" => U512::from(PAYMENT_AMOUNT * 4) }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code(CONTRACT, session_args) + .with_empty_payment_bytes(payment_args) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash(self.rng.gen()) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy).build(); + self.builder.exec(exec_request).expect_success().commit(); + } + + /// Calls regression_20240105.wasm with expectation of execution failure due to running out + /// of gas within the duration specified in `TIMEOUT`. + fn execute_with_timeout(self, session_args: RuntimeArgs, extra_auth_keys: u8) { + if cfg!(debug_assertions) { + println!("not testing in debug mode"); + return; + } + let (tx, rx) = mpsc::channel(); + let Fixture { + builder, + data_dir, + mut rng, + } = self; + let post_state_hash = builder.get_post_state_hash(); + let mut auth_keys = Vec::new(); + auth_keys.push(*DEFAULT_ACCOUNT_ADDR); + for i in 1..=extra_auth_keys { + auth_keys.push(AccountHash::new([i; 32])); + } + let executor = thread::spawn(move || { + let payment_args = runtime_args! { "amount" => U512::from(PAYMENT_AMOUNT) }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code(CONTRACT, session_args) + .with_empty_payment_bytes(payment_args.clone()) + .with_authorization_keys(&auth_keys) + .with_deploy_hash(rng.gen()) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy).build(); + + let chainspec_config = + ChainspecConfig::from_chainspec_path(&*PRODUCTION_CHAINSPEC_PATH).unwrap(); + let mut engine_config = EngineConfig::from(chainspec_config); + // Increase the `max_memory` available in order to avoid hitting unreachable + // instruction during execution. + engine_config.set_max_memory(10_000); + let mut builder = + LmdbWasmTestBuilder::open(data_dir.path(), engine_config, post_state_hash); + let error = match builder.try_exec(exec_request) { + Ok(_) => builder.get_error().unwrap(), + Err(error) => error, + }; + let _ = tx.send(error); + }); + + let timeout = if let Ok(value) = env::var("CL_TEST_TIMEOUT_SECS") { + Duration::from_secs(value.parse().expect("should parse as u64")) + } else { + TIMEOUT + }; + let start = Instant::now(); + let receiver_result = rx.recv_timeout(timeout); + executor.join().unwrap(); + match receiver_result { + Ok(error) => { + assert!( + matches!(error, Error::Exec(ExecError::GasLimit)), + "expected gas limit error, but got {:?}", + error + ); + } + Err(RecvTimeoutError::Timeout) => { + panic!( + "execution should take less than {} seconds, but took {} seconds ", + timeout.as_secs_f32(), + start.elapsed().as_secs_f32(), + ) + } + Err(RecvTimeoutError::Disconnected) => unreachable!(), + } + } + } + + #[ignore] + #[test] + fn write_small() { + let session_args = runtime_args! { + "fn" => "write", + "len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn write_large() { + let session_args = runtime_args! { + "fn" => "write", + "len" => 100_000_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn read_missing() { + let session_args = runtime_args! { + "fn" => "read", + "len" => Option::::None, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn read_small() { + let session_args = runtime_args! { + "fn" => "read", + "len" => Some(1_u32), + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn read_large() { + let session_args = runtime_args! { + "fn" => "read", + "len" => Some(100_000_u32), + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn add_small() { + let session_args = runtime_args! { + "fn" => "add", + "large" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn add_large() { + let session_args = runtime_args! { + "fn" => "add", + "large" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn new_uref_small() { + let session_args = runtime_args! { + "fn" => "new", + "len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn new_uref_large() { + let session_args = runtime_args! { + "fn" => "new", + "len" => 1_000_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn call_contract_small_runtime_args() { + let session_args = runtime_args! { + "fn" => "call_contract", + "args_len" => 1_u32 + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn call_contract_large_runtime_args() { + let session_args = runtime_args! { + "fn" => "call_contract", + "args_len" => 1_024_u32 + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_key_small_name_missing_key() { + let session_args = runtime_args! { + "fn" => "get_key", + "large_name" => false, + "large_key" => Option::::None + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_key_small_name_small_key() { + let session_args = runtime_args! { + "fn" => "get_key", + "large_name" => false, + "large_key" => Some(false) + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_key_small_name_large_key() { + let session_args = runtime_args! { + "fn" => "get_key", + "large_name" => false, + "large_key" => Some(true) + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_key_large_name_small_key() { + let session_args = runtime_args! { + "fn" => "get_key", + "large_name" => true, + "large_key" => Some(false) + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_key_large_name_large_key() { + let session_args = runtime_args! { + "fn" => "get_key", + "large_name" => true, + "large_key" => Some(true) + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn has_key_small_name_missing_key() { + let session_args = runtime_args! { + "fn" => "has_key", + "large_name" => false, + "key_exists" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn has_key_small_name_existing_key() { + let session_args = runtime_args! { + "fn" => "has_key", + "large_name" => false, + "key_exists" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn has_key_large_name_missing_key() { + let session_args = runtime_args! { + "fn" => "has_key", + "large_name" => true, + "key_exists" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn has_key_large_name_existing_key() { + let session_args = runtime_args! { + "fn" => "has_key", + "large_name" => true, + "key_exists" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn put_key_small_name_small_key() { + let session_args = runtime_args! { + "fn" => "put_key", + "large_name" => false, + "large_key" => false, + "num_keys" => Option::::None + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn put_key_small_name_large_key() { + let session_args = runtime_args! { + "fn" => "put_key", + "large_name" => false, + "large_key" => true, + "num_keys" => Option::::None + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn put_key_large_name_small_key() { + let session_args = runtime_args! { + "fn" => "put_key", + "large_name" => true, + "large_key" => false, + "num_keys" => Option::::None + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn put_key_large_name_large_key() { + let session_args = runtime_args! { + "fn" => "put_key", + "large_name" => true, + "large_key" => true, + "num_keys" => Option::::None + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn is_valid_uref_for_invalid() { + let session_args = runtime_args! { + "fn" => "is_valid_uref", + "valid" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn is_valid_uref_for_valid() { + let session_args = runtime_args! { + "fn" => "is_valid_uref", + "valid" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn add_and_remove_associated_key() { + let session_args = runtime_args! { + "fn" => "add_associated_key", + "remove_after_adding" => true, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn add_associated_key_duplicated() { + let session_args = runtime_args! { + "fn" => "add_associated_key", + "remove_after_adding" => false, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn remove_associated_key_non_existent() { + let session_args = runtime_args! { "fn" => "remove_associated_key" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn update_associated_key_non_existent() { + let session_args = runtime_args! { + "fn" => "update_associated_key", + "exists" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn update_associated_key_existing() { + let session_args = runtime_args! { + "fn" => "update_associated_key", + "exists" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn set_action_threshold() { + let session_args = runtime_args! { "fn" => "set_action_threshold" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn load_named_keys_empty() { + let session_args = runtime_args! { + "fn" => "load_named_keys", + "num_keys" => 0_u32, + "large_name" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn load_named_keys_one_key_small_name() { + let num_keys = 1_u32; + let mut fixture = Fixture::new(); + let session_args = runtime_args! { + "fn" => "put_key", + "large_name" => false, + "large_key" => true, + "num_keys" => Some(num_keys), + }; + fixture.execute_setup(session_args); + let session_args = runtime_args! { + "fn" => "load_named_keys", + "num_keys" => num_keys + }; + fixture.execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn load_named_keys_one_key_large_name() { + let num_keys = 1_u32; + let mut fixture = Fixture::new(); + let session_args = runtime_args! { + "fn" => "put_key", + "large_name" => true, + "large_key" => true, + "num_keys" => Some(num_keys), + }; + fixture.execute_setup(session_args); + let session_args = runtime_args! { + "fn" => "load_named_keys", + "num_keys" => num_keys, + }; + fixture.execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn load_named_keys_many_keys_small_name() { + let num_keys = 1_000_u32; + let mut fixture = Fixture::new(); + let session_args = runtime_args! { + "fn" => "put_key", + "large_name" => false, + "large_key" => true, + "num_keys" => Some(num_keys), + }; + fixture.execute_setup(session_args); + let session_args = runtime_args! { + "fn" => "load_named_keys", + "num_keys" => num_keys, + }; + fixture.execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn load_named_keys_many_keys_large_name() { + let num_keys = 10_u32; + let mut fixture = Fixture::new(); + let session_args = runtime_args! { + "fn" => "put_key", + "large_name" => true, + "large_key" => true, + "num_keys" => Some(num_keys), + }; + fixture.execute_setup(session_args); + let session_args = runtime_args! { + "fn" => "load_named_keys", + "num_keys" => num_keys, + }; + fixture.execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn remove_key_small_name() { + let session_args = runtime_args! { + "fn" => "remove_key", + "large_name" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn remove_key_large_name() { + let session_args = runtime_args! { + "fn" => "remove_key", + "large_name" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_caller() { + let session_args = runtime_args! { "fn" => "get_caller" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_blocktime() { + let session_args = runtime_args! { "fn" => "get_blocktime" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_purse() { + let session_args = runtime_args! { "fn" => "create_purse" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn transfer_to_account_create_account() { + let session_args = runtime_args! { + "fn" => "transfer_to_account", + "account_exists" => false, + "amount" => U512::MAX + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn transfer_to_account_existing_account() { + let session_args = runtime_args! { + "fn" => "transfer_to_account", + "account_exists" => true, + "amount" => U512::MAX + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn transfer_from_purse_to_account_create_account() { + let session_args = runtime_args! { + "fn" => "transfer_from_purse_to_account", + "account_exists" => false, + "amount" => U512::MAX + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn transfer_from_purse_to_account_existing_account() { + let session_args = runtime_args! { + "fn" => "transfer_from_purse_to_account", + "account_exists" => true, + "amount" => U512::MAX + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn transfer_from_purse_to_purse() { + let session_args = runtime_args! { + "fn" => "transfer_from_purse_to_purse", + "amount" => U512::MAX + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_balance_non_existent_purse() { + let session_args = runtime_args! { + "fn" => "get_balance", + "purse_exists" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_balance_existing_purse() { + let session_args = runtime_args! { + "fn" => "get_balance", + "purse_exists" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_phase() { + let session_args = runtime_args! { "fn" => "get_phase" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_system_contract() { + let session_args = runtime_args! { "fn" => "get_system_contract" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_main_purse() { + let session_args = runtime_args! { "fn" => "get_main_purse" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn read_host_buffer_empty() { + let session_args = runtime_args! { "fn" => "read_host_buffer" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_package_at_hash() { + let session_args = runtime_args! { "fn" => "create_contract_package_at_hash" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn add_contract_version_no_entry_points_no_named_keys() { + let session_args = runtime_args! { + "fn" => "add_contract_version", + "entry_points_len" => 0_u32, + "named_keys_len" => 0_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn add_contract_version_small_entry_points_small_named_keys() { + let session_args = runtime_args! { + "fn" => "add_contract_version", + "entry_points_len" => 1_u32, + "named_keys_len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn add_contract_version_small_entry_points_large_named_keys() { + let session_args = runtime_args! { + "fn" => "add_contract_version", + "entry_points_len" => 1_u32, + "named_keys_len" => 100_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn add_contract_version_large_entry_points_small_named_keys() { + let session_args = runtime_args! { + "fn" => "add_contract_version", + "entry_points_len" => 100_u32, + "named_keys_len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn add_contract_version_large_entry_points_large_named_keys() { + let session_args = runtime_args! { + "fn" => "add_contract_version", + "entry_points_len" => 100_u32, + "named_keys_len" => 100_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn disable_contract_version() { + let session_args = runtime_args! { "fn" => "disable_contract_version" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn call_versioned_contract_small_runtime_args() { + let session_args = runtime_args! { + "fn" => "call_versioned_contract", + "args_len" => 1_u32 + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn call_versioned_contract_large_runtime_args() { + let session_args = runtime_args! { + "fn" => "call_versioned_contract", + "args_len" => 1_024_u32 + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_small_label_no_new_urefs_no_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 0_u8, + "num_existing_urefs" => 0_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_small_label_no_new_urefs_few_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 0_u8, + "num_existing_urefs" => 1_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_small_label_no_new_urefs_many_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 0_u8, + "num_existing_urefs" => 10_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_small_label_few_new_urefs_no_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 1_u8, + "num_existing_urefs" => 0_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_small_label_few_new_urefs_few_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 1_u8, + "num_existing_urefs" => 1_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_small_label_few_new_urefs_many_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 1_u8, + "num_existing_urefs" => 5_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_small_label_many_new_urefs_no_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 5_u8, + "num_existing_urefs" => 0_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_small_label_many_new_urefs_few_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 5_u8, + "num_existing_urefs" => 1_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_small_label_many_new_urefs_many_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 5_u8, + "num_existing_urefs" => 5_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_large_label_no_new_urefs_no_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_000_000_u32, + "num_new_urefs" => 0_u8, + "num_existing_urefs" => 0_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_large_label_no_new_urefs_few_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_000_000_u32, + "num_new_urefs" => 0_u8, + "num_existing_urefs" => 1_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_large_label_no_new_urefs_many_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_000_000_u32, + "num_new_urefs" => 0_u8, + "num_existing_urefs" => 10_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_large_label_few_new_urefs_no_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_000_000_u32, + "num_new_urefs" => 1_u8, + "num_existing_urefs" => 0_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_large_label_few_new_urefs_few_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_000_000_u32, + "num_new_urefs" => 1_u8, + "num_existing_urefs" => 1_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_large_label_few_new_urefs_many_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_000_000_u32, + "num_new_urefs" => 1_u8, + "num_existing_urefs" => 5_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_large_label_many_new_urefs_no_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_000_000_u32, + "num_new_urefs" => 5_u8, + "num_existing_urefs" => 0_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_large_label_many_new_urefs_few_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_000_000_u32, + "num_new_urefs" => 5_u8, + "num_existing_urefs" => 1_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_large_label_many_new_urefs_many_existing_urefs() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_000_000_u32, + "num_new_urefs" => 5_u8, + "num_existing_urefs" => 5_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_failure_max_urefs_exceeded() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => u8::MAX, + "num_existing_urefs" => 0_u8, + "allow_exceeding_max_groups" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn create_contract_user_group_failure_max_groups_exceeded() { + let session_args = runtime_args! { + "fn" => "create_contract_user_group", + "label_len" => 1_u32, + "num_new_urefs" => 0_u8, + "num_existing_urefs" => 0_u8, + "allow_exceeding_max_groups" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + // #[ignore] + // #[test] + // fn print_small() { + // let session_args = runtime_args! { + // "fn" => "print", + // "num_chars" => 1_u32 + // }; + // Fixture::new().execute_with_timeout(session_args, 0) + // } + // + // #[ignore] + // #[test] + // fn print_large() { + // let session_args = runtime_args! { + // "fn" => "print", + // "num_chars" => 1_000_000_u32 + // }; + // Fixture::new().execute_with_timeout(session_args, 0) + // } + + #[ignore] + #[test] + fn get_runtime_arg_size_zero() { + let session_args = runtime_args! { + "fn" => "get_runtime_arg_size", + "arg" => () + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_runtime_arg_size_small() { + let session_args = runtime_args! { + "fn" => "get_runtime_arg_size", + "arg" => 1_u8 + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_runtime_arg_size_large() { + let session_args = runtime_args! { + "fn" => "get_runtime_arg_size", + "arg" => [1_u8; 1_000_000] + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_runtime_arg_zero_size() { + let session_args = runtime_args! { + "fn" => "get_runtime_arg", + "arg" => () + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_runtime_arg_small_size() { + let session_args = runtime_args! { + "fn" => "get_runtime_arg", + "arg" => 1_u8 + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn get_runtime_arg_large_size() { + let session_args = runtime_args! { + "fn" => "get_runtime_arg", + "arg" => [1_u8; 1_000_000] + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn remove_contract_user_group() { + let session_args = runtime_args! { "fn" => "remove_contract_user_group" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn extend_contract_user_group_urefs_and_remove_as_required() { + let session_args = runtime_args! { + "fn" => "extend_contract_user_group_urefs", + "allow_exceeding_max_urefs" => false + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn extend_contract_user_group_urefs_failure_max_urefs_exceeded() { + let session_args = runtime_args! { + "fn" => "extend_contract_user_group_urefs", + "allow_exceeding_max_urefs" => true + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn remove_contract_user_group_urefs() { + let session_args = runtime_args! { "fn" => "remove_contract_user_group_urefs" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn blake2b_small() { + let session_args = runtime_args! { + "fn" => "blake2b", + "len" => 1_u32 + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn blake2b_large() { + let session_args = runtime_args! { + "fn" => "blake2b", + "len" => 1_000_000_u32 + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn new_dictionary() { + let session_args = runtime_args! { "fn" => "new_dictionary" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_get_small_name_small_value() { + let session_args = runtime_args! { + "fn" => "dictionary_get", + "name_len" => 1_u32, + "value_len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_get_small_name_large_value() { + let session_args = runtime_args! { + "fn" => "dictionary_get", + "name_len" => 1_u32, + "value_len" => 1_000_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_get_large_name_small_value() { + let session_args = runtime_args! { + "fn" => "dictionary_get", + "name_len" => DICTIONARY_ITEM_KEY_MAX_LENGTH as u32 - 4, + "value_len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_get_large_name_large_value() { + let session_args = runtime_args! { + "fn" => "dictionary_get", + "name_len" => DICTIONARY_ITEM_KEY_MAX_LENGTH as u32 - 4, + "value_len" => 1_000_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_put_small_name_small_value() { + let session_args = runtime_args! { + "fn" => "dictionary_put", + "name_len" => 1_u32, + "value_len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_put_small_name_large_value() { + let session_args = runtime_args! { + "fn" => "dictionary_put", + "name_len" => 1_u32, + "value_len" => 1_000_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_put_large_name_small_value() { + let session_args = runtime_args! { + "fn" => "dictionary_put", + "name_len" => DICTIONARY_ITEM_KEY_MAX_LENGTH as u32 - 4, + "value_len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_put_large_name_large_value() { + let session_args = runtime_args! { + "fn" => "dictionary_put", + "name_len" => DICTIONARY_ITEM_KEY_MAX_LENGTH as u32 - 4, + "value_len" => 1_000_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn load_call_stack() { + let session_args = runtime_args! { "fn" => "load_call_stack" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn load_authorization_keys_small() { + let session_args = runtime_args! { + "fn" => "load_authorization_keys", + "setup" => false, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn load_authorization_keys_large() { + let session_args = runtime_args! { + "fn" => "load_authorization_keys", + "setup" => true, + }; + let mut fixture = Fixture::new(); + fixture.execute_setup(session_args); + let session_args = runtime_args! { + "fn" => "load_authorization_keys", + "setup" => false, + }; + fixture.execute_with_timeout(session_args, production_max_associated_keys() - 1) + } + + #[ignore] + #[test] + fn random_bytes() { + let session_args = runtime_args! { "fn" => "random_bytes" }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_read_small_name_small_value() { + let session_args = runtime_args! { + "fn" => "dictionary_read", + "name_len" => 1_u32, + "value_len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_read_small_name_large_value() { + let session_args = runtime_args! { + "fn" => "dictionary_read", + "name_len" => 1_u32, + "value_len" => 1_000_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_read_large_name_small_value() { + let session_args = runtime_args! { + "fn" => "dictionary_read", + "name_len" => DICTIONARY_ITEM_KEY_MAX_LENGTH as u32 - 4, + "value_len" => 1_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn dictionary_read_large_name_large_value() { + let session_args = runtime_args! { + "fn" => "dictionary_read", + "name_len" => DICTIONARY_ITEM_KEY_MAX_LENGTH as u32 - 4, + "value_len" => 1_000_u32, + }; + Fixture::new().execute_with_timeout(session_args, 0) + } + + #[ignore] + #[test] + fn enable_contract_version() { + let session_args = runtime_args! { "fn" => "enable_contract_version" }; + Fixture::new().execute_with_timeout(session_args, 0) + } +} diff --git a/execution_engine_testing/tests/src/test/storage_costs.rs b/execution_engine_testing/tests/src/test/storage_costs.rs index 15d9191844..e6e7d91444 100644 --- a/execution_engine_testing/tests/src/test/storage_costs.rs +++ b/execution_engine_testing/tests/src/test/storage_costs.rs @@ -139,6 +139,7 @@ static NEW_HOST_FUNCTION_COSTS: Lazy = Lazy::new(|| HostFunct blake2b: HostFunction::fixed(0), random_bytes: HostFunction::fixed(0), enable_contract_version: HostFunction::fixed(0), + risc0_verifier: HostFunction::fixed(0) }); static STORAGE_COSTS_ONLY: Lazy = Lazy::new(|| { WasmConfig::new( diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index 3644035978..e1d8fa22a3 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -979,6 +979,7 @@ fn should_verify_wasm_add_bid_wasm_cost_is_not_recursive() { blake2b: HostFunction::fixed(0), random_bytes: HostFunction::fixed(0), enable_contract_version: HostFunction::fixed(0), + risc0_verifier: HostFunction::fixed(0) }; let new_wasm_config = WasmConfig::new( diff --git a/kairos-delta-tree/Cargo.lock b/kairos-delta-tree/Cargo.lock new file mode 100644 index 0000000000..7b0ebf3dd1 --- /dev/null +++ b/kairos-delta-tree/Cargo.lock @@ -0,0 +1,307 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "kairos-delta-tree" +version = "0.1.0" +dependencies = [ + "digest", + "serde", + "sha2", + "sha256", + "uint", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha256" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" +dependencies = [ + "async-trait", + "bytes", + "hex", + "sha2", + "tokio", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "2.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "pin-project-lite", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/kairos-delta-tree/Cargo.toml b/kairos-delta-tree/Cargo.toml new file mode 100644 index 0000000000..0e71218dab --- /dev/null +++ b/kairos-delta-tree/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "kairos-delta-tree" +version = "0.1.0" +edition = "2021" + +[dependencies] +sha256 = "1.4.0" +uint = "0.9.0" +sha2 = "0.10.0" +digest = "0.10.0" +serde = {version="1.0.197", features=["derive"]} diff --git a/kairos-delta-tree/readme.md b/kairos-delta-tree/readme.md new file mode 100644 index 0000000000..11a311d66e --- /dev/null +++ b/kairos-delta-tree/readme.md @@ -0,0 +1,8 @@ +# Kairos Delta Tree for native Transaction Rollup +This implementation of a fixed-size Merkle Tree stores only the leafs affected by an insertion. Additionally, I implemeted a function to verify the integrity of an insert operation similar to how a merkle proof are used. + +# Run tests + +```rust +cargo test -- --nocapture +``` \ No newline at end of file diff --git a/kairos-delta-tree/src/crypto.rs b/kairos-delta-tree/src/crypto.rs new file mode 100644 index 0000000000..9783499a5b --- /dev/null +++ b/kairos-delta-tree/src/crypto.rs @@ -0,0 +1,14 @@ +extern crate sha256; +use sha2::{Sha256, Digest}; + +pub fn hash_bytes(input: Vec) -> Vec { + let mut hasher = Sha256::new(); + hasher.update(input); + let result = hasher.finalize(); + result.to_vec() +} + +pub fn hash_left_right(mut left: Vec, mut right: Vec) -> Vec{ + left.append(&mut right); + hash_bytes(left) +} \ No newline at end of file diff --git a/kairos-delta-tree/src/lib.rs b/kairos-delta-tree/src/lib.rs new file mode 100644 index 0000000000..c1c55e15f3 --- /dev/null +++ b/kairos-delta-tree/src/lib.rs @@ -0,0 +1,103 @@ +pub mod crypto; +use crypto::hash_left_right; +use serde::{Serialize, Deserialize}; + +pub const ROOT_HISTORY_SIZE: u16 = 30u16; +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct KairosDeltaTree{ + pub zero_node: Vec, + pub zero_levels: Vec>, + pub filled: Vec>, + pub root: Option>, + pub index: usize, + pub depth: usize +} + +impl KairosDeltaTree{ + pub fn calculate_zero_levels(&mut self){ + let mut zero_levels: Vec> = vec![self.zero_node.clone()]; + for i in 0..self.depth - 1{ + zero_levels.push(hash_left_right(zero_levels[zero_levels.len()-1].clone(), zero_levels[zero_levels.len()-1].clone())); + }; + self.zero_levels = zero_levels; + } + pub fn add_leaf(&mut self, leaf: Vec){ + // does depth even matter? + /*if !self.index > 2usize.pow(self.depth as u32){ + + }*/ + let mut current_index = self.index; + let mut current_hash: Vec = leaf.clone(); + for i in 0..self.depth { + if current_index % 2 == 0 { + self.filled[i] = current_hash.clone(); + current_hash = hash_left_right(current_hash, self.zero_levels[i].clone()); + } else { + let left = self.filled[i].clone(); + current_hash = hash_left_right(left.clone(), current_hash.clone()); + } + current_index /= 2; + } + //let current_root: Vec = self.filled.clone().pop().unwrap(); + self.root = Some(current_hash); + self.index += 1; + } + pub fn merkle_proof(&mut self, leaf: Vec) -> Vec{ + let mut current_index = self.index - 1; + let mut current_hash: Vec = leaf.clone(); + for i in 0..self.depth{ + if current_index % 2 == 0 { + current_hash = hash_left_right(current_hash, self.zero_levels[i].clone()); + } + else{ + current_hash = hash_left_right(self.filled[i].clone(), current_hash.clone()); + } + current_index /= 2; + } + current_hash + } +} + +#[test] +fn test_tree(){ + use crypto::hash_bytes; + // construct merkle tree + let mut tree: KairosDeltaTree = KairosDeltaTree{ + zero_node: hash_bytes(vec![0;32]), + zero_levels: Vec::new(), + filled: vec![vec![], vec![], vec![], vec![], vec![]], + root: None, + index: 0, + depth: 5 + }; + tree.calculate_zero_levels(); + let leaf = vec![242, 69, 81, 38, 252, 95, 197, 129, 177, 105, 42, 137, 129, 73, 125, 148, 130, 204, 83, 82, 126, 104, 106, 71, 156, 96, 55, 233, 132, 103, 128, 11]; + let _ = tree.add_leaf(leaf.clone()); + let merkle_root: Option> = tree.root.clone(); + assert_eq!(tree.merkle_proof(leaf.clone()), merkle_root.clone().unwrap()); + println!("First root: {:?}", &merkle_root.unwrap()); + + let _ = tree.add_leaf(leaf.clone()); + let merkle_root = tree.root.clone(); + assert_eq!(tree.merkle_proof(leaf.clone()), merkle_root.clone().unwrap()); + println!("Second root: {:?}", &merkle_root.unwrap()); +} + +#[test] +fn space(){ + use crypto::hash_bytes; + let mut tree: KairosDeltaTree = KairosDeltaTree{ + zero_node: hash_bytes(vec![0;32]), + zero_levels: Vec::new(), + filled: vec![vec![], vec![], vec![], vec![], vec![]], + root: None, + index: 0, + depth: 5 + }; + tree.calculate_zero_levels(); + let leaf = vec![242, 69, 81, 38, 252, 95, 197, 129, 177, 105, 42, 137, 129, 73, 125, 148, 130, 204, 83, 82, 126, 104, 106, 71, 156, 96, 55, 233, 132, 103, 128, 11]; + for i in 0..255{ + tree.add_leaf(leaf.clone()); + println!("Tree: {:?} \n", &tree); + } +} \ No newline at end of file diff --git a/kairos-risc0-types/Cargo.lock b/kairos-risc0-types/Cargo.lock new file mode 100644 index 0000000000..db7cdc2b00 --- /dev/null +++ b/kairos-risc0-types/Cargo.lock @@ -0,0 +1,821 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake2" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" +dependencies = [ + "crypto-mac", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "casper-types" +version = "4.0.1" +source = "git+https://github.com/jonas089/casper-node?branch=kairos-1.5.6#9f3995853204a18f17de9c022233d22aa14b9c37" +dependencies = [ + "base16", + "base64", + "bitflags", + "blake2", + "ed25519-dalek", + "hex", + "hex_fmt", + "k256", + "num", + "num-derive", + "num-integer", + "num-rational", + "num-traits", + "rand", + "serde", + "serde_bytes", + "serde_json", + "uint", +] + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex_fmt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2", +] + +[[package]] +name = "kairos-delta-tree" +version = "0.1.0" +dependencies = [ + "digest 0.10.7", + "serde", + "sha2", + "sha256", + "uint", +] + +[[package]] +name = "kairos-risc0-types" +version = "0.1.0" +dependencies = [ + "casper-types", + "kairos-delta-tree", + "serde", + "serde-json-wasm", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "num" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha256" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" +dependencies = [ + "async-trait", + "bytes", + "hex", + "sha2", + "tokio", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "pin-project-lite", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/kairos-risc0-types/Cargo.toml b/kairos-risc0-types/Cargo.toml new file mode 100644 index 0000000000..fee5763640 --- /dev/null +++ b/kairos-risc0-types/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "kairos-risc0-types" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = {version="1.0.197", features=["derive"]} +serde-json-wasm = "1.0.1" +kairos-delta-tree = {path="../kairos-delta-tree", optional=true} +casper-types = {path="../types"} +[features] \ No newline at end of file diff --git a/kairos-risc0-types/src/constants.rs b/kairos-risc0-types/src/constants.rs new file mode 100644 index 0000000000..47b6fbccd8 --- /dev/null +++ b/kairos-risc0-types/src/constants.rs @@ -0,0 +1,5 @@ +pub const FORMATTED_DEFAULT_ACCOUNT_STR: &str = "account-hash-32da6919b3a0a9be4bc5b38fa74de98f90dc43924bf17e73f6635992f110f011"; +pub const RPC_PORT: &str = "11101"; +pub const NODE_ADDRESS: &str = "http://127.0.0.1:11101/rpc"; +pub const FORMATTED_COUNTER_UREF: &str = "uref-SOMETHING"; +pub const FORMATTED_DICT_UREF: &str = "uref-SOMETHING"; \ No newline at end of file diff --git a/kairos-risc0-types/src/lib.rs b/kairos-risc0-types/src/lib.rs new file mode 100644 index 0000000000..b7d73e8814 --- /dev/null +++ b/kairos-risc0-types/src/lib.rs @@ -0,0 +1,95 @@ +use serde::{Serialize, Deserialize}; +use casper_types::{Key, U512, URef}; +use std::collections::HashMap; +mod tests; +pub mod constants; + +#[cfg(feature = "kairos-delta-tree")] +pub use kairos_delta_tree::{KairosDeltaTree, crypto::hash_bytes}; +// The decision to use "Key" over more deterministic types is based on the variable design +// with respect to target node architecture. Everything will be handled in Bytes and Keys. + +pub trait HashableStruct{ + fn hash(&self) -> Vec; +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct RiscZeroProof{ + pub receipt_serialized: Vec, + pub program_id: Vec +} + +#[cfg(feature = "kairos-delta-tree")] +#[derive(Serialize,Deserialize, Debug, Clone, PartialEq)] +pub struct TransactionBatch{ + pub deposits: Vec, + pub transfers : Vec, + pub withdrawals: Vec +} +// Hash the Batch as a struct +#[cfg(feature = "kairos-delta-tree")] +impl HashableStruct for TransactionBatch{ + fn hash(&self) -> Vec{ + hash_bytes(serde_json_wasm::to_vec(self).unwrap()) + } +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct Deposit { + pub account: Key, + pub amount: U512, + pub timestamp: Option, + pub processed: bool, +} +#[cfg(feature = "kairos-delta-tree")] +impl HashableStruct for Deposit{ + fn hash(&self) -> Vec{ + hash_bytes(serde_json_wasm::to_vec(self).unwrap()) + } +} + + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct Withdrawal { + pub account: Key, + pub amount: U512, + pub timestamp: String, + pub processed: bool, +} +#[cfg(feature = "kairos-delta-tree")] +impl HashableStruct for Withdrawal{ + fn hash(&self) -> Vec{ + hash_bytes(serde_json_wasm::to_vec(self).unwrap()) + } +} + +#[cfg(feature = "kairos-delta-tree")] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct Transfer { + pub sender: Key, + pub recipient: Key, + pub amount: U512, + pub timestamp: String, + pub signature: Vec, + pub processed: bool, + pub nonce: u64 +} +#[cfg(feature = "kairos-delta-tree")] +impl HashableStruct for Transfer{ + fn hash(&self) -> Vec{ + hash_bytes(serde_json_wasm::to_vec(self).unwrap()) + } +} +#[cfg(feature = "kairos-delta-tree")] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct CircuitArgs{ + pub tree: KairosDeltaTree, + pub batch: TransactionBatch +} + +#[cfg(feature = "kairos-delta-tree")] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct CircuitJournal{ + pub input: KairosDeltaTree, + pub output: KairosDeltaTree +} \ No newline at end of file diff --git a/kairos-risc0-types/src/tests.rs b/kairos-risc0-types/src/tests.rs new file mode 100644 index 0000000000..7195663617 --- /dev/null +++ b/kairos-risc0-types/src/tests.rs @@ -0,0 +1,14 @@ +#[cfg(feature = "tornado-tree")] +#[test] +fn try_hash_batch(){ + use crate::{Deposit, Withdrawal, Transfer, TransactionBatch, HashableStruct}; + let transfers: Vec = vec![]; + let deposits: Vec = vec![]; + let withdrawals: Vec = vec![]; + let batch = TransactionBatch{ + transfers, + deposits, + withdrawals + }; + println!("Transaction History Hash: {:?}", batch.hash()); +} \ No newline at end of file diff --git a/node/CHANGELOG.md b/node/CHANGELOG.md index 45b00b7772..137581ee6f 100644 --- a/node/CHANGELOG.md +++ b/node/CHANGELOG.md @@ -11,6 +11,15 @@ All notable changes to this project will be documented in this file. The format +## 1.5.6 + +### Changed +* The node will recognise if a pending upgrade is unstaged and will avoid shutting down for upgrade in this case. +* If an upgrade with the same activation point as the current one is detected on startup, the node will immediately shut down for upgrade. +* Reduce chainspec setting `deploys.max_ttl` from 18 hours to 2 hours. + + + ## 1.5.5 ### Added diff --git a/node/Cargo.toml b/node/Cargo.toml index d162d3dbf3..733b33e2ac 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "casper-node" -version = "1.5.5" # when updating, also update 'html_root_url' in lib.rs +version = "1.5.6" # when updating, also update 'html_root_url' in lib.rs authors = ["Marc Brinkmann ", "Fraser Hutchison "] edition = "2021" description = "The Casper blockchain node" @@ -22,10 +22,10 @@ base16 = "0.2.1" base64 = "0.13.0" bincode = "1" bytes = "1.0.1" -casper-execution-engine = { version = "7.0.0", path = "../execution_engine" } +casper-execution-engine = { version = "7.0.1", path = "../execution_engine" } casper-hashing = { version = "3.0.0", path = "../hashing" } casper-json-rpc = { version = "1.1.0", path = "../json_rpc" } -casper-types = { version = "4.0.1", path = "../types", features = ["datasize", "json-schema", "std-fs-io"] } +casper-types = { version = "4.0.1", path = "../types", features = ["datasize", "json-schema", "std"] } datasize = { version = "0.2.11", features = ["detailed", "fake_clock-types", "futures-types", "smallvec-types"] } derive_more = "0.99.7" either = { version = "1", features = ["serde"] } @@ -97,7 +97,7 @@ vergen = { version = "8.2.1", default-features = false, features = ["git", "gito [dev-dependencies] assert-json-diff = "2.0.1" assert_matches = "1.5.0" -casper-types = { path = "../types", features = ["datasize", "json-schema", "std-fs-io", "testing"] } +casper-types = { path = "../types", features = ["datasize", "json-schema", "std", "testing"] } fake_instant = "0.4.0" pnet = "0.28.0" pretty_assertions = "0.7.2" diff --git a/node/src/components/block_accumulator.rs b/node/src/components/block_accumulator.rs index a32be89591..00a448e658 100644 --- a/node/src/components/block_accumulator.rs +++ b/node/src/components/block_accumulator.rs @@ -170,9 +170,12 @@ impl BlockAccumulator { } } - /// Register activation point from next protocol version chainspec. - pub(crate) fn register_activation_point(&mut self, activation_point: ActivationPoint) { - self.activation_point = Some(activation_point); + /// Register activation point from next protocol version chainspec, if any. + pub(crate) fn register_activation_point( + &mut self, + maybe_activation_point: Option, + ) { + self.activation_point = maybe_activation_point; } /// Drops all old block acceptors and tracks new local block height; diff --git a/node/src/components/block_accumulator/tests.rs b/node/src/components/block_accumulator/tests.rs index 58d4066af0..8d5d2f04b0 100644 --- a/node/src/components/block_accumulator/tests.rs +++ b/node/src/components/block_accumulator/tests.rs @@ -957,7 +957,7 @@ fn accumulator_should_leap() { } let upgrade_attempt_execution_threshold = attempt_execution_threshold * 2; - block_accumulator.register_activation_point(ActivationPoint::EraId(era_id.successor())); + block_accumulator.register_activation_point(Some(ActivationPoint::EraId(era_id.successor()))); let offset = centurion.saturating_sub(upgrade_attempt_execution_threshold); for height in offset..centurion { expected_leap_instruction( diff --git a/node/src/components/consensus/consensus_protocol.rs b/node/src/components/consensus/consensus_protocol.rs index 4c035e7b3e..016530d99d 100644 --- a/node/src/components/consensus/consensus_protocol.rs +++ b/node/src/components/consensus/consensus_protocol.rs @@ -200,7 +200,7 @@ pub(crate) enum ProtocolOutcome { ScheduleTimer(Timestamp, TimerId), QueueAction(ActionId), /// Request deploys for a new block, providing the necessary context. - CreateNewBlock(BlockContext), + CreateNewBlock(BlockContext, Timestamp), /// A block was finalized. FinalizedBlock(FinalizedBlock), /// Request validation of the consensus value, contained in a message received from the given diff --git a/node/src/components/consensus/era_supervisor.rs b/node/src/components/consensus/era_supervisor.rs index 8fb7ecab17..4ac3a6efd6 100644 --- a/node/src/components/consensus/era_supervisor.rs +++ b/node/src/components/consensus/era_supervisor.rs @@ -1033,7 +1033,7 @@ impl EraSupervisor { ProtocolOutcome::QueueAction(action_id) => effect_builder .immediately() .event(move |()| Event::Action { era_id, action_id }), - ProtocolOutcome::CreateNewBlock(block_context) => { + ProtocolOutcome::CreateNewBlock(block_context, proposal_expiry) => { let accusations = self .iter_past(era_id, PAST_EVIDENCE_ERAS) .flat_map(|e_id| self.era(e_id).consensus.validators_with_evidence()) @@ -1050,7 +1050,9 @@ impl EraSupervisor { .set_timeout(Duration::from_millis(delay)) .await; } - let appendable_block = effect_builder.request_appendable_block(timestamp).await; + let appendable_block = effect_builder + .request_appendable_block(timestamp, proposal_expiry) + .await; Arc::new(appendable_block.into_block_payload(accusations, random_bit)) } .event(move |block_payload| { diff --git a/node/src/components/consensus/highway_core/active_validator.rs b/node/src/components/consensus/highway_core/active_validator.rs index cfa8299445..71871317ad 100644 --- a/node/src/components/consensus/highway_core/active_validator.rs +++ b/node/src/components/consensus/highway_core/active_validator.rs @@ -35,7 +35,9 @@ pub(crate) enum Effect { ScheduleTimer(Timestamp), /// `propose` needs to be called with a value for a new block with the specified block context /// and parent value. - RequestNewBlock(BlockContext), + /// The timestamp is the time at which the witness unit will be sent, which will invalidate the + /// proposal - so any response to this request has to be received before that time. + RequestNewBlock(BlockContext, Timestamp), /// This validator is faulty. /// /// When this is returned, the validator automatically deactivates. @@ -192,7 +194,8 @@ impl ActiveValidator { // Only create new units if enough validators are online. if !self.paused && self.enough_validators_online(state, timestamp) { if timestamp == r_id && state.leader(r_id) == self.vidx { - effects.extend(self.request_new_block(state, instance_id, timestamp)); + let expiry = r_id.saturating_add(self.proposal_request_expiry(r_len)); + effects.extend(self.request_new_block(state, instance_id, timestamp, expiry)); return effects; } else if timestamp == r_id.saturating_add(self.witness_offset(r_len)) { let panorama = self.panorama_at(state, timestamp); @@ -309,6 +312,7 @@ impl ActiveValidator { state: &State, instance_id: C::InstanceId, timestamp: Timestamp, + expiry: Timestamp, ) -> Option> { if let Some((prop_context, _)) = self.next_proposal.take() { warn!(?prop_context, "no proposal received; requesting new one"); @@ -331,7 +335,7 @@ impl ActiveValidator { }; let block_context = BlockContext::new(timestamp, ancestor_values); self.next_proposal = Some((block_context.clone(), panorama)); - Some(Effect::RequestNewBlock(block_context)) + Some(Effect::RequestNewBlock(block_context, expiry)) } /// Proposes a new block with the given consensus value. @@ -535,6 +539,17 @@ impl ActiveValidator { round_len * 2 / 3 } + /// Returns the duration after the beginning of a round during which a response to a proposal + /// request has to be returned. + #[allow(clippy::arithmetic_side_effects)] // Round length will never be large enough to overflow. + fn proposal_request_expiry(&self, round_len: TimeDiff) -> TimeDiff { + // The time window is 1/6 of the round length - but no shorter than 500 ms, unless that's + // longer than the witness offset, in which case it's just the witness offset. + (round_len / 6) + .max(TimeDiff::from_millis(500)) + .min(self.witness_offset(round_len)) + } + /// The round length of the round containing `timestamp`. /// /// This returns `self.next_round_len`, if that is a valid round length for a unit cast at @@ -913,8 +928,8 @@ mod tests { // 416, and the first witness tick 426. // Alice wants to propose a block, and also make her witness unit at 426. let bctx = match &*test.handle_timer(ALICE, 416.into()) { - [Eff::ScheduleTimer(timestamp), Eff::RequestNewBlock(bctx)] - if *timestamp == 426.into() => + [Eff::ScheduleTimer(timestamp), Eff::RequestNewBlock(bctx, expiry)] + if *timestamp == 426.into() && *expiry == 426.into() => { bctx.clone() } @@ -1065,7 +1080,7 @@ mod tests { // After synchronizing the protocol state up until `last_own_unit`, Alice can now propose a // new block. let bctx = match &*alice.handle_timer(next_proposal_timer, &state, instance_id) { - [Eff::ScheduleTimer(_), Eff::RequestNewBlock(bctx)] => bctx.clone(), + [Eff::ScheduleTimer(_), Eff::RequestNewBlock(bctx, _)] => bctx.clone(), effects => panic!("unexpected effects {:?}", effects), }; @@ -1096,7 +1111,7 @@ mod tests { ) -> Timestamp { let (witness_timestamp, bctx) = match &*validator.handle_timer(proposal_timer, state, instance_id) { - [Eff::ScheduleTimer(witness_timestamp), Eff::RequestNewBlock(bctx)] => { + [Eff::ScheduleTimer(witness_timestamp), Eff::RequestNewBlock(bctx, _)] => { (*witness_timestamp, bctx.clone()) } effects => panic!("unexpected effects {:?}", effects), diff --git a/node/src/components/consensus/highway_core/highway.rs b/node/src/components/consensus/highway_core/highway.rs index 64b9ae37f1..596a2cdacc 100644 --- a/node/src/components/consensus/highway_core/highway.rs +++ b/node/src/components/consensus/highway_core/highway.rs @@ -547,7 +547,7 @@ impl Highway { result.extend(self.add_valid_vertex(vv.clone(), timestamp)) } Effect::WeAreFaulty(_) => self.deactivate_validator(), - Effect::ScheduleTimer(_) | Effect::RequestNewBlock(_) => (), + Effect::ScheduleTimer(_) | Effect::RequestNewBlock(_, _) => (), } } result.extend(effects); diff --git a/node/src/components/consensus/highway_core/highway_testing.rs b/node/src/components/consensus/highway_core/highway_testing.rs index 79b9d0b6aa..7107599052 100644 --- a/node/src/components/consensus/highway_core/highway_testing.rs +++ b/node/src/components/consensus/highway_core/highway_testing.rs @@ -120,7 +120,9 @@ impl From> for HighwayMessage { // validators so for them it's just `Vertex` that needs to be validated. Effect::NewVertex(ValidVertex(v)) => HighwayMessage::NewVertex(Box::new(v)), Effect::ScheduleTimer(t) => HighwayMessage::Timer(t), - Effect::RequestNewBlock(block_context) => HighwayMessage::RequestBlock(block_context), + Effect::RequestNewBlock(block_context, _expiry) => { + HighwayMessage::RequestBlock(block_context) + } Effect::WeAreFaulty(fault) => HighwayMessage::WeAreFaulty(Box::new(fault)), } } diff --git a/node/src/components/consensus/protocols/highway.rs b/node/src/components/consensus/protocols/highway.rs index 803c0fb079..24b9f65531 100644 --- a/node/src/components/consensus/protocols/highway.rs +++ b/node/src/components/consensus/protocols/highway.rs @@ -251,8 +251,8 @@ impl HighwayProtocol { TIMER_ID_ACTIVE_VALIDATOR, )] } - AvEffect::RequestNewBlock(block_context) => { - vec![ProtocolOutcome::CreateNewBlock(block_context)] + AvEffect::RequestNewBlock(block_context, expiry) => { + vec![ProtocolOutcome::CreateNewBlock(block_context, expiry)] } AvEffect::WeAreFaulty(fault) => { error!("this validator is faulty: {:?}", fault); diff --git a/node/src/components/consensus/protocols/zug.rs b/node/src/components/consensus/protocols/zug.rs index c465502969..1f825339d6 100644 --- a/node/src/components/consensus/protocols/zug.rs +++ b/node/src/components/consensus/protocols/zug.rs @@ -1426,7 +1426,7 @@ impl Zug { | ProtocolOutcome::CreatedRequestToRandomPeer(_) | ProtocolOutcome::ScheduleTimer(_, _) | ProtocolOutcome::QueueAction(_) - | ProtocolOutcome::CreateNewBlock(_) + | ProtocolOutcome::CreateNewBlock(_, _) | ProtocolOutcome::DoppelgangerDetected | ProtocolOutcome::Disconnect(_) => false, })); @@ -1890,7 +1890,10 @@ impl Zug { self.current_round, maybe_parent_round_id, )); - vec![ProtocolOutcome::CreateNewBlock(block_context)] + vec![ProtocolOutcome::CreateNewBlock( + block_context, + now.saturating_add(TimeDiff::from_millis(self.proposal_timeout_millis as u64)), + )] } /// Creates a new proposal message in the current round, and a corresponding signed echo, diff --git a/node/src/components/consensus/protocols/zug/des_testing.rs b/node/src/components/consensus/protocols/zug/des_testing.rs index 5c8b114e6f..a6a6865652 100644 --- a/node/src/components/consensus/protocols/zug/des_testing.rs +++ b/node/src/components/consensus/protocols/zug/des_testing.rs @@ -134,7 +134,9 @@ impl From> for ZugMessage { ZugMessage::Timer(timestamp, timer_id) } ProtocolOutcome::QueueAction(action_id) => ZugMessage::QueueAction(action_id), - ProtocolOutcome::CreateNewBlock(block_ctx) => ZugMessage::RequestNewBlock(block_ctx), + ProtocolOutcome::CreateNewBlock(block_ctx, _expiry) => { + ZugMessage::RequestNewBlock(block_ctx) + } ProtocolOutcome::FinalizedBlock(finalized_block) => { ZugMessage::FinalizedBlock(finalized_block) } diff --git a/node/src/components/consensus/protocols/zug/tests.rs b/node/src/components/consensus/protocols/zug/tests.rs index d3eb7b3127..2cb0f1b853 100644 --- a/node/src/components/consensus/protocols/zug/tests.rs +++ b/node/src/components/consensus/protocols/zug/tests.rs @@ -252,7 +252,7 @@ fn remove_targeted_messages( fn remove_create_new_block(outcomes: &mut ProtocolOutcomes) -> BlockContext { let mut result = None; outcomes.retain(|outcome| match outcome { - ProtocolOutcome::CreateNewBlock(block_context) => { + ProtocolOutcome::CreateNewBlock(block_context, _) => { if let Some(other_context) = result.replace(block_context.clone()) { panic!( "got multiple CreateNewBlock outcomes: {:?}, {:?}", @@ -294,8 +294,11 @@ fn expect_no_gossip_block_finalized(outcomes: ProtocolOutcomes) { ProtocolOutcome::CreatedGossipMessage(msg) => { panic!("unexpected gossip message {:?}", msg); } - ProtocolOutcome::CreateNewBlock(block_context) => { - panic!("unexpected CreateNewBlock: {:?}", block_context); + ProtocolOutcome::CreateNewBlock(block_context, expiry) => { + panic!( + "unexpected CreateNewBlock: {:?} exp. {}", + block_context, expiry + ); } _ => {} } diff --git a/node/src/components/deploy_buffer.rs b/node/src/components/deploy_buffer.rs index 713e2dbd79..f78ce73858 100644 --- a/node/src/components/deploy_buffer.rs +++ b/node/src/components/deploy_buffer.rs @@ -5,7 +5,7 @@ mod metrics; mod tests; use std::{ - collections::{btree_map, BTreeMap, BTreeSet, HashMap, HashSet}, + collections::{btree_map, BTreeMap, BTreeSet, HashMap, HashSet, VecDeque}, convert::TryInto, iter::FromIterator, mem, @@ -18,6 +18,7 @@ use prometheus::Registry; use smallvec::smallvec; use tracing::{debug, error, info, warn}; +use casper_hashing::Digest; use casper_types::Timestamp; use crate::{ @@ -326,13 +327,65 @@ impl DeployBuffer { .collect() } + fn buckets(&mut self) -> HashMap> { + let proposable = self.proposable(); + + let mut buckets: HashMap> = + HashMap::new(); + + for (with_approvals, footprint) in proposable { + let body_hash = *footprint.header.body_hash(); + buckets + .entry(body_hash) + .and_modify(|vec| vec.push((with_approvals.clone(), footprint.clone()))) + .or_insert(vec![(with_approvals, footprint)]); + } + buckets + } + /// Returns a right-sized payload of deploys that can be proposed. - fn appendable_block(&mut self, timestamp: Timestamp) -> AppendableBlock { + fn appendable_block( + &mut self, + timestamp: Timestamp, + request_expiry: Timestamp, + ) -> AppendableBlock { let mut ret = AppendableBlock::new(self.deploy_config, timestamp); + if Timestamp::now() >= request_expiry { + return ret; + } let mut holds = HashSet::new(); let mut have_hit_transfer_limit = false; let mut have_hit_deploy_limit = false; - for (with_approvals, footprint) in self.proposable() { + + let mut buckets = self.buckets(); + let mut body_hashes_queue: VecDeque<_> = buckets.keys().cloned().collect(); + + #[cfg(test)] + let mut iter_counter = 0; + #[cfg(test)] + let iter_limit = self.buffer.len() * 4; + + while let Some(body_hash) = body_hashes_queue.pop_front() { + if Timestamp::now() > request_expiry { + break; + } + #[cfg(test)] + { + iter_counter += 1; + assert!( + iter_counter < iter_limit, + "the number of iterations shouldn't be too large" + ); + } + + let Some((with_approvals, footprint)) = + buckets.get_mut(&body_hash).and_then(Vec::<_>::pop) + else { + continue; + }; + // bucket wasn't empty - push the hash back into the queue to be processed again on the + // next pass + body_hashes_queue.push_back(body_hash); if footprint.is_transfer && have_hit_transfer_limit { continue; } @@ -550,8 +603,11 @@ where } Event::Request(DeployBufferRequest::GetAppendableBlock { timestamp, + request_expiry, responder, - }) => responder.respond(self.appendable_block(timestamp)).ignore(), + }) => responder + .respond(self.appendable_block(timestamp, request_expiry)) + .ignore(), Event::BlockFinalized(finalized_block) => { self.register_block_finalized(&finalized_block); Effects::new() diff --git a/node/src/components/deploy_buffer/tests.rs b/node/src/components/deploy_buffer/tests.rs index ec1d6d9027..10e4a64098 100644 --- a/node/src/components/deploy_buffer/tests.rs +++ b/node/src/components/deploy_buffer/tests.rs @@ -1,3 +1,10 @@ +use std::iter; + +use prometheus::Registry; +use rand::Rng; + +use casper_types::{testing::TestRng, EraId, SecretKey, TimeDiff}; + use super::*; use crate::{ effect::announcements::DeployBufferAnnouncement::{self, DeploysExpired}, @@ -5,9 +12,6 @@ use crate::{ types::{Block, FinalizedBlock}, utils, }; -use casper_types::{testing::TestRng, EraId, TimeDiff}; -use prometheus::Registry; -use rand::Rng; enum DeployType { Transfer, @@ -81,27 +85,50 @@ fn assert_container_sizes( expected_dead: usize, expected_held: usize, ) { - assert_eq!(deploy_buffer.buffer.len(), expected_buffer); - assert_eq!(deploy_buffer.dead.len(), expected_dead); assert_eq!( - deploy_buffer - .hold - .values() - .map(|deploys| deploys.len()) - .sum::(), - expected_held + deploy_buffer.buffer.len(), + expected_buffer, + "buffer.len {} != expected {}", + deploy_buffer.buffer.len(), + expected_buffer ); assert_eq!( + deploy_buffer.dead.len(), + expected_dead, + "dead.len {} != expected {}", + deploy_buffer.dead.len(), + expected_dead + ); + let hold_len = deploy_buffer + .hold + .values() + .map(|deploys| deploys.len()) + .sum::(); + assert_eq!( + hold_len, expected_held, + "hold.len {} != expected {}", + hold_len, expected_held + ); + assert_eq!( + deploy_buffer.metrics.total_deploys.get(), + expected_buffer as i64, + "metrics total {} != expected {}", deploy_buffer.metrics.total_deploys.get(), - expected_buffer as i64 + expected_buffer, ); assert_eq!( deploy_buffer.metrics.held_deploys.get(), - expected_held as i64 + expected_held as i64, + "metrics held {} != expected {}", + deploy_buffer.metrics.held_deploys.get(), + expected_held, ); assert_eq!( deploy_buffer.metrics.dead_deploys.get(), - expected_dead as i64 + expected_dead as i64, + "metrics dead {} != expected {}", + deploy_buffer.metrics.dead_deploys.get(), + expected_dead, ); } @@ -202,8 +229,9 @@ fn get_proposable_deploys() { assert!(proposable_deploy_hashes.contains(deploy.hash())); } - // Get an appendable block. This should put the deploys on hold. - let appendable_block = deploy_buffer.appendable_block(Timestamp::now()); + let timestamp = Timestamp::now(); + let expiry = timestamp.saturating_add(TimeDiff::from_seconds(1)); + let appendable_block = deploy_buffer.appendable_block(timestamp, expiry); assert_eq!(deploy_buffer.hold.len(), 1); assert_container_sizes( &deploy_buffer, @@ -295,8 +323,9 @@ fn get_appendable_block( .for_each(|deploy| deploy_buffer.register_deploy(deploy.clone())); assert_container_sizes(deploy_buffer, deploys.len(), 0, 0); - // now check how many transfers were added in the block; should not exceed the config limits. - let appendable_block = deploy_buffer.appendable_block(Timestamp::now()); + let timestamp = Timestamp::now(); + let expiry = timestamp.saturating_add(TimeDiff::from_seconds(1)); + let appendable_block = deploy_buffer.appendable_block(timestamp, expiry); assert!(appendable_block.deploy_and_transfer_set().len() <= deploy_limit,); assert_eq!(deploy_buffer.hold.len(), 1); assert_container_sizes( @@ -346,8 +375,9 @@ fn register_deploys_and_blocks() { let pre_proposal_timestamp = Timestamp::now(); - // get an appendable block. This should put the deploys on hold. - let appendable_block = deploy_buffer.appendable_block(Timestamp::now()); + let timestamp = Timestamp::now(); + let expiry = timestamp.saturating_add(TimeDiff::from_seconds(1)); + let appendable_block = deploy_buffer.appendable_block(timestamp, expiry); assert_eq!(deploy_buffer.hold.len(), 1); assert_container_sizes( &deploy_buffer, @@ -394,6 +424,273 @@ fn register_deploys_and_blocks() { ); } +#[test] +fn should_have_one_bucket_per_distinct_body_hash() { + let mut rng = TestRng::new(); + let max_deploy_count = 2; + let max_transfer_count = 0; + let deploy_config = DeployConfig { + block_max_deploy_count: max_deploy_count, + block_max_transfer_count: max_transfer_count, + block_max_approval_count: max_deploy_count + max_transfer_count, + ..Default::default() + }; + let mut deploy_buffer = + DeployBuffer::new(deploy_config, Config::default(), &Registry::new()).unwrap(); + + let secret_key1 = SecretKey::random(&mut rng); + let ttl = TimeDiff::from_seconds(30); + let deploy1 = Deploy::random_contract_by_name( + &mut rng, + Some(secret_key1), + None, + None, + Some(Timestamp::now()), + Some(ttl), + ); + let deploy1_body_hash = *deploy1.header().body_hash(); + deploy_buffer.register_deploy(deploy1); + + let secret_key2 = SecretKey::random(&mut rng); // different signer + let deploy2 = Deploy::random_contract_by_name( + &mut rng, + Some( + SecretKey::from_pem(secret_key2.to_pem().expect("should pemify")) + .expect("should un-pemify"), + ), + None, + None, + Some(Timestamp::now()), // different timestamp + Some(ttl), + ); + assert_eq!( + &deploy1_body_hash, + deploy2.header().body_hash(), + "1 & 2 should have same body hashes" + ); + deploy_buffer.register_deploy(deploy2); + + let buckets = deploy_buffer.buckets(); + assert!(buckets.len() == 1, "should be 1 bucket"); + + let deploy3 = Deploy::random_contract_by_name( + &mut rng, + Some( + SecretKey::from_pem(secret_key2.to_pem().expect("should pemify")) + .expect("should un-pemify"), + ), + None, + None, + Some(Timestamp::now()), // different timestamp + Some(ttl), + ); + assert_eq!( + &deploy1_body_hash, + deploy3.header().body_hash(), + "1 & 3 should have same body hashes" + ); + deploy_buffer.register_deploy(deploy3); + let buckets = deploy_buffer.buckets(); + assert!(buckets.len() == 1, "should still be 1 bucket"); + + let deploy4 = Deploy::random_contract_by_name( + &mut rng, + Some( + SecretKey::from_pem(secret_key2.to_pem().expect("should pemify")) + .expect("should un-pemify"), + ), + Some("some other contract name".to_string()), + None, + Some(Timestamp::now()), // different timestamp + Some(ttl), + ); + assert_ne!( + &deploy1_body_hash, + deploy4.header().body_hash(), + "1 & 4 should have different body hashes" + ); + deploy_buffer.register_deploy(deploy4); + let buckets = deploy_buffer.buckets(); + assert!(buckets.len() == 2, "should be 2 buckets"); + + let transfer5 = Deploy::random_valid_native_transfer_with_timestamp_and_ttl( + &mut rng, + Timestamp::now(), + ttl, + ); + assert_ne!( + &deploy1_body_hash, + transfer5.header().body_hash(), + "1 & 5 should have different body hashes" + ); + deploy_buffer.register_deploy(transfer5); + let buckets = deploy_buffer.buckets(); + assert!(buckets.len() == 3, "should be 3 buckets"); +} + +#[test] +fn should_be_empty_if_no_time_until_expiry() { + let mut rng = TestRng::new(); + let max_deploy_count = 1; + let max_transfer_count = 1; + let deploy_config = DeployConfig { + block_max_deploy_count: max_deploy_count, + block_max_transfer_count: max_transfer_count, + block_max_approval_count: max_deploy_count + max_transfer_count, + ..Default::default() + }; + let mut deploy_buffer = + DeployBuffer::new(deploy_config, Config::default(), &Registry::new()).unwrap(); + + let secret_key1 = SecretKey::random(&mut rng); + let ttl = TimeDiff::from_seconds(30); + let deploy1 = Deploy::random_contract_by_name( + &mut rng, + Some(secret_key1), + None, + None, + Some(Timestamp::now()), + Some(ttl), + ); + let deploy1_body_hash = *deploy1.header().body_hash(); + deploy_buffer.register_deploy(deploy1); + + let buckets = deploy_buffer.buckets(); + assert!(buckets.len() == 1, "should be 1 buckets"); + + let transfer2 = Deploy::random_valid_native_transfer_with_timestamp_and_ttl( + &mut rng, + Timestamp::now(), + ttl, + ); + assert_ne!( + &deploy1_body_hash, + transfer2.header().body_hash(), + "1 & 2 should have different body hashes" + ); + deploy_buffer.register_deploy(transfer2); + let buckets = deploy_buffer.buckets(); + assert!(buckets.len() == 2, "should be 2 buckets"); + + let now = Timestamp::now(); + let appendable = deploy_buffer.appendable_block(now, now); + let count = appendable.deploy_and_transfer_set().len(); + assert!(count == 0, "expected 0 found {}", count); + + // logic should tolerate invalid expiry + let appendable = + deploy_buffer.appendable_block(now, now.saturating_sub(TimeDiff::from_millis(1))); + let count = appendable.deploy_and_transfer_set().len(); + assert!(count == 0, "expected 0 found {}", count); +} + +#[test] +fn should_have_diverse_proposable_blocks_with_stocked_buffer() { + let rng = &mut TestRng::new(); + let max_deploy_count = 50; + let max_transfer_count = 5; + let deploy_config = DeployConfig { + block_max_deploy_count: max_deploy_count, + block_max_transfer_count: max_transfer_count, + block_max_approval_count: max_deploy_count + max_transfer_count, + ..Default::default() + }; + let mut deploy_buffer = + DeployBuffer::new(deploy_config, Config::default(), &Registry::new()).unwrap(); + + let cap = (max_deploy_count * 100) as usize; + + let secret_keys: Vec = iter::repeat_with(|| SecretKey::random(rng)) + .take(10) + .collect(); + let contract_names = ["a", "b", "c", "d", "e"]; + let contract_entry_points = ["foo", "bar"]; + + fn ttl(rng: &mut TestRng) -> TimeDiff { + TimeDiff::from_seconds(rng.gen_range(60..3600)) + } + + let mut last_timestamp = Timestamp::now(); + for i in 0..cap { + let ttl = ttl(rng); + let secret_key = Some( + SecretKey::from_pem( + secret_keys[rng.gen_range(0..secret_keys.len())] + .to_pem() + .expect("should pemify"), + ) + .expect("should un-pemify"), + ); + let contract_name = Some(contract_names[rng.gen_range(0..contract_names.len())].into()); + let contract_entry_point = + Some(contract_entry_points[rng.gen_range(0..contract_entry_points.len())].into()); + let deploy = Deploy::random_contract_by_name( + rng, + secret_key, + contract_name, + contract_entry_point, + Some(last_timestamp), + Some(ttl), + ); + deploy_buffer.register_deploy(deploy); + assert_eq!( + deploy_buffer.buffer.len(), + i + 1, + "failed to buffer deploy {i}" + ); + last_timestamp += TimeDiff::from_millis(1); + } + + for i in 0..max_transfer_count { + let ttl = ttl(rng); + deploy_buffer.register_deploy(Deploy::random_valid_native_transfer_with_timestamp_and_ttl( + rng, + last_timestamp, + ttl, + )); + assert_eq!( + deploy_buffer.buffer.len(), + i as usize + 1 + cap, + "failed to buffer transfer {i}" + ); + last_timestamp += TimeDiff::from_millis(1); + } + + let expected_count = cap + (max_transfer_count as usize); + assert_container_sizes(&deploy_buffer, expected_count, 0, 0); + + let buckets1 = deploy_buffer.buckets(); + assert!( + buckets1.len() > 1, + "should be multiple buckets with this much state" + ); + let buckets2 = deploy_buffer.buckets(); + assert_eq!( + buckets1, buckets2, + "with same state should get same buckets every time" + ); + + // while it is not impossible to get identical appendable blocks over an unchanged buffer + // using this strategy, it should be very unlikely...the below brute forces a check for this + let expected_eq_tolerance = 1; + let mut actual_eq_count = 0; + + let expiry = last_timestamp.saturating_add(TimeDiff::from_seconds(1)); + for _ in 0..10 { + let appendable1 = deploy_buffer.appendable_block(last_timestamp, expiry); + let appendable2 = deploy_buffer.appendable_block(last_timestamp, expiry); + if appendable1 == appendable2 { + actual_eq_count += 1; + } + } + assert!( + actual_eq_count <= expected_eq_tolerance, + "{} matches exceeded tolerance of {}", + actual_eq_count, + expected_eq_tolerance + ); +} + /// Event for the mock reactor. #[derive(Debug)] enum ReactorEvent { @@ -500,3 +797,110 @@ async fn expire_deploys_and_check_announcement() { // the valid deploys should still be in the buffer assert_container_sizes(&deploy_buffer, deploys.len(), 0, 0); } + +fn register_random_deploys_unique_hashes( + deploy_buffer: &mut DeployBuffer, + num_deploys: usize, + rng: &mut TestRng, +) { + let deploys = std::iter::repeat_with(|| { + let name = format!("{}", rng.gen::()); + let call = format!("{}", rng.gen::()); + Deploy::random_contract_by_name( + rng, + None, + Some(name), + Some(call), + Some(Timestamp::now()), // different timestamp + None, + ) + }) + .take(num_deploys); + for deploy in deploys { + deploy_buffer.register_deploy(deploy); + } +} + +fn register_random_deploys_same_hash( + deploy_buffer: &mut DeployBuffer, + num_deploys: usize, + rng: &mut TestRng, +) { + let deploys = std::iter::repeat_with(|| { + let name = "test".to_owned(); + let call = "test".to_owned(); + Deploy::random_contract_by_name( + rng, + None, + Some(name), + Some(call), + Some(Timestamp::now()), // different timestamp + None, + ) + }) + .take(num_deploys); + for deploy in deploys { + deploy_buffer.register_deploy(deploy); + } +} + +#[test] +fn test_buckets_single_hash() { + let mut rng = TestRng::new(); + let deploy_config = DeployConfig { + block_max_transfer_count: 1000, + block_max_deploy_count: 100, + block_max_approval_count: 1100, + ..Default::default() + }; + let mut deploy_buffer = + DeployBuffer::new(deploy_config, Config::default(), &Registry::new()).unwrap(); + + register_random_deploys_same_hash(&mut deploy_buffer, 64000, &mut rng); + + let _block = deploy_buffer.appendable_block( + Timestamp::now(), + Timestamp::now() + TimeDiff::from_millis(16384 / 6), + ); +} + +#[test] +fn test_buckets_unique_hashes() { + let mut rng = TestRng::new(); + let deploy_config = DeployConfig { + block_max_transfer_count: 1000, + block_max_deploy_count: 100, + block_max_approval_count: 1100, + ..Default::default() + }; + let mut deploy_buffer = + DeployBuffer::new(deploy_config, Config::default(), &Registry::new()).unwrap(); + + register_random_deploys_unique_hashes(&mut deploy_buffer, 64000, &mut rng); + + let _block = deploy_buffer.appendable_block( + Timestamp::now(), + Timestamp::now() + TimeDiff::from_millis(16384 / 6), + ); +} + +#[test] +fn test_buckets_mixed_load() { + let mut rng = TestRng::new(); + let deploy_config = DeployConfig { + block_max_transfer_count: 1000, + block_max_deploy_count: 100, + block_max_approval_count: 1100, + ..Default::default() + }; + let mut deploy_buffer = + DeployBuffer::new(deploy_config, Config::default(), &Registry::new()).unwrap(); + + register_random_deploys_unique_hashes(&mut deploy_buffer, 60000, &mut rng); + register_random_deploys_same_hash(&mut deploy_buffer, 4000, &mut rng); + + let _block = deploy_buffer.appendable_block( + Timestamp::now(), + Timestamp::now() + TimeDiff::from_millis(16384 / 6), + ); +} diff --git a/node/src/components/network.rs b/node/src/components/network.rs index 89115c5651..77a21b5ac2 100644 --- a/node/src/components/network.rs +++ b/node/src/components/network.rs @@ -946,15 +946,15 @@ where // Record the time the pong arrived and forward it to outgoing. let pong = TaggedTimestamp::from_parts(Instant::now(), nonce); if self.outgoing_manager.record_pong(peer_id, pong) { - effect_builder - .announce_block_peer_with_justification( - peer_id, - BlocklistJustification::PongLimitExceeded, - ) - .ignore() - } else { - Effects::new() + // Note: We no longer block peers here with a `PongLimitExceeded` for failed + // pongs, merely warn. + info!( + "peer {} exceeded failed pong limit, or allowed number of pongs", + peer_id // Redundant information due to span, but better safe than sorry. + ); } + + Effects::new() } Message::Payload(payload) => { effect_builder.announce_incoming(peer_id, payload).ignore() diff --git a/node/src/components/network/blocklist.rs b/node/src/components/network/blocklist.rs index 1dfe232455..5fd28029e1 100644 --- a/node/src/components/network/blocklist.rs +++ b/node/src/components/network/blocklist.rs @@ -38,6 +38,7 @@ pub(crate) enum BlocklistJustification { era: EraId, }, /// Too many unasked or expired pongs were sent by the peer. + #[allow(dead_code)] // Disabled as per 1.5.5 for stability reasons. PongLimitExceeded, /// Peer misbehaved during consensus and is blocked for it. BadConsensusBehavior, diff --git a/node/src/components/rpc_server/rpcs/docs.rs b/node/src/components/rpc_server/rpcs/docs.rs index 9b43fe1a05..2e2dbc6c49 100644 --- a/node/src/components/rpc_server/rpcs/docs.rs +++ b/node/src/components/rpc_server/rpcs/docs.rs @@ -30,7 +30,7 @@ use super::{ use crate::effect::EffectBuilder; pub(crate) const DOCS_EXAMPLE_PROTOCOL_VERSION: ProtocolVersion = - ProtocolVersion::from_parts(1, 5, 5); + ProtocolVersion::from_parts(1, 5, 6); const DEFINITIONS_PATH: &str = "#/components/schemas/"; diff --git a/node/src/components/upgrade_watcher.rs b/node/src/components/upgrade_watcher.rs index 2f96a1399e..da02945c98 100644 --- a/node/src/components/upgrade_watcher.rs +++ b/node/src/components/upgrade_watcher.rs @@ -69,7 +69,7 @@ pub(crate) enum Event { /// Check config dir to see if an upgrade activation point is available, and if so announce it. CheckForNextUpgrade, /// If the result of checking for an upgrade is successful, it is passed here. - GotNextUpgrade(NextUpgrade), + GotNextUpgrade(Option), } impl Display for Event { @@ -84,9 +84,12 @@ impl Display for Event { Event::CheckForNextUpgrade => { write!(formatter, "check for next upgrade") } - Event::GotNextUpgrade(next_upgrade) => { + Event::GotNextUpgrade(Some(next_upgrade)) => { write!(formatter, "got {}", next_upgrade) } + Event::GotNextUpgrade(None) => { + write!(formatter, "no upgrade detected") + } } } } @@ -122,7 +125,7 @@ pub(crate) enum Error { } /// Information about the next protocol upgrade. -#[derive(PartialEq, Eq, DataSize, Debug, Serialize, Deserialize, Clone, JsonSchema)] +#[derive(PartialEq, Eq, DataSize, Debug, Serialize, Deserialize, Clone, Copy, JsonSchema)] pub struct NextUpgrade { activation_point: ActivationPoint, #[data_size(skip)] @@ -209,6 +212,11 @@ impl UpgradeWatcher { }) } + pub(crate) fn next_upgrade_activation_point(&self) -> Option { + self.next_upgrade + .map(|next_upgrade| next_upgrade.activation_point.era_id()) + } + fn start_checking_for_upgrades( &mut self, effect_builder: EffectBuilder, @@ -230,7 +238,6 @@ impl UpgradeWatcher { let root_dir = self.root_dir.clone(); let current_version = self.current_version; let mut effects = async move { - // TODO: only do this on era change / JIT let maybe_next_upgrade = task::spawn_blocking(move || next_upgrade(root_dir, current_version)) .await @@ -238,11 +245,9 @@ impl UpgradeWatcher { warn!(%error, "failed to join tokio task"); None }); - if let Some(next_upgrade) = maybe_next_upgrade { - effect_builder - .announce_upgrade_activation_point_read(next_upgrade) - .await - } + effect_builder + .upgrade_watcher_announcement(maybe_next_upgrade) + .await } .ignore(); @@ -255,18 +260,28 @@ impl UpgradeWatcher { effects } - fn handle_got_next_upgrade(&mut self, next_upgrade: NextUpgrade) -> Effects { - debug!("got {}", next_upgrade); - if let Some(ref current_point) = self.next_upgrade { - if next_upgrade != *current_point { - info!( - new_point=%next_upgrade.activation_point, - %current_point, - "changing upgrade activation point" - ); - } + fn handle_got_next_upgrade( + &mut self, + maybe_next_upgrade: Option, + ) -> Effects { + trace!("got {:?}", maybe_next_upgrade); + if self.next_upgrade != maybe_next_upgrade { + let new_point = match &maybe_next_upgrade { + Some(next_upgrade) => next_upgrade.to_string(), + None => "none".to_string(), + }; + let current_point = match &self.next_upgrade { + Some(next_upgrade) => next_upgrade.to_string(), + None => "none".to_string(), + }; + info!( + %new_point, + %current_point, + "changing upgrade activation point" + ); } - self.next_upgrade = Some(next_upgrade); + + self.next_upgrade = maybe_next_upgrade; Effects::new() } } @@ -321,7 +336,7 @@ where ); Effects::new() } - Event::Request(request) => request.0.respond(self.next_upgrade.clone()).ignore(), + Event::Request(request) => request.0.respond(self.next_upgrade).ignore(), Event::CheckForNextUpgrade => self.check_for_next_upgrade(effect_builder), Event::GotNextUpgrade(next_upgrade) => self.handle_got_next_upgrade(next_upgrade), }, @@ -332,6 +347,7 @@ where COMPONENT_NAME } } + impl InitializedComponent for UpgradeWatcher where REv: From + From + Send, @@ -369,17 +385,18 @@ impl UpgradePoint { } } -fn dir_name_from_version(version: &ProtocolVersion) -> PathBuf { +fn dir_name_from_version(version: ProtocolVersion) -> PathBuf { PathBuf::from(version.to_string().replace('.', "_")) } /// Iterates the given path, returning the subdir representing the immediate next SemVer version -/// after `current_version`. +/// after `current_version`. If no higher version than `current_version` is found, then +/// `current_version` is returned. /// /// Subdir names should be semvers with dots replaced with underscores. fn next_installed_version( dir: &Path, - current_version: &ProtocolVersion, + current_version: ProtocolVersion, ) -> Result { let max_version = ProtocolVersion::from_parts(u32::max_value(), u32::max_value(), u32::max_value()); @@ -411,7 +428,7 @@ fn next_installed_version( } }; - if version > *current_version && version < next_version { + if version > current_version && version < next_version { next_version = version; } read_version = true; @@ -424,7 +441,7 @@ fn next_installed_version( } if next_version == max_version { - next_version = *current_version; + next_version = current_version; } Ok(next_version) @@ -434,7 +451,7 @@ fn next_installed_version( /// UpgradePoint file from there and returns its version and activation point. Returns `None` if /// there is no greater version available, or if any step errors. fn next_upgrade(dir: PathBuf, current_version: ProtocolVersion) -> Option { - let next_version = match next_installed_version(&dir, ¤t_version) { + let next_version = match next_installed_version(&dir, current_version) { Ok(version) => version, Err(_error) => { #[cfg(not(test))] @@ -447,7 +464,7 @@ fn next_upgrade(dir: PathBuf, current_version: ProtocolVersion) -> Option upgrade_point, Err(error) => { @@ -473,36 +490,51 @@ mod tests { use casper_types::testing::TestRng; use super::*; - use crate::types::chainspec::CHAINSPEC_FILENAME; + use crate::{ + logging, + types::{ + chainspec::{ActivationPoint, CHAINSPEC_FILENAME}, + ChainspecRawBytes, + }, + utils::Loadable, + }; + + const V0_0_0: ProtocolVersion = ProtocolVersion::from_parts(0, 0, 0); + const V0_9_9: ProtocolVersion = ProtocolVersion::from_parts(0, 9, 9); + const V1_0_0: ProtocolVersion = ProtocolVersion::from_parts(1, 0, 0); + const V1_0_3: ProtocolVersion = ProtocolVersion::from_parts(1, 0, 3); + const V1_2_3: ProtocolVersion = ProtocolVersion::from_parts(1, 2, 3); + const V2_2_2: ProtocolVersion = ProtocolVersion::from_parts(2, 2, 2); #[test] fn should_get_next_installed_version() { let tempdir = tempfile::tempdir().expect("should create temp dir"); - let get_next_version = |current_version: &ProtocolVersion| { + let get_next_version = |current_version: ProtocolVersion| { next_installed_version(tempdir.path(), current_version).unwrap() }; - let mut current = ProtocolVersion::from_parts(0, 0, 0); - let mut next_version = ProtocolVersion::from_parts(1, 0, 0); + // Should get next version (major version bump). fs::create_dir(tempdir.path().join("1_0_0")).unwrap(); - assert_eq!(get_next_version(¤t), next_version); - current = next_version; + assert_eq!(get_next_version(V0_0_0), V1_0_0); - next_version = ProtocolVersion::from_parts(1, 2, 3); + // Should get next version (minor version bump). fs::create_dir(tempdir.path().join("1_2_3")).unwrap(); - assert_eq!(get_next_version(¤t), next_version); - current = next_version; + assert_eq!(get_next_version(V1_0_0), V1_2_3); + // Should report current as next version if only lower versions staged. fs::create_dir(tempdir.path().join("1_0_3")).unwrap(); - assert_eq!(get_next_version(¤t), next_version); + assert_eq!(get_next_version(V1_2_3), V1_2_3); + // Should report lower of two higher versions. fs::create_dir(tempdir.path().join("2_2_2")).unwrap(); fs::create_dir(tempdir.path().join("3_3_3")).unwrap(); - assert_eq!( - get_next_version(¤t), - ProtocolVersion::from_parts(2, 2, 2) - ); + assert_eq!(get_next_version(V1_2_3), V2_2_2); + + // If higher versions unstaged, should report current again. + fs::remove_dir_all(tempdir.path().join("2_2_2")).unwrap(); + fs::remove_dir_all(tempdir.path().join("3_3_3")).unwrap(); + assert_eq!(get_next_version(V1_2_3), V1_2_3); } #[test] @@ -511,9 +543,9 @@ mod tests { // Executes `next_installed_version()` and asserts the resulting error as a string starts // with the given text. - let min_version = ProtocolVersion::from_parts(0, 0, 0); + let min_version = V0_0_0; let assert_error_starts_with = |path: &Path, expected: String| { - let error_msg = next_installed_version(path, &min_version) + let error_msg = next_installed_version(path, min_version) .unwrap_err() .to_string(); assert!( @@ -553,8 +585,8 @@ mod tests { // Try with a dir which has a valid and invalid subdir - the invalid one should be ignored. fs::create_dir(tempdir.path().join("1_2_3")).unwrap(); assert_eq!( - next_installed_version(tempdir.path(), &min_version).unwrap(), - ProtocolVersion::from_parts(1, 2, 3) + next_installed_version(tempdir.path(), min_version).unwrap(), + V1_2_3 ); } @@ -563,10 +595,10 @@ mod tests { fn install_chainspec( rng: &mut TestRng, root_dir: &Path, - version: &ProtocolVersion, + version: ProtocolVersion, ) -> Chainspec { let mut chainspec = Chainspec::random(rng); - chainspec.protocol_config.version = *version; + chainspec.protocol_config.version = version; let subdir = root_dir.join(dir_name_from_version(version)); fs::create_dir(&subdir).unwrap(); @@ -584,77 +616,82 @@ mod tests { fn should_get_next_upgrade() { let tempdir = tempfile::tempdir().expect("should create temp dir"); - let next_point = |current_version: &ProtocolVersion| { - next_upgrade(tempdir.path().to_path_buf(), *current_version).unwrap() + let next_point = |current_version: ProtocolVersion| { + next_upgrade(tempdir.path().to_path_buf(), current_version).unwrap() }; let mut rng = crate::new_rng(); - let mut current = ProtocolVersion::from_parts(0, 9, 9); - let v1_0_0 = ProtocolVersion::from_parts(1, 0, 0); - let chainspec_v1_0_0 = install_chainspec(&mut rng, tempdir.path(), &v1_0_0); - assert_eq!( - next_point(¤t), - chainspec_v1_0_0.protocol_config.into() - ); + let chainspec_v1_0_0 = install_chainspec(&mut rng, tempdir.path(), V1_0_0); + assert_eq!(next_point(V0_9_9), chainspec_v1_0_0.protocol_config.into()); - current = v1_0_0; - let v1_0_3 = ProtocolVersion::from_parts(1, 0, 3); - let chainspec_v1_0_3 = install_chainspec(&mut rng, tempdir.path(), &v1_0_3); - assert_eq!( - next_point(¤t), - chainspec_v1_0_3.protocol_config.into() - ); + let chainspec_v1_0_3 = install_chainspec(&mut rng, tempdir.path(), V1_0_3); + assert_eq!(next_point(V1_0_0), chainspec_v1_0_3.protocol_config.into()); } #[test] fn should_not_get_old_or_invalid_upgrade() { let tempdir = tempfile::tempdir().expect("should create temp dir"); - let maybe_next_point = |current_version: &ProtocolVersion| { - next_upgrade(tempdir.path().to_path_buf(), *current_version) + let maybe_next_point = |current_version: ProtocolVersion| { + next_upgrade(tempdir.path().to_path_buf(), current_version) }; let mut rng = crate::new_rng(); // Check we return `None` if there are no version subdirs. - let v1_0_0 = ProtocolVersion::from_parts(1, 0, 0); - let mut current = v1_0_0; - assert!(maybe_next_point(¤t).is_none()); + assert!(maybe_next_point(V1_0_0).is_none()); // Check we return `None` if current_version == next_version. - let chainspec_v1_0_0 = install_chainspec(&mut rng, tempdir.path(), &v1_0_0); - assert!(maybe_next_point(¤t).is_none()); + let chainspec_v1_0_0 = install_chainspec(&mut rng, tempdir.path(), V1_0_0); + assert!(maybe_next_point(V1_0_0).is_none()); // Check we return `None` if current_version > next_version. - current = ProtocolVersion::from_parts(2, 0, 0); - assert!(maybe_next_point(¤t).is_none()); + assert!(maybe_next_point(V2_2_2).is_none()); // Check we return `None` if we find an upgrade file where the protocol_config.version field // doesn't match the subdir name. - let v0_9_9 = ProtocolVersion::from_parts(0, 9, 9); - current = v0_9_9; - assert!(maybe_next_point(¤t).is_some()); + assert!(maybe_next_point(V0_9_9).is_some()); let mut chainspec_v0_9_9 = chainspec_v1_0_0; - chainspec_v0_9_9.protocol_config.version = v0_9_9; + chainspec_v0_9_9.protocol_config.version = V0_9_9; let path_v1_0_0 = tempdir .path() - .join(dir_name_from_version(&v1_0_0)) + .join(dir_name_from_version(V1_0_0)) .join(CHAINSPEC_FILENAME); fs::write( &path_v1_0_0, toml::to_string_pretty(&chainspec_v0_9_9).expect("should encode to toml"), ) .expect("should install upgrade point"); - assert!(maybe_next_point(¤t).is_none()); + assert!(maybe_next_point(V0_9_9).is_none()); // Check we return `None` if the next version upgrade_point file is corrupt. fs::write(&path_v1_0_0, "bad data".as_bytes()).unwrap(); - assert!(maybe_next_point(¤t).is_none()); + assert!(maybe_next_point(V0_9_9).is_none()); // Check we return `None` if the next version upgrade_point file is missing. fs::remove_file(&path_v1_0_0).unwrap(); - assert!(maybe_next_point(¤t).is_none()); + assert!(maybe_next_point(V0_9_9).is_none()); + } + + #[test] + fn should_register_unstaged_upgrade() { + let _ = logging::init(); + let tempdir = tempfile::tempdir().expect("should create temp dir"); + let (chainspec, _) = <(Chainspec, ChainspecRawBytes)>::from_resources("local"); + let mut upgrade_watcher = + UpgradeWatcher::new(&chainspec, Config::default(), tempdir.path()).unwrap(); + assert!(upgrade_watcher.next_upgrade.is_none()); + + let next_upgrade = NextUpgrade { + activation_point: ActivationPoint::EraId(EraId::MAX), + protocol_version: ProtocolVersion::from_parts(9, 9, 9), + }; + let _ = upgrade_watcher.handle_got_next_upgrade(Some(next_upgrade)); + assert_eq!(Some(next_upgrade), upgrade_watcher.next_upgrade); + + let _ = upgrade_watcher.handle_got_next_upgrade(None); + assert!(upgrade_watcher.next_upgrade.is_none()); } } diff --git a/node/src/effect.rs b/node/src/effect.rs index a1a81bd4f6..d40dad4445 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -993,13 +993,13 @@ impl EffectBuilder { } /// Announces upgrade activation point read. - pub(crate) async fn announce_upgrade_activation_point_read(self, next_upgrade: NextUpgrade) + pub(crate) async fn upgrade_watcher_announcement(self, maybe_next_upgrade: Option) where REv: From, { self.event_queue .schedule( - UpgradeWatcherAnnouncement::UpgradeActivationPointRead(next_upgrade), + UpgradeWatcherAnnouncement(maybe_next_upgrade), QueueKind::Control, ) .await @@ -1705,13 +1705,18 @@ impl EffectBuilder { } /// Passes the timestamp of a future block for which deploys are to be proposed. - pub(crate) async fn request_appendable_block(self, timestamp: Timestamp) -> AppendableBlock + pub(crate) async fn request_appendable_block( + self, + timestamp: Timestamp, + request_expiry: Timestamp, + ) -> AppendableBlock where REv: From, { self.make_request( |responder| DeployBufferRequest::GetAppendableBlock { timestamp, + request_expiry, responder, }, QueueKind::Consensus, diff --git a/node/src/effect/announcements.rs b/node/src/effect/announcements.rs index 83cf2e36e1..c149e60c32 100644 --- a/node/src/effect/announcements.rs +++ b/node/src/effect/announcements.rs @@ -333,19 +333,14 @@ impl Display for GossiperAnnouncement { } } -/// A chainspec loader announcement. #[derive(Debug, Serialize)] -pub(crate) enum UpgradeWatcherAnnouncement { - /// New upgrade recognized. - UpgradeActivationPointRead(NextUpgrade), -} +pub(crate) struct UpgradeWatcherAnnouncement(pub(crate) Option); impl Display for UpgradeWatcherAnnouncement { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - UpgradeWatcherAnnouncement::UpgradeActivationPointRead(next_upgrade) => { - write!(f, "read {}", next_upgrade) - } + match &self.0 { + Some(next_upgrade) => write!(f, "read {}", next_upgrade), + None => write!(f, "no upgrade staged"), } } } diff --git a/node/src/effect/requests.rs b/node/src/effect/requests.rs index 7487fcc210..3bb87cbced 100644 --- a/node/src/effect/requests.rs +++ b/node/src/effect/requests.rs @@ -662,6 +662,7 @@ impl Display for MarkBlockCompletedRequest { pub(crate) enum DeployBufferRequest { GetAppendableBlock { timestamp: Timestamp, + request_expiry: Timestamp, responder: Responder, }, } @@ -669,11 +670,15 @@ pub(crate) enum DeployBufferRequest { impl Display for DeployBufferRequest { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { match self { - DeployBufferRequest::GetAppendableBlock { timestamp, .. } => { + DeployBufferRequest::GetAppendableBlock { + timestamp, + request_expiry, + .. + } => { write!( formatter, - "request for appendable block at instant {}", - timestamp + "request for appendable block at instant {} (expires at {})", + timestamp, request_expiry, ) } } diff --git a/node/src/lib.rs b/node/src/lib.rs index 3bdf5280b4..3bbd416507 100644 --- a/node/src/lib.rs +++ b/node/src/lib.rs @@ -8,7 +8,7 @@ //! While the [`main`](fn.main.html) function is the central entrypoint for the node application, //! its core event loop is found inside the [reactor](reactor/index.html). -#![doc(html_root_url = "https://docs.rs/casper-node/1.5.5")] +#![doc(html_root_url = "https://docs.rs/casper-node/1.5.6")] #![doc( html_favicon_url = "https://raw.githubusercontent.com/casper-network/casper-node/blob/dev/images/Casper_Logo_Favicon_48.png", html_logo_url = "https://raw.githubusercontent.com/casper-network/casper-node/blob/dev/images/Casper_Logo_Favicon.png", diff --git a/node/src/reactor/main_reactor.rs b/node/src/reactor/main_reactor.rs index aeb5f91f13..63d92fb54d 100644 --- a/node/src/reactor/main_reactor.rs +++ b/node/src/reactor/main_reactor.rs @@ -191,6 +191,7 @@ pub(crate) struct MainReactor { upgrade_timeout: TimeDiff, sync_handling: SyncHandling, signature_gossip_tracker: SignatureGossipTracker, + prevent_validator_shutdown: bool, } impl reactor::Reactor for MainReactor { @@ -216,7 +217,7 @@ impl reactor::Reactor for MainReactor { ), MainEvent::FatalAnnouncement(fatal_ann) => { - if self.consensus.is_active_validator() { + if self.consensus.is_active_validator() && self.prevent_validator_shutdown { warn!(%fatal_ann, "consensus is active, not shutting down"); Effects::new() } else { @@ -290,18 +291,21 @@ impl reactor::Reactor for MainReactor { self.upgrade_watcher .handle_event(effect_builder, rng, req.into()), ), - MainEvent::UpgradeWatcherAnnouncement( - UpgradeWatcherAnnouncement::UpgradeActivationPointRead(next_upgrade), - ) => { + MainEvent::UpgradeWatcherAnnouncement(UpgradeWatcherAnnouncement( + maybe_next_upgrade, + )) => { // register activation point of upgrade w/ block accumulator - self.block_accumulator - .register_activation_point(next_upgrade.activation_point()); + self.block_accumulator.register_activation_point( + maybe_next_upgrade + .as_ref() + .map(|next_upgrade| next_upgrade.activation_point()), + ); reactor::wrap_effects( MainEvent::UpgradeWatcher, self.upgrade_watcher.handle_event( effect_builder, rng, - upgrade_watcher::Event::GotNextUpgrade(next_upgrade), + upgrade_watcher::Event::GotNextUpgrade(maybe_next_upgrade), ), ) } @@ -1001,6 +1005,7 @@ impl reactor::Reactor for MainReactor { let event_queue_metrics = EventQueueMetrics::new(registry.clone(), event_queue)?; let protocol_version = chainspec.protocol_config.version; + let prevent_validator_shutdown = config.value().node.prevent_validator_shutdown; let trusted_hash = config.value().node.trusted_hash; let (root_dir, config) = config.into_parts(); @@ -1200,11 +1205,24 @@ impl reactor::Reactor for MainReactor { shutdown_for_upgrade_timeout: config.node.shutdown_for_upgrade_timeout, switched_to_shutdown_for_upgrade: Timestamp::from(0), upgrade_timeout: config.node.upgrade_timeout, + prevent_validator_shutdown, }; info!("MainReactor: instantiated"); - let effects = effect_builder - .immediately() - .event(|()| MainEvent::ReactorCrank); + + // If there's an upgrade staged with the same activation point as the current one, we must + // shut down immediately for upgrade. + let should_upgrade_immediately = reactor.upgrade_watcher.next_upgrade_activation_point() + == Some(reactor.chainspec.protocol_config.activation_point.era_id()); + let effects = if should_upgrade_immediately { + info!("MainReactor: immediate shutdown for upgrade"); + effect_builder + .immediately() + .event(|()| MainEvent::ControlAnnouncement(ControlAnnouncement::ShutdownForUpgrade)) + } else { + effect_builder + .immediately() + .event(|()| MainEvent::ReactorCrank) + }; Ok((reactor, effects)) } diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index af81531e88..f4815d443c 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -430,7 +430,7 @@ impl TestFixture { ProtocolVersion::from_parts(999, 0, 0), ); effect_builder - .announce_upgrade_activation_point_read(upgrade) + .upgrade_watcher_announcement(Some(upgrade)) .ignore() }) .await; diff --git a/node/src/types/chainspec.rs b/node/src/types/chainspec.rs index c058ea1981..9be3cb182d 100644 --- a/node/src/types/chainspec.rs +++ b/node/src/types/chainspec.rs @@ -363,6 +363,7 @@ mod tests { blake2b: HostFunction::new(133, [0, 1, 2, 3]), random_bytes: HostFunction::new(123, [0, 1]), enable_contract_version: HostFunction::new(142, [0, 1, 2, 3]), + risc0_verifier: HostFunction::new(200, [0, 1, 2, 3]), }); static EXPECTED_GENESIS_WASM_COSTS: Lazy = Lazy::new(|| { WasmConfig::new( diff --git a/node/src/types/deploy.rs b/node/src/types/deploy.rs index 891e632703..cde30411a4 100644 --- a/node/src/types/deploy.rs +++ b/node/src/types/deploy.rs @@ -921,6 +921,62 @@ impl Deploy { Self::random_transfer_with_session(rng, session) } + /// Returns a random deploy with custom session specified as a stored versioned contract by + /// name. + pub(crate) fn random_contract_by_name( + rng: &mut TestRng, + maybe_secret_key: Option, + maybe_contract_name: Option, + maybe_entry_point_name: Option, + maybe_timestamp: Option, + maybe_ttl: Option, + ) -> Self { + let payment_args = runtime_args! { + "amount" => U512::from(10), + }; + let payment = ExecutableDeployItem::ModuleBytes { + module_bytes: Bytes::new(), + args: payment_args, + }; + let contract_name = match maybe_contract_name { + None => "Test".to_string(), + Some(contract_name) => contract_name, + }; + let entry_point_name = match maybe_entry_point_name { + None => "Test".to_string(), + Some(entry_point_name) => entry_point_name, + }; + let session = ExecutableDeployItem::StoredVersionedContractByName { + name: contract_name, + version: None, + entry_point: entry_point_name, + args: Default::default(), + }; + let secret_key = match maybe_secret_key { + None => SecretKey::random(rng), + Some(secret_key) => secret_key, + }; + let timestamp = match maybe_timestamp { + None => Timestamp::now(), + Some(timestamp) => timestamp, + }; + let ttl = match maybe_ttl { + None => TimeDiff::from_seconds(rng.gen_range(60..3600)), + Some(ttl) => ttl, + }; + Deploy::new( + timestamp, + ttl, + 1, + vec![], + "test_chain".to_string(), + payment, + session, + &secret_key, + None, + ) + } + /// Returns a random invalid deploy with custom session specified as a stored versioned contract /// by hash, but missing the runtime args. pub(crate) fn random_with_missing_session_package_by_hash(rng: &mut TestRng) -> Self { diff --git a/node/src/types/deploy/footprint.rs b/node/src/types/deploy/footprint.rs index 2eac1ec144..e5a1f54c02 100644 --- a/node/src/types/deploy/footprint.rs +++ b/node/src/types/deploy/footprint.rs @@ -6,7 +6,7 @@ use casper_types::Gas; use super::DeployHeader; /// Information about how much block limit a deploy will consume. -#[derive(Clone, DataSize, Debug, Deserialize, Serialize)] +#[derive(Clone, DataSize, Debug, Deserialize, Serialize, PartialEq)] pub(crate) struct Footprint { pub(crate) header: DeployHeader, pub(crate) gas_estimate: Gas, diff --git a/node/src/types/node_config.rs b/node/src/types/node_config.rs index f38629c1c9..e01ad69141 100644 --- a/node/src/types/node_config.rs +++ b/node/src/types/node_config.rs @@ -74,6 +74,9 @@ pub struct NodeConfig { /// Maximum time a node will wait for an upgrade to commit. pub upgrade_timeout: TimeDiff, + + /// If true, prevents a node from shutting down if it is supposed to be a validator in the era. + pub prevent_validator_shutdown: bool, } impl Default for NodeConfig { @@ -87,6 +90,7 @@ impl Default for NodeConfig { force_resync: false, shutdown_for_upgrade_timeout: DEFAULT_SHUTDOWN_FOR_UPGRADE_TIMEOUT.parse().unwrap(), upgrade_timeout: DEFAULT_UPGRADE_TIMEOUT.parse().unwrap(), + prevent_validator_shutdown: false, } } } diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index 7bfd2be784..d6454089cd 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -247,6 +247,7 @@ transfer_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0] update_associated_key = { cost = 4_200, arguments = [0, 0, 0] } write = { cost = 14_000, arguments = [0, 0, 0, 980] } write_local = { cost = 9_500, arguments = [0, 1_800, 0, 520] } +risc0_verifier = {cost = 10_000, arguments = [0, 0, 0, 0]} [system_costs] wasmless_transfer_cost = 100_000_000 diff --git a/resources/production/chainspec.toml b/resources/production/chainspec.toml index 16d1f73baa..572f7789d7 100644 --- a/resources/production/chainspec.toml +++ b/resources/production/chainspec.toml @@ -258,6 +258,7 @@ update_associated_key = { cost = 4_200, arguments = [0, 0, 0] } write = { cost = 14_000, arguments = [0, 0, 0, 980] } write_local = { cost = 9_500, arguments = [0, 1_800, 0, 520] } enable_contract_version = { cost = 200, arguments = [0, 0, 0, 0] } +risc0_verifier = {cost = 200, arguments = [0, 0, 0, 0]} [system_costs] wasmless_transfer_cost = 100_000_000 diff --git a/resources/test/valid/0_9_0/chainspec.toml b/resources/test/valid/0_9_0/chainspec.toml index 597c493d09..c942978fdd 100644 --- a/resources/test/valid/0_9_0/chainspec.toml +++ b/resources/test/valid/0_9_0/chainspec.toml @@ -141,6 +141,7 @@ update_associated_key = { cost = 139, arguments = [0, 1, 2] } write = { cost = 140, arguments = [0, 1, 0, 2] } write_local = { cost = 141, arguments = [0, 1, 2, 3] } enable_contract_version = { cost = 142, arguments = [0, 1, 2, 3] } +risc0_verifier = {cost = 200, arguments = [0, 0, 0, 0]} [system_costs] wasmless_transfer_cost = 100_000_000 diff --git a/resources/test/valid/0_9_0_unordered/chainspec.toml b/resources/test/valid/0_9_0_unordered/chainspec.toml index e922307476..4450d571cc 100644 --- a/resources/test/valid/0_9_0_unordered/chainspec.toml +++ b/resources/test/valid/0_9_0_unordered/chainspec.toml @@ -139,6 +139,7 @@ update_associated_key = { cost = 139, arguments = [0, 1, 2] } write = { cost = 140, arguments = [0, 1, 0, 2] } write_local = { cost = 141, arguments = [0, 1, 2, 3] } enable_contract_version = { cost = 142, arguments = [0, 1, 2, 3] } +risc0_verifier = {cost = 200, arguments = [0, 0, 0, 0]} [system_costs] wasmless_transfer_cost = 100_000_000 diff --git a/resources/test/valid/1_0_0/chainspec.toml b/resources/test/valid/1_0_0/chainspec.toml index c40c8671ee..3379ad5cc2 100644 --- a/resources/test/valid/1_0_0/chainspec.toml +++ b/resources/test/valid/1_0_0/chainspec.toml @@ -142,6 +142,7 @@ update_associated_key = { cost = 139, arguments = [0, 1, 2] } write = { cost = 140, arguments = [0, 1, 0, 2] } write_local = { cost = 141, arguments = [0, 1, 2, 3] } enable_contract_version = { cost = 142, arguments = [0, 1, 2, 3] } +risc0_verifier = {cost = 200, arguments = [0, 0, 0, 0]} [system_costs] wasmless_transfer_cost = 100_000_000 diff --git a/smart_contracts/contract/src/contract_api/mod.rs b/smart_contracts/contract/src/contract_api/mod.rs index 524a8f0705..74f9f7acd6 100644 --- a/smart_contracts/contract/src/contract_api/mod.rs +++ b/smart_contracts/contract/src/contract_api/mod.rs @@ -4,6 +4,7 @@ pub mod account; pub mod runtime; pub mod storage; pub mod system; +pub mod risc0; use alloc::{ alloc::{alloc, Layout}, diff --git a/smart_contracts/contract/src/contract_api/risc0.rs b/smart_contracts/contract/src/contract_api/risc0.rs new file mode 100644 index 0000000000..d66d160686 --- /dev/null +++ b/smart_contracts/contract/src/contract_api/risc0.rs @@ -0,0 +1,15 @@ +use crate::{ext_ffi, unwrap_or_revert::UnwrapOrRevert}; +use casper_types::api_error; +pub fn risc0_verifier>(proof: T) -> [u8;1]{ + let mut res: [u8;1] = [0;1]; + let result = unsafe { + ext_ffi::casper_risc_zero_verifier( + proof.as_ref().as_ptr(), + proof.as_ref().len(), + res.as_mut_ptr(), + 1 + ) + }; + api_error::result_from(result).unwrap_or_revert(); + res +} \ No newline at end of file diff --git a/smart_contracts/contract/src/contract_api/runtime.rs b/smart_contracts/contract/src/contract_api/runtime.rs index d6ada2b8c7..3f20139792 100644 --- a/smart_contracts/contract/src/contract_api/runtime.rs +++ b/smart_contracts/contract/src/contract_api/runtime.rs @@ -53,7 +53,7 @@ pub fn call_contract( let (contract_hash_ptr, contract_hash_size, _bytes1) = contract_api::to_ptr(contract_hash); let (entry_point_name_ptr, entry_point_name_size, _bytes2) = contract_api::to_ptr(entry_point_name); - let (runtime_args_ptr, runtime_args_size, _bytes2) = contract_api::to_ptr(runtime_args); + let (runtime_args_ptr, runtime_args_size, _bytes3) = contract_api::to_ptr(runtime_args); let bytes_written = { let mut bytes_written = MaybeUninit::uninit(); @@ -87,13 +87,13 @@ pub fn call_versioned_contract( entry_point_name: &str, runtime_args: RuntimeArgs, ) -> T { - let (contract_package_hash_ptr, contract_package_hash_size, _bytes) = + let (contract_package_hash_ptr, contract_package_hash_size, _bytes1) = contract_api::to_ptr(contract_package_hash); - let (contract_version_ptr, contract_version_size, _bytes) = + let (contract_version_ptr, contract_version_size, _bytes2) = contract_api::to_ptr(contract_version); - let (entry_point_name_ptr, entry_point_name_size, _bytes) = + let (entry_point_name_ptr, entry_point_name_size, _bytes3) = contract_api::to_ptr(entry_point_name); - let (runtime_args_ptr, runtime_args_size, _bytes) = contract_api::to_ptr(runtime_args); + let (runtime_args_ptr, runtime_args_size, _bytes4) = contract_api::to_ptr(runtime_args); let bytes_written = { let mut bytes_written = MaybeUninit::uninit(); diff --git a/smart_contracts/contract/src/contract_api/system.rs b/smart_contracts/contract/src/contract_api/system.rs index b7b0dff86b..a11e7e54d1 100644 --- a/smart_contracts/contract/src/contract_api/system.rs +++ b/smart_contracts/contract/src/contract_api/system.rs @@ -107,7 +107,7 @@ pub fn get_purse_balance(purse: URef) -> Option { Some(value) } -/// Returns the balance in motes of a purse. +/// Returns the balance in motes of the account's main purse. pub fn get_balance() -> Option { get_purse_balance(account::get_main_purse()) } diff --git a/smart_contracts/contract/src/ext_ffi.rs b/smart_contracts/contract/src/ext_ffi.rs index 3bdb478bb9..65175f5b44 100644 --- a/smart_contracts/contract/src/ext_ffi.rs +++ b/smart_contracts/contract/src/ext_ffi.rs @@ -805,4 +805,10 @@ extern "C" { contract_hash_ptr: *const u8, contract_hash_size: usize, ) -> i32; + pub fn casper_risc_zero_verifier( + proof_ptr: *const u8, + proof_size: usize, + out_ptr: *const u8, + out_size: usize + ) -> i32; } diff --git a/smart_contracts/contract_as/package-lock.json b/smart_contracts/contract_as/package-lock.json index 2b1bcce6d2..e1d6902082 100644 --- a/smart_contracts/contract_as/package-lock.json +++ b/smart_contracts/contract_as/package-lock.json @@ -1,6 +1,6 @@ { "name": "casper-contract", - "version": "1.5.5", + "version": "1.5.6", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/smart_contracts/contract_as/package.json b/smart_contracts/contract_as/package.json index 5e00e5db4c..0b8f7ed40a 100644 --- a/smart_contracts/contract_as/package.json +++ b/smart_contracts/contract_as/package.json @@ -1,6 +1,6 @@ { "name": "casper-contract", - "version": "1.5.5", + "version": "1.5.6", "description": "Library for developing Casper smart contracts.", "homepage": "https://docs.casperlabs.io/en/latest/dapp-dev-guide/index.html", "repository": { diff --git a/smart_contracts/contracts/test/deserialize-error/src/main.rs b/smart_contracts/contracts/test/deserialize-error/src/main.rs index 63852877b4..eab0045601 100644 --- a/smart_contracts/contracts/test/deserialize-error/src/main.rs +++ b/smart_contracts/contracts/test/deserialize-error/src/main.rs @@ -8,7 +8,7 @@ use alloc::{vec, vec::Vec}; use casper_contract::{self, contract_api::storage, unwrap_or_revert::UnwrapOrRevert}; use casper_types::{ api_error, bytesrepr::ToBytes, contracts::Parameters, CLType, ContractHash, EntryPoint, - EntryPointAccess, EntryPointType, EntryPoints, RuntimeArgs, + EntryPointAccess, EntryPointType, EntryPoints, }; #[no_mangle] @@ -42,16 +42,11 @@ mod malicious_ffi { // This is half-baked runtime::call_contract with changed `extra_urefs` // parameter with a desired payload that's supposed to bring the node down. -pub fn my_call_contract( - contract_hash: ContractHash, - _entry_point_name: &str, - runtime_args: RuntimeArgs, -) -> usize { +pub fn my_call_contract(contract_hash: ContractHash, entry_point_name: &str) -> usize { let (contract_hash_ptr, contract_hash_size, _bytes1) = to_ptr(contract_hash); - let malicious_string = vec![255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; - - let (runtime_args_ptr, runtime_args_size, _bytes2) = to_ptr(runtime_args); + let entry_point_name = ToBytes::to_bytes(entry_point_name).unwrap(); + let malicious_args = vec![255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; { let mut bytes_written = 0usize; @@ -59,10 +54,10 @@ pub fn my_call_contract( malicious_ffi::casper_call_contract( contract_hash_ptr, contract_hash_size, - malicious_string.as_ptr(), - malicious_string.len(), - runtime_args_ptr, - runtime_args_size, + entry_point_name.as_ptr(), + entry_point_name.len(), + malicious_args.as_ptr(), + malicious_args.len(), &mut bytes_written as *mut usize, ) }; @@ -90,5 +85,5 @@ pub extern "C" fn call() { }; let (contract_hash, _contract_version) = storage::new_contract(entry_points, None, None, None); - my_call_contract(contract_hash, "do_nothing", RuntimeArgs::default()); + my_call_contract(contract_hash, "do_nothing"); } diff --git a/smart_contracts/contracts/test/regression_20240105/Cargo.toml b/smart_contracts/contracts/test/regression_20240105/Cargo.toml new file mode 100644 index 0000000000..446ef49461 --- /dev/null +++ b/smart_contracts/contracts/test/regression_20240105/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "regression_20240105" +version = "0.1.0" +edition = "2021" + +[dependencies] +casper-contract = { path = "../../../contract", features = ["test-support"] } +casper-types = { path = "../../../../types" } + +[[bin]] +name = "regression_20240105" +path = "src/main.rs" +bench = false +doctest = false +test = false diff --git a/smart_contracts/contracts/test/regression_20240105/src/main.rs b/smart_contracts/contracts/test/regression_20240105/src/main.rs new file mode 100644 index 0000000000..a514467065 --- /dev/null +++ b/smart_contracts/contracts/test/regression_20240105/src/main.rs @@ -0,0 +1,958 @@ +#![no_std] +#![no_main] + +extern crate alloc; + +use alloc::{ + collections::{BTreeMap, BTreeSet}, + format, + string::{String, ToString}, + vec, + vec::Vec, +}; +use core::mem::MaybeUninit; + +use casper_contract::{ + contract_api, + contract_api::{account, runtime, storage, system}, + ext_ffi, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + account::{AccountHash, ActionType, Weight}, + api_error, + bytesrepr::ToBytes, + contracts::MAX_GROUPS, + runtime_args, AccessRights, ApiError, CLType, CLValue, ContractHash, ContractPackageHash, + EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Key, Parameter, RuntimeArgs, + TransferredTo, URef, U512, +}; + +const NOOP: &str = "noop"; + +fn to_ptr(t: &T) -> (*const u8, usize, Vec) { + let bytes = t.to_bytes().unwrap_or_revert(); + let ptr = bytes.as_ptr(); + let size = bytes.len(); + (ptr, size, bytes) +} + +#[no_mangle] +extern "C" fn noop() {} + +fn store_noop_contract(maybe_contract_pkg_hash: Option) -> ContractHash { + let mut entry_points = EntryPoints::new(); + entry_points.add_entry_point(EntryPoint::new( + NOOP, + vec![], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::Contract, + )); + match maybe_contract_pkg_hash { + Some(contract_pkg_hash) => { + let (contract_hash, _version) = + storage::add_contract_version(contract_pkg_hash, entry_points, BTreeMap::new()); + contract_hash + } + None => { + let (contract_hash, _version) = storage::new_contract(entry_points, None, None, None); + contract_hash + } + } +} + +fn get_name() -> String { + let large_name: bool = runtime::get_named_arg("large_name"); + if large_name { + "a".repeat(10_000) + } else { + "a".to_string() + } +} + +fn get_named_arg_size(name: &str) -> usize { + let mut arg_size: usize = 0; + let ret = unsafe { + ext_ffi::casper_get_named_arg_size( + name.as_bytes().as_ptr(), + name.len(), + &mut arg_size as *mut usize, + ) + }; + api_error::result_from(ret).unwrap_or_revert(); + arg_size +} + +#[no_mangle] +pub extern "C" fn call() { + let fn_arg: String = runtime::get_named_arg("fn"); + match fn_arg.as_str() { + "write" => { + let len: u32 = runtime::get_named_arg("len"); + let uref = storage::new_uref(()); + let key = Key::from(uref); + let (key_ptr, key_size, _bytes1) = to_ptr(&key); + let value = vec![u8::MAX; len as usize]; + let cl_value = CLValue::from_t(value).unwrap_or_revert(); + let (cl_value_ptr, cl_value_size, _bytes2) = to_ptr(&cl_value); + for _i in 0..u64::MAX { + unsafe { + ext_ffi::casper_write(key_ptr, key_size, cl_value_ptr, cl_value_size); + } + } + } + "read" => { + let len: Option = runtime::get_named_arg("len"); + let key = match len { + Some(len) => { + let key = Key::URef(storage::new_uref(())); + let uref = storage::new_uref(()); + storage::write(uref, vec![u8::MAX; len as usize]); + key + } + None => Key::Hash([0; 32]), + }; + let key_bytes = key.into_bytes().unwrap(); + let key_ptr = key_bytes.as_ptr(); + let key_size = key_bytes.len(); + let mut buffer = vec![0; len.unwrap_or_default() as usize]; + for _i in 0..u64::MAX { + let mut value_size = MaybeUninit::uninit(); + let ret = unsafe { + ext_ffi::casper_read_value(key_ptr, key_size, value_size.as_mut_ptr()) + }; + // If we actually read a value, we need to clear the host buffer before trying to + // read another value. + if len.is_some() { + assert_eq!(ret, 0); + } else { + assert_eq!(ret, u32::from(ApiError::ValueNotFound) as i32); + continue; + } + unsafe { + value_size.assume_init(); + } + let mut bytes_written = MaybeUninit::uninit(); + let ret = unsafe { + ext_ffi::casper_read_host_buffer( + buffer.as_mut_ptr(), + buffer.len(), + bytes_written.as_mut_ptr(), + ) + }; + assert_eq!(ret, 0); + } + } + "add" => { + let large: bool = runtime::get_named_arg("large"); + if large { + let uref = storage::new_uref(U512::zero()); + for _i in 0..u64::MAX { + storage::add(uref, U512::MAX) + } + } else { + let uref = storage::new_uref(0_i32); + for _i in 0..u64::MAX { + storage::add(uref, 1_i32) + } + } + } + "new" => { + let len: u32 = runtime::get_named_arg("len"); + for _i in 0..u64::MAX { + let _n = storage::new_uref(vec![u32::MAX; len as usize]); + } + } + "call_contract" => { + let args_len: u32 = runtime::get_named_arg("args_len"); + let args = runtime_args! { "a" => vec![u8::MAX; args_len as usize] }; + let contract_hash = store_noop_contract(None); + let (contract_hash_ptr, contract_hash_size, _bytes1) = to_ptr(&contract_hash); + let (entry_point_name_ptr, entry_point_name_size, _bytes2) = to_ptr(&NOOP); + let (runtime_args_ptr, runtime_args_size, _bytes3) = to_ptr(&args); + let mut bytes_written = MaybeUninit::uninit(); + for _i in 0..u64::MAX { + let ret = unsafe { + ext_ffi::casper_call_contract( + contract_hash_ptr, + contract_hash_size, + entry_point_name_ptr, + entry_point_name_size, + runtime_args_ptr, + runtime_args_size, + bytes_written.as_mut_ptr(), + ) + }; + api_error::result_from(ret).unwrap_or_revert(); + } + } + "get_key" => { + let maybe_large_key: Option = runtime::get_named_arg("large_key"); + match maybe_large_key { + Some(large_key) => { + let name = get_name(); + let key = if large_key { + let uref = storage::new_uref(()); + Key::URef(uref) + } else { + Key::EraInfo(EraId::new(0)) + }; + runtime::put_key(&name, key); + for _i in 0..u64::MAX { + let _k = runtime::get_key(&name); + } + } + None => { + for i in 0..u64::MAX { + let _k = runtime::get_key(i.to_string().as_str()); + } + } + } + } + "has_key" => { + let exists: bool = runtime::get_named_arg("key_exists"); + if exists { + let name = get_name(); + runtime::put_key(&name, Key::EraInfo(EraId::new(0))); + for _i in 0..u64::MAX { + let _b = runtime::has_key(&name); + } + } else { + for i in 0..u64::MAX { + let _b = runtime::has_key(i.to_string().as_str()); + } + } + } + "put_key" => { + let base_name = get_name(); + let large_key: bool = runtime::get_named_arg("large_key"); + let key = if large_key { + let uref = storage::new_uref(()); + Key::URef(uref) + } else { + Key::EraInfo(EraId::new(0)) + }; + let maybe_num_keys: Option = runtime::get_named_arg("num_keys"); + let num_keys = maybe_num_keys.unwrap_or(u32::MAX); + for i in 0..num_keys { + runtime::put_key(format!("{base_name}{i}").as_str(), key); + } + } + "is_valid_uref" => { + let valid: bool = runtime::get_named_arg("valid"); + let uref = if valid { + storage::new_uref(()) + } else { + URef::new([1; 32], AccessRights::default()) + }; + for _i in 0..u64::MAX { + let is_valid = runtime::is_valid_uref(uref); + assert_eq!(valid, is_valid); + } + } + "add_associated_key" => { + let remove_after_adding: bool = runtime::get_named_arg("remove_after_adding"); + let account_hash = AccountHash::new([1; 32]); + let weight = Weight::new(1); + for _i in 0..u64::MAX { + if remove_after_adding { + account::add_associated_key(account_hash, weight).unwrap_or_revert(); + // Remove to avoid getting a duplicate key error on next iteration. + account::remove_associated_key(account_hash).unwrap_or_revert(); + } else { + let _e = account::add_associated_key(account_hash, weight); + } + } + } + "remove_associated_key" => { + for _i in 0..u64::MAX { + account::remove_associated_key(AccountHash::new([1; 32])).unwrap_err(); + } + } + "update_associated_key" => { + let exists: bool = runtime::get_named_arg("exists"); + let account_hash = AccountHash::new([1; 32]); + if exists { + account::add_associated_key(account_hash, Weight::new(1)).unwrap_or_revert(); + for i in 0..u64::MAX { + account::update_associated_key(account_hash, Weight::new(i as u8)) + .unwrap_or_revert(); + } + } else { + for i in 0..u64::MAX { + account::update_associated_key(account_hash, Weight::new(i as u8)).unwrap_err(); + } + } + } + "set_action_threshold" => { + for _i in 0..u64::MAX { + account::set_action_threshold(ActionType::Deployment, Weight::new(1)) + .unwrap_or_revert(); + } + } + "load_named_keys" => { + let num_keys: u32 = runtime::get_named_arg("num_keys"); + if num_keys == 0 { + for _i in 0..u64::MAX { + assert!(runtime::list_named_keys().is_empty()); + } + return; + } + // Where `num_keys` > 0, we should have put the required number of named keys in a + // previous execution via the `put_key` flow of this contract. + for _i in 0..u64::MAX { + assert_eq!(runtime::list_named_keys().len() as u32, num_keys); + } + } + "remove_key" => { + let name = get_name(); + for _i in 0..u64::MAX { + runtime::remove_key(&name) + } + } + "get_caller" => { + for _i in 0..u64::MAX { + let _c = runtime::get_caller(); + } + } + "get_blocktime" => { + for _i in 0..u64::MAX { + let _b = runtime::get_blocktime(); + } + } + "create_purse" => { + for _i in 0..u64::MAX { + let _u = system::create_purse(); + } + } + "transfer_to_account" => { + let account_exists: bool = runtime::get_named_arg("account_exists"); + let amount = U512::one(); + let id = Some(u64::MAX); + if account_exists { + let target = AccountHash::new([1; 32]); + let to = system::transfer_to_account(target, amount, id).unwrap_or_revert(); + assert_eq!(to, TransferredTo::NewAccount); + for _i in 0..u64::MAX { + let to = system::transfer_to_account(target, amount, id).unwrap_or_revert(); + assert_eq!(to, TransferredTo::ExistingAccount); + } + } else { + let mut array = [0_u8; 32]; + for index in 0..32 { + for i in 1..=u8::MAX { + array[index] = i; + let target = AccountHash::new(array); + let to = system::transfer_to_account(target, amount, id).unwrap_or_revert(); + assert_eq!(to, TransferredTo::NewAccount); + } + } + } + } + "transfer_from_purse_to_account" => { + let account_exists: bool = runtime::get_named_arg("account_exists"); + let source = account::get_main_purse(); + let amount = U512::one(); + let id = Some(u64::MAX); + if account_exists { + let target = AccountHash::new([1; 32]); + let to = system::transfer_to_account(target, amount, id).unwrap_or_revert(); + assert_eq!(to, TransferredTo::NewAccount); + for _i in 0..u64::MAX { + let to = system::transfer_from_purse_to_account(source, target, amount, id) + .unwrap_or_revert(); + assert_eq!(to, TransferredTo::ExistingAccount); + } + } else { + let mut array = [0_u8; 32]; + for index in 0..32 { + for i in 1..=u8::MAX { + array[index] = i; + let target = AccountHash::new(array); + let to = system::transfer_from_purse_to_account(source, target, amount, id) + .unwrap_or_revert(); + assert_eq!(to, TransferredTo::NewAccount); + } + } + } + } + "transfer_from_purse_to_purse" => { + let source = account::get_main_purse(); + let target = system::create_purse(); + let amount = U512::one(); + let id = Some(u64::MAX); + system::transfer_from_purse_to_purse(source, target, amount, id).unwrap_or_revert(); + for _i in 0..u64::MAX { + system::transfer_from_purse_to_purse(source, target, amount, id).unwrap_or_revert(); + } + } + "get_balance" => { + let purse_exists: bool = runtime::get_named_arg("purse_exists"); + let uref = if purse_exists { + account::get_main_purse() + } else { + URef::new([1; 32], AccessRights::empty()) + }; + for _i in 0..u64::MAX { + let maybe_balance = system::get_purse_balance(uref); + assert_eq!(maybe_balance.is_some(), purse_exists); + } + } + "get_phase" => { + for _i in 0..u64::MAX { + let _p = runtime::get_phase(); + } + } + "get_system_contract" => { + for _i in 0..u64::MAX { + let _h = system::get_mint(); + } + } + "get_main_purse" => { + for _i in 0..u64::MAX { + let _u = account::get_main_purse(); + } + } + "read_host_buffer" => { + // The case where the host buffer is repeatedly filled is covered in the `read` + // branch above. All we do here is check repeatedly where `read_host_buffer` returns + // `HostBufferEmpty`. + let mut buffer = vec![0; 1]; + let mut bytes_written = MaybeUninit::uninit(); + for _i in 0..u64::MAX { + let ret = unsafe { + ext_ffi::casper_read_host_buffer( + buffer.as_mut_ptr(), + buffer.len(), + bytes_written.as_mut_ptr(), + ) + }; + assert_eq!(ret, u32::from(ApiError::HostBufferEmpty) as i32); + } + } + "create_contract_package_at_hash" => { + for _i in 0..u64::MAX { + let _h = storage::create_contract_package_at_hash(); + } + } + "add_contract_version" => { + let entry_points_len: u32 = runtime::get_named_arg("entry_points_len"); + let mut entry_points = EntryPoints::new(); + for entry_point_index in 0..entry_points_len { + entry_points.add_entry_point(EntryPoint::new( + format!("function_{entry_point_index}"), + vec![Parameter::new("a", CLType::PublicKey); 10], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::Contract, + )); + } + let named_keys_len: u32 = runtime::get_named_arg("named_keys_len"); + let mut named_keys = BTreeMap::new(); + for named_key_index in 0..named_keys_len { + let _ = named_keys.insert(named_key_index.to_string(), Key::Hash([1; 32])); + } + let (contract_pkg_hash, _uref) = storage::create_contract_package_at_hash(); + for i in 1..u64::MAX { + let (_h, version) = storage::add_contract_version( + contract_pkg_hash, + entry_points.clone(), + named_keys.clone(), + ); + assert_eq!(version, i as u32); + } + } + "disable_contract_version" => { + let (contract_pkg_hash, _uref) = storage::create_contract_package_at_hash(); + let (contract_hash, _version) = storage::add_contract_version( + contract_pkg_hash, + EntryPoints::new(), + BTreeMap::new(), + ); + for _i in 0..u64::MAX { + storage::disable_contract_version(contract_pkg_hash, contract_hash) + .unwrap_or_revert(); + } + } + "call_versioned_contract" => { + let args_len: u32 = runtime::get_named_arg("args_len"); + let args = runtime_args! { "a" => vec![u8::MAX; args_len as usize] }; + let (contract_pkg_hash, _uref) = storage::create_contract_package_at_hash(); + let _ = store_noop_contract(Some(contract_pkg_hash)); + let (contract_pkg_hash_ptr, contract_pkg_hash_size, _bytes1) = + to_ptr(&contract_pkg_hash); + let (contract_version_ptr, contract_version_size, _bytes2) = to_ptr(&Some(1_u32)); + let (entry_point_name_ptr, entry_point_name_size, _bytes3) = to_ptr(&NOOP); + let (runtime_args_ptr, runtime_args_size, _bytes4) = to_ptr(&args); + let mut bytes_written = MaybeUninit::uninit(); + for _i in 0..u64::MAX { + let ret = unsafe { + ext_ffi::casper_call_versioned_contract( + contract_pkg_hash_ptr, + contract_pkg_hash_size, + contract_version_ptr, + contract_version_size, + entry_point_name_ptr, + entry_point_name_size, + runtime_args_ptr, + runtime_args_size, + bytes_written.as_mut_ptr(), + ) + }; + api_error::result_from(ret).unwrap_or_revert(); + } + } + "create_contract_user_group" => { + let label_len: u32 = runtime::get_named_arg("label_len"); + assert!(label_len > 0); + let label_prefix: String = "a".repeat(label_len as usize - 1); + let num_new_urefs: u8 = runtime::get_named_arg("num_new_urefs"); + let num_existing_urefs: u8 = runtime::get_named_arg("num_existing_urefs"); + let mut existing_urefs = BTreeSet::new(); + for _ in 0..num_existing_urefs { + existing_urefs.insert(storage::new_uref(())); + } + let (existing_urefs_ptr, existing_urefs_size, _bytes1) = to_ptr(&existing_urefs); + let (contract_pkg_hash, _uref) = storage::create_contract_package_at_hash(); + let (contract_pkg_hash_ptr, contract_pkg_hash_size, _bytes2) = + to_ptr(&contract_pkg_hash); + let mut index = 0_u8; + let mut label = String::new(); + let allow_exceeding_max_groups: bool = + runtime::get_named_arg("allow_exceeding_max_groups"); + let expect_failure = num_new_urefs == u8::MAX || allow_exceeding_max_groups; + let mut buffer = vec![0_u8; 5_000]; + let mut output_size = MaybeUninit::uninit(); + let mut bytes_written = MaybeUninit::uninit(); + loop { + if index == MAX_GROUPS && !allow_exceeding_max_groups { + // We need to remove the group to avoid hitting the `contracts::MAX_GROUPS` + // limit (currently 10). + let result = storage::remove_contract_user_group(contract_pkg_hash, &label); + if !expect_failure { + result.unwrap_or_revert(); + } + } else { + label = format!("{label_prefix}{index}"); + index += 1; + } + let (label_ptr, label_size, _bytes3) = to_ptr(&label); + let ret = unsafe { + ext_ffi::casper_create_contract_user_group( + contract_pkg_hash_ptr, + contract_pkg_hash_size, + label_ptr, + label_size, + num_new_urefs, + existing_urefs_ptr, + existing_urefs_size, + output_size.as_mut_ptr(), + ) + }; + if !expect_failure { + api_error::result_from(ret).unwrap_or_revert(); + let ret = unsafe { + ext_ffi::casper_read_host_buffer( + buffer.as_mut_ptr(), + buffer.len(), + bytes_written.as_mut_ptr(), + ) + }; + api_error::result_from(ret).unwrap_or_revert(); + } + } + } + "print" => { + let num_chars: u32 = runtime::get_named_arg("num_chars"); + let value: String = "a".repeat(num_chars as usize); + for _i in 0..u64::MAX { + runtime::print(&value); + } + } + "get_runtime_arg_size" => { + let name = "arg"; + for _i in 0..u64::MAX { + let _s = get_named_arg_size(name); + } + } + "get_runtime_arg" => { + let name = "arg"; + let arg_size = get_named_arg_size(name); + let data_non_null_ptr = contract_api::alloc_bytes(arg_size); + for _i in 0..u64::MAX { + let ret = unsafe { + ext_ffi::casper_get_named_arg( + name.as_bytes().as_ptr(), + name.len(), + data_non_null_ptr.as_ptr(), + arg_size, + ) + }; + api_error::result_from(ret).unwrap_or_revert(); + } + } + "remove_contract_user_group" => { + let (contract_pkg_hash, _uref) = storage::create_contract_package_at_hash(); + for _i in 0..u64::MAX { + storage::remove_contract_user_group(contract_pkg_hash, "a").unwrap_err(); + } + } + "extend_contract_user_group_urefs" => { + let allow_exceeding_max_urefs: bool = + runtime::get_named_arg("allow_exceeding_max_urefs"); + let (contract_pkg_hash, _uref) = storage::create_contract_package_at_hash(); + let label = "a"; + let _ = + storage::create_contract_user_group(contract_pkg_hash, label, 0, BTreeSet::new()) + .unwrap_or_revert(); + for _i in 0..u64::MAX { + if allow_exceeding_max_urefs { + let _r = storage::provision_contract_user_group_uref(contract_pkg_hash, label); + } else { + let uref = + storage::provision_contract_user_group_uref(contract_pkg_hash, label) + .unwrap_or_revert(); + storage::remove_contract_user_group_urefs( + contract_pkg_hash, + label, + BTreeSet::from_iter(Some(uref)), + ) + .unwrap_or_revert(); + } + } + } + "remove_contract_user_group_urefs" => { + // The success case is covered in `create_contract_user_group` above. We only test + // for unknown user groups here. + let (contract_pkg_hash, _uref) = storage::create_contract_package_at_hash(); + for _i in 0..u64::MAX { + storage::remove_contract_user_group(contract_pkg_hash, "a").unwrap_err(); + } + } + "blake2b" => { + let len: u32 = runtime::get_named_arg("len"); + let data = vec![1; len as usize]; + for _i in 0..u64::MAX { + let _hash = runtime::blake2b(&data); + } + } + "new_dictionary" => { + let mut buffer = vec![0_u8; 33]; // bytesrepr-serialized length of URef + for _i in 0..u64::MAX { + let mut value_size = MaybeUninit::uninit(); + let ret = unsafe { ext_ffi::casper_new_dictionary(value_size.as_mut_ptr()) }; + api_error::result_from(ret).unwrap_or_revert(); + assert_eq!(buffer.len(), unsafe { value_size.assume_init() }); + let mut bytes_written = MaybeUninit::uninit(); + let ret = unsafe { + ext_ffi::casper_read_host_buffer( + buffer.as_mut_ptr(), + buffer.len(), + bytes_written.as_mut_ptr(), + ) + }; + assert_eq!(ret, 0); + } + } + "dictionary_get" => { + let name_len: u32 = runtime::get_named_arg("name_len"); + let name: String = "a".repeat(name_len as usize); + let value_len: u32 = runtime::get_named_arg("value_len"); + let value = vec![u8::MAX; value_len as usize]; + let uref = storage::new_dictionary("a").unwrap_or_revert(); + storage::dictionary_put(uref, &name, value); + + for _i in 0..u64::MAX { + let read_value: Vec = storage::dictionary_get(uref, &name) + .unwrap_or_revert() + .unwrap_or_revert(); + assert_eq!(read_value.len(), value_len as usize); + } + } + "dictionary_put" => { + let name_len: u32 = runtime::get_named_arg("name_len"); + let name: String = "a".repeat(name_len as usize); + + let value_len: u32 = runtime::get_named_arg("value_len"); + let value = vec![u8::MAX; value_len as usize]; + + let uref = storage::new_dictionary("a").unwrap_or_revert(); + let (uref_ptr, uref_size, _bytes1) = to_ptr(&uref); + + let (item_name_ptr, item_name_size, _bytes2) = to_ptr(&name); + + let cl_value = CLValue::from_t(value).unwrap_or_revert(); + let (cl_value_ptr, cl_value_size, _bytes3) = to_ptr(&cl_value); + + for _i in 0..u64::MAX { + let ret = unsafe { + ext_ffi::casper_dictionary_put( + uref_ptr, + uref_size, + item_name_ptr, + item_name_size, + cl_value_ptr, + cl_value_size, + ) + }; + api_error::result_from(ret).unwrap_or_revert(); + } + } + "load_call_stack" => { + for _i in 0..u64::MAX { + let call_stack = runtime::get_call_stack(); + assert_eq!(call_stack.len(), 1); + } + } + "load_authorization_keys" => { + let setup: bool = runtime::get_named_arg("setup"); + if setup { + let weight = Weight::new(1); + for i in 1..100 { + let account_hash = AccountHash::new([i; 32]); + account::add_associated_key(account_hash, weight).unwrap_or_revert(); + } + } else { + for _i in 0..u64::MAX { + let _k = runtime::list_authorization_keys(); + } + } + } + "random_bytes" => { + for _i in 0..u64::MAX { + let _n = runtime::random_bytes(); + } + } + "dictionary_read" => { + let name_len: u32 = runtime::get_named_arg("name_len"); + let name: String = "a".repeat(name_len as usize); + let value_len: u32 = runtime::get_named_arg("value_len"); + let value = vec![u8::MAX; value_len as usize]; + let uref = storage::new_dictionary("a").unwrap_or_revert(); + storage::dictionary_put(uref, &name, value); + let key = Key::dictionary(uref, name.as_bytes()); + + for _i in 0..u64::MAX { + let read_value: Vec = storage::dictionary_read(key) + .unwrap_or_revert() + .unwrap_or_revert(); + assert_eq!(read_value.len(), value_len as usize); + } + } + "enable_contract_version" => { + let (contract_pkg_hash, _uref) = storage::create_contract_package_at_hash(); + let (contract_hash, _version) = storage::add_contract_version( + contract_pkg_hash, + EntryPoints::new(), + BTreeMap::new(), + ); + for _i in 0..u64::MAX { + storage::enable_contract_version(contract_pkg_hash, contract_hash) + .unwrap_or_revert(); + } + } + _ => panic!(), + } +} + +#[no_mangle] +extern "C" fn function_0() {} +#[no_mangle] +extern "C" fn function_1() {} +#[no_mangle] +extern "C" fn function_2() {} +#[no_mangle] +extern "C" fn function_3() {} +#[no_mangle] +extern "C" fn function_4() {} +#[no_mangle] +extern "C" fn function_5() {} +#[no_mangle] +extern "C" fn function_6() {} +#[no_mangle] +extern "C" fn function_7() {} +#[no_mangle] +extern "C" fn function_8() {} +#[no_mangle] +extern "C" fn function_9() {} +#[no_mangle] +extern "C" fn function_10() {} +#[no_mangle] +extern "C" fn function_11() {} +#[no_mangle] +extern "C" fn function_12() {} +#[no_mangle] +extern "C" fn function_13() {} +#[no_mangle] +extern "C" fn function_14() {} +#[no_mangle] +extern "C" fn function_15() {} +#[no_mangle] +extern "C" fn function_16() {} +#[no_mangle] +extern "C" fn function_17() {} +#[no_mangle] +extern "C" fn function_18() {} +#[no_mangle] +extern "C" fn function_19() {} +#[no_mangle] +extern "C" fn function_20() {} +#[no_mangle] +extern "C" fn function_21() {} +#[no_mangle] +extern "C" fn function_22() {} +#[no_mangle] +extern "C" fn function_23() {} +#[no_mangle] +extern "C" fn function_24() {} +#[no_mangle] +extern "C" fn function_25() {} +#[no_mangle] +extern "C" fn function_26() {} +#[no_mangle] +extern "C" fn function_27() {} +#[no_mangle] +extern "C" fn function_28() {} +#[no_mangle] +extern "C" fn function_29() {} +#[no_mangle] +extern "C" fn function_30() {} +#[no_mangle] +extern "C" fn function_31() {} +#[no_mangle] +extern "C" fn function_32() {} +#[no_mangle] +extern "C" fn function_33() {} +#[no_mangle] +extern "C" fn function_34() {} +#[no_mangle] +extern "C" fn function_35() {} +#[no_mangle] +extern "C" fn function_36() {} +#[no_mangle] +extern "C" fn function_37() {} +#[no_mangle] +extern "C" fn function_38() {} +#[no_mangle] +extern "C" fn function_39() {} +#[no_mangle] +extern "C" fn function_40() {} +#[no_mangle] +extern "C" fn function_41() {} +#[no_mangle] +extern "C" fn function_42() {} +#[no_mangle] +extern "C" fn function_43() {} +#[no_mangle] +extern "C" fn function_44() {} +#[no_mangle] +extern "C" fn function_45() {} +#[no_mangle] +extern "C" fn function_46() {} +#[no_mangle] +extern "C" fn function_47() {} +#[no_mangle] +extern "C" fn function_48() {} +#[no_mangle] +extern "C" fn function_49() {} +#[no_mangle] +extern "C" fn function_50() {} +#[no_mangle] +extern "C" fn function_51() {} +#[no_mangle] +extern "C" fn function_52() {} +#[no_mangle] +extern "C" fn function_53() {} +#[no_mangle] +extern "C" fn function_54() {} +#[no_mangle] +extern "C" fn function_55() {} +#[no_mangle] +extern "C" fn function_56() {} +#[no_mangle] +extern "C" fn function_57() {} +#[no_mangle] +extern "C" fn function_58() {} +#[no_mangle] +extern "C" fn function_59() {} +#[no_mangle] +extern "C" fn function_60() {} +#[no_mangle] +extern "C" fn function_61() {} +#[no_mangle] +extern "C" fn function_62() {} +#[no_mangle] +extern "C" fn function_63() {} +#[no_mangle] +extern "C" fn function_64() {} +#[no_mangle] +extern "C" fn function_65() {} +#[no_mangle] +extern "C" fn function_66() {} +#[no_mangle] +extern "C" fn function_67() {} +#[no_mangle] +extern "C" fn function_68() {} +#[no_mangle] +extern "C" fn function_69() {} +#[no_mangle] +extern "C" fn function_70() {} +#[no_mangle] +extern "C" fn function_71() {} +#[no_mangle] +extern "C" fn function_72() {} +#[no_mangle] +extern "C" fn function_73() {} +#[no_mangle] +extern "C" fn function_74() {} +#[no_mangle] +extern "C" fn function_75() {} +#[no_mangle] +extern "C" fn function_76() {} +#[no_mangle] +extern "C" fn function_77() {} +#[no_mangle] +extern "C" fn function_78() {} +#[no_mangle] +extern "C" fn function_79() {} +#[no_mangle] +extern "C" fn function_80() {} +#[no_mangle] +extern "C" fn function_81() {} +#[no_mangle] +extern "C" fn function_82() {} +#[no_mangle] +extern "C" fn function_83() {} +#[no_mangle] +extern "C" fn function_84() {} +#[no_mangle] +extern "C" fn function_85() {} +#[no_mangle] +extern "C" fn function_86() {} +#[no_mangle] +extern "C" fn function_87() {} +#[no_mangle] +extern "C" fn function_88() {} +#[no_mangle] +extern "C" fn function_89() {} +#[no_mangle] +extern "C" fn function_90() {} +#[no_mangle] +extern "C" fn function_91() {} +#[no_mangle] +extern "C" fn function_92() {} +#[no_mangle] +extern "C" fn function_93() {} +#[no_mangle] +extern "C" fn function_94() {} +#[no_mangle] +extern "C" fn function_95() {} +#[no_mangle] +extern "C" fn function_96() {} +#[no_mangle] +extern "C" fn function_97() {} +#[no_mangle] +extern "C" fn function_98() {} +#[no_mangle] +extern "C" fn function_99() {} diff --git a/types/CHANGELOG.md b/types/CHANGELOG.md index 5c8e45fa4a..08b78b254f 100644 --- a/types/CHANGELOG.md +++ b/types/CHANGELOG.md @@ -11,13 +11,6 @@ All notable changes to this project will be documented in this file. The format -## Unreleased - -### Changed -* Remove filesystem I/O functionality from the `std` feature, and gated this behind a new feature `std-fs-io` which depends upon `std`. - - - ## 4.0.1 ### Added diff --git a/types/Cargo.toml b/types/Cargo.toml index 96aa208dd2..98c2eedcb1 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -18,7 +18,7 @@ blake2 = { version = "0.9.0", default-features = false } datasize = { version = "0.2.4", optional = true } derp = { version = "0.0.14", optional = true } ed25519-dalek = { version = "2.0.0", default-features = false, features = ["alloc", "zeroize"] } -getrandom = { version = "0.2.0", features = ["rdrand", "js"], optional = true } +getrandom = { version = "0.2.0", features = ["rdrand"], optional = true } hex = { version = "0.4.2", default-features = false, features = ["alloc"] } hex_fmt = "0.3.0" humantime = { version = "2", optional = true } @@ -67,10 +67,7 @@ untrusted = "0.7.1" [features] json-schema = ["once_cell", "schemars"] -# Includes a restricted set of std lib functionality suitable for usage e.g. in a JS environment when compiled to Wasm. -std = ["base16/std", "derp", "getrandom/std", "humantime", "once_cell", "pem", "serde_json/preserve_order", "thiserror", "untrusted"] -# Includes a complete set of std lib functionality, including filesystem I/O operations. -std-fs-io = ["std"] +std = ["derp", "getrandom/std", "humantime", "once_cell", "pem", "serde_json/preserve_order", "thiserror", "untrusted"] testing = ["proptest", "proptest-derive", "rand_pcg", "strum"] # DEPRECATED - use "testing" instead of "gens". gens = ["testing"] diff --git a/types/src/bytesrepr.rs b/types/src/bytesrepr.rs index 136dd19a94..3bc692281a 100644 --- a/types/src/bytesrepr.rs +++ b/types/src/bytesrepr.rs @@ -2,7 +2,6 @@ mod bytes; use alloc::{ - alloc::{alloc, Layout}, collections::{BTreeMap, BTreeSet, VecDeque}, str, string::String, @@ -15,7 +14,6 @@ use core::{ convert::TryInto, fmt::{self, Display, Formatter}, mem, - ptr::NonNull, }; #[cfg(feature = "datasize")] @@ -415,7 +413,7 @@ impl ToBytes for Vec { fn to_bytes(&self) -> Result, Error> { ensure_efficient_serialization::(); - let mut result = try_vec_with_capacity(self.serialized_length())?; + let mut result = Vec::with_capacity(self.serialized_length()); let length_32: u32 = self.len().try_into().map_err(|_| Error::NotRepresentable)?; result.append(&mut length_32.to_bytes()?); @@ -454,37 +452,34 @@ impl ToBytes for Vec { } } -// TODO Replace `try_vec_with_capacity` with `Vec::try_reserve_exact` once it's in stable. -fn try_vec_with_capacity(capacity: usize) -> Result, Error> { - // see https://doc.rust-lang.org/src/alloc/raw_vec.rs.html#75-98 - let elem_size = mem::size_of::(); - let alloc_size = capacity.checked_mul(elem_size).ok_or(Error::OutOfMemory)?; - - let ptr = if alloc_size == 0 { - NonNull::::dangling() - } else { - let align = mem::align_of::(); - let layout = Layout::from_size_align(alloc_size, align).map_err(|_| Error::OutOfMemory)?; - let raw_ptr = unsafe { alloc(layout) }; - let non_null_ptr = NonNull::::new(raw_ptr).ok_or(Error::OutOfMemory)?; - non_null_ptr.cast() - }; - unsafe { Ok(Vec::from_raw_parts(ptr.as_ptr(), 0, capacity)) } -} - fn vec_from_vec(bytes: Vec) -> Result<(Vec, Vec), Error> { ensure_efficient_serialization::(); Vec::::from_bytes(bytes.as_slice()).map(|(x, remainder)| (x, Vec::from(remainder))) } +/// Returns a conservative estimate for the preallocated number of elements for a new `Vec`. +/// +/// `hint` indicates the desired upper limit in heap size (in bytes), which is itself bounded by +/// 4096 bytes. This function will never return less than 1. +#[inline] +fn cautious(hint: usize) -> usize { + let el_size = core::mem::size_of::(); + core::cmp::max(core::cmp::min(hint, 4096 / el_size), 1) +} + impl FromBytes for Vec { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { ensure_efficient_serialization::(); let (count, mut stream) = u32::from_bytes(bytes)?; - let mut result = try_vec_with_capacity(count as usize)?; + if count == 0 { + return Ok((Vec::new(), stream)); + } + + let mut result = Vec::with_capacity(cautious::(count as usize)); + for _ in 0..count { let (value, remainder) = T::from_bytes(stream)?; result.push(value); @@ -1252,7 +1247,7 @@ where /// avoid using serializing Vec. fn u8_slice_to_bytes(bytes: &[u8]) -> Result, Error> { let serialized_length = u8_slice_serialized_length(bytes); - let mut vec = try_vec_with_capacity(serialized_length)?; + let mut vec = Vec::with_capacity(serialized_length); let length_prefix: u32 = bytes .len() .try_into() @@ -1328,6 +1323,8 @@ where } #[cfg(test)] mod tests { + use crate::U128; + use super::*; #[test] @@ -1371,6 +1368,54 @@ mod tests { let bytes = b"0123456789".to_vec(); bytes.to_bytes().unwrap(); } + + #[test] + fn should_calculate_capacity() { + #[allow(dead_code)] + struct CustomStruct { + u8_field: u8, + u16_field: u16, + u32_field: u32, + u64_field: u64, + // Here we're using U128 type that represents u128 with a two u64s which is what the + // compiler is doing for x86_64. On 64-bit ARM architecture u128 is aligned + // to 16 bytes, but on x86_64 it's aligned to 8 bytes. This changes the + // memory layout of the struct and affects the results of function `cautious`. + // The expected behaviour of u128 alignment is 8 bytes instead of 16, + // and there is a bug in the rust compiler for this: https://github.com/rust-lang/rust/issues/54341 + u128_field: U128, + str_field: String, + } + assert_eq!( + cautious::(u32::MAX as usize), + 512, + "hint is 2^32-1 and we can only preallocate 512 elements" + ); + assert_eq!( + cautious::(usize::MAX), + 4096, + "hint is usize::MAX and we can only preallocate 4096 elements" + ); + assert_eq!( + cautious::(usize::MAX), + 2048, + "hint is usize::MAX and we can only preallocate 2048 elements" + ); + assert_eq!( + cautious::(usize::MAX), + 73, + "hint is usize::MAX and we can only preallocate 73 elements" + ); + } + + #[test] + fn deserializing_empty_vec_has_no_capacity() { + let bytes = ToBytes::to_bytes(&(0u32, b"123")).unwrap(); + let (vec, rem): (Vec, _) = FromBytes::from_bytes(&bytes).unwrap(); + assert!(vec.is_empty()); + assert_eq!(vec.capacity(), 0); + assert_eq!(rem, b"123"); + } } #[cfg(test)] diff --git a/types/src/cl_value.rs b/types/src/cl_value.rs index a33eaef7f6..1dc1bee5b7 100644 --- a/types/src/cl_value.rs +++ b/types/src/cl_value.rs @@ -15,7 +15,7 @@ use crate::{ bytesrepr::{self, Bytes, FromBytes, ToBytes, U32_SERIALIZED_LENGTH}, checksummed_hex, CLType, CLTyped, }; -pub use jsonrepr::cl_value_to_json; + mod jsonrepr; /// Error while converting a [`CLValue`] into a given type. diff --git a/types/src/crypto/asymmetric_key.rs b/types/src/crypto/asymmetric_key.rs index 16a86d526a..5c82289f02 100644 --- a/types/src/crypto/asymmetric_key.rs +++ b/types/src/crypto/asymmetric_key.rs @@ -45,10 +45,6 @@ use serde_json::json; #[cfg(any(feature = "std", test))] use untrusted::Input; -#[cfg(any(feature = "std", test))] -use crate::crypto::ErrorExt; -#[cfg(any(feature = "std-fs-io", test))] -use crate::file_utils::{read_file, write_file, write_private_file}; #[cfg(any(all(feature = "std", feature = "testing"), test))] use crate::testing::TestRng; use crate::{ @@ -59,6 +55,11 @@ use crate::{ crypto::Error, CLType, CLTyped, Tagged, }; +#[cfg(any(feature = "std", test))] +use crate::{ + crypto::ErrorExt, + file_utils::{read_file, write_file, write_private_file}, +}; #[cfg(any(feature = "testing", test))] pub mod gens; @@ -246,13 +247,11 @@ impl SecretKey { } /// Attempts to write the key bytes to the configured file path. - #[cfg(any(feature = "std-fs-io", test))] pub fn to_file>(&self, file: P) -> Result<(), ErrorExt> { write_private_file(file, self.to_pem()?).map_err(ErrorExt::SecretKeySave) } /// Attempts to read the key bytes from configured file path. - #[cfg(any(feature = "std-fs-io", test))] pub fn from_file>(file: P) -> Result { let data = read_file(file).map_err(ErrorExt::SecretKeyLoad)?; Self::from_pem(data) @@ -529,13 +528,11 @@ impl PublicKey { } /// Attempts to write the key bytes to the configured file path. - #[cfg(any(feature = "std-fs-io", test))] pub fn to_file>(&self, file: P) -> Result<(), ErrorExt> { write_file(file, self.to_pem()?).map_err(ErrorExt::PublicKeySave) } /// Attempts to read the key bytes from configured file path. - #[cfg(any(feature = "std-fs-io", test))] pub fn from_file>(file: P) -> Result { let data = read_file(file).map_err(ErrorExt::PublicKeyLoad)?; Self::from_pem(data) diff --git a/types/src/crypto/error.rs b/types/src/crypto/error.rs index 0f9ec0a439..6750e61f01 100644 --- a/types/src/crypto/error.rs +++ b/types/src/crypto/error.rs @@ -11,7 +11,7 @@ use pem::PemError; #[cfg(any(feature = "std", test))] use thiserror::Error; -#[cfg(any(feature = "std-fs-io", test))] +#[cfg(any(feature = "std", test))] use crate::file_utils::{ReadFileError, WriteFileError}; /// Cryptographic errors. @@ -75,22 +75,18 @@ pub enum ErrorExt { CryptoError(#[from] Error), /// Error trying to read a secret key. - #[cfg(any(feature = "std-fs-io", test))] #[error("secret key load failed: {0}")] SecretKeyLoad(ReadFileError), /// Error trying to read a public key. - #[cfg(any(feature = "std-fs-io", test))] #[error("public key load failed: {0}")] PublicKeyLoad(ReadFileError), /// Error trying to write a secret key. - #[cfg(any(feature = "std-fs-io", test))] #[error("secret key save failed: {0}")] SecretKeySave(WriteFileError), /// Error trying to write a public key. - #[cfg(any(feature = "std-fs-io", test))] #[error("public key save failed: {0}")] PublicKeySave(WriteFileError), diff --git a/types/src/key.rs b/types/src/key.rs index f092a74a3b..c9ca44a061 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -1209,10 +1209,29 @@ mod tests { // Prefix is 2^32-1 = shouldn't allocate that much let bytes: Vec = vec![255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; let res: Result<(Vec, &[u8]), _> = FromBytes::from_bytes(&bytes); - #[cfg(target_os = "linux")] - assert_eq!(res.expect_err("should fail"), Error::OutOfMemory); - #[cfg(target_os = "macos")] - assert_eq!(res.expect_err("should fail"), Error::EarlyEndOfStream); + assert_eq!( + res.expect_err("should fail"), + Error::EarlyEndOfStream, + "length prefix says 2^32-1, but there's not enough data in the stream" + ); + + // Prefix is 2^32-2 = shouldn't allocate that much + let bytes: Vec = vec![255, 255, 255, 254, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + let res: Result<(Vec, &[u8]), _> = FromBytes::from_bytes(&bytes); + assert_eq!( + res.expect_err("should fail"), + Error::EarlyEndOfStream, + "length prefix says 2^32-2, but there's not enough data in the stream" + ); + + // Valid prefix but not enough data in the stream + let bytes: Vec = vec![0, 0, 0, 254, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + let res: Result<(Vec, &[u8]), _> = FromBytes::from_bytes(&bytes); + assert_eq!( + res.expect_err("should fail"), + Error::EarlyEndOfStream, + "length prefix says 254, but there's not enough data in the stream" + ); } #[test] diff --git a/types/src/lib.rs b/types/src/lib.rs index df4a7f13d1..c2aeac55d0 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -35,7 +35,7 @@ pub mod crypto; mod deploy_info; mod era_id; mod execution_result; -#[cfg(any(feature = "std-fs-io", test))] +#[cfg(any(feature = "std", test))] pub mod file_utils; mod gas; #[cfg(any(feature = "testing", feature = "gens", test))] @@ -66,7 +66,7 @@ pub use access_rights::{ pub use api_error::ApiError; pub use block_time::{BlockTime, BLOCKTIME_SERIALIZED_LENGTH}; pub use cl_type::{named_key_type, CLType, CLTyped}; -pub use cl_value::{cl_value_to_json, CLTypeMismatch, CLValue, CLValueError}; +pub use cl_value::{CLTypeMismatch, CLValue, CLValueError}; pub use contract_wasm::{ContractWasm, ContractWasmHash}; #[doc(inline)] pub use contracts::{ diff --git a/types/src/transfer.rs b/types/src/transfer.rs index c751736dcb..23f51df809 100644 --- a/types/src/transfer.rs +++ b/types/src/transfer.rs @@ -53,12 +53,6 @@ impl DeployHash { } } -impl AsRef<[u8]> for DeployHash { - fn as_ref(&self) -> &[u8] { - self.0.as_ref() - } -} - #[cfg(feature = "json-schema")] impl JsonSchema for DeployHash { fn schema_name() -> String { diff --git a/utils/highway-state-grapher/Cargo.toml b/utils/highway-state-grapher/Cargo.toml deleted file mode 100644 index b396ae7ccb..0000000000 --- a/utils/highway-state-grapher/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "highway-state-grapher" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bincode = "1" -clap = { version = "4", features = ["derive"] } -casper-hashing = { path = "../../hashing" } -casper-node = { path = "../../node" } -casper-types = { path = "../../types" } -flate2 = "1" -freetype-sys = "0.13" -glium = "0.26" -glium_text_rusttype = "0.3" -libc = "0.2" -nalgebra = "0.32" -serde = "1" diff --git a/utils/highway-state-grapher/DejaVuSans.ttf b/utils/highway-state-grapher/DejaVuSans.ttf deleted file mode 100644 index e5f7eecce4..0000000000 Binary files a/utils/highway-state-grapher/DejaVuSans.ttf and /dev/null differ diff --git a/utils/highway-state-grapher/src/main.rs b/utils/highway-state-grapher/src/main.rs deleted file mode 100644 index 617f8f2e2d..0000000000 --- a/utils/highway-state-grapher/src/main.rs +++ /dev/null @@ -1,614 +0,0 @@ -mod renderer; - -use std::{ - collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque}, - fmt::{self, Debug}, - fs::File, - io::Read, - ops::RangeBounds, -}; - -use casper_hashing::Digest; -use casper_node::consensus::{ - highway_core::{ - finality_detector::{assigned_weight_and_latest_unit, find_max_quora}, - Panorama, State, - }, - utils::{ValidatorIndex, ValidatorMap}, - ClContext, -}; -use casper_types::{EraId, PublicKey, Timestamp, U512}; - -use clap::Parser; -use flate2::read::GzDecoder; -use glium::{ - glutin::{ - event::{ElementState, Event, MouseButton, MouseScrollDelta, VirtualKeyCode, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - window::WindowBuilder, - ContextBuilder, - }, - Display, -}; -use serde::{Deserialize, Serialize}; - -use crate::renderer::Renderer; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -struct Args { - filename: String, -} - -/// Debug dump of era used for serialization. -#[derive(Debug, Serialize, Deserialize)] -pub(crate) struct EraDump { - /// The era that is being dumped. - pub id: EraId, - - /// The scheduled starting time of this era. - pub start_time: Timestamp, - /// The height of this era's first block. - pub start_height: u64, - - // omitted: pending blocks - /// Validators that have been faulty in any of the recent BONDED_ERAS switch blocks. This - /// includes `new_faulty`. - pub faulty: HashSet, - /// Validators that are excluded from proposing new blocks. - pub cannot_propose: HashSet, - /// Accusations collected in this era so far. - pub accusations: HashSet, - /// The validator weights. - pub validators: BTreeMap, - - /// The state of the highway instance associated with the era. - pub highway_state: State, -} - -/// Helper struct for sorting the units with regards to the implicit partial ordering in the DAG. -struct Units { - set: HashSet, - order: Vec, -} - -impl Units { - /// Collects all the unit hashes and orders them roughly from the newest to the oldest. - fn do_collect_ancestor_units( - &mut self, - state: &State, - panorama: &Panorama, - ) { - let hashes_to_add: Vec<_> = panorama.iter_correct_hashes().collect(); - let mut hashes_to_proceed_with = vec![]; - for hash in hashes_to_add { - if self.set.insert(*hash) { - self.order.push(*hash); - hashes_to_proceed_with.push(*hash); - } - } - for hash in hashes_to_proceed_with { - let unit = state.unit(&hash); - self.do_collect_ancestor_units(state, &unit.panorama); - } - } - - /// Reorders the units in self.order so that every unit comes after all its dependencies. - fn reorder(&mut self, state: &State) { - let mut new_order_set = HashSet::new(); - let mut new_order = vec![]; - let mut queue: VecDeque<_> = std::mem::take(&mut self.order).into_iter().rev().collect(); - loop { - if queue.is_empty() { - break; - } - let unit = queue.pop_front().unwrap(); - if state - .unit(&unit) - .panorama - .iter_correct_hashes() - .all(|cited| new_order_set.contains(cited)) - { - new_order_set.insert(unit); - new_order.push(unit) - } else { - queue.push_back(unit); - } - } - self.order = new_order; - } - - /// Collects all the unit hashes and orders them so that every unit comes after all its - /// dependencies. - fn collect_ancestor_units(&mut self, state: &State) { - self.do_collect_ancestor_units(state, state.panorama()); - self.reorder(state); - } -} - -/// A more readable unit ID: the validator index together with the height in that validator's -/// swimlane -#[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub struct UnitId(ValidatorIndex, usize); - -impl Debug for UnitId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "V{}_{}", self.0 .0, self.1) - } -} - -/// A more readable block id. The first field is the block height, the second is the number of the -/// block among all the blocks at that height (if there are no orphan blocks, all the block IDs will -/// have 0s in the second field). -#[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub struct BlockId(u64, u8); - -impl Debug for BlockId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "B{}", self.0)?; - for _ in 0..self.1 { - write!(f, "'")?; - } - Ok(()) - } -} - -/// A helper struct for coloring units based on the validator's max quorum. -/// `max_rank` is the number of distinct values of max quorum. `rank` is the index relative to the -/// maximum value (ie. the largest max quorum has rank 0, the second largest has rank 1 etc.) -#[derive(Clone, Copy)] -pub struct Quorum { - pub rank: usize, - pub max_rank: usize, - pub weight_percent: f32, -} - -impl Debug for Quorum { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:3.1}", self.weight_percent) - } -} - -/// A representation of the protocol state unit for the purpose of drawing it on the screen. -/// `graph_height` is the maximum of graph heights of the cited units, plus 1 - drawing based on -/// graph height guarantees that every unit will appear higher than all its dependencies. -#[derive(Clone)] -pub struct GraphUnit { - pub id: UnitId, - pub creator: ValidatorIndex, - pub vote: BlockId, - pub is_proposal: bool, - pub cited_units: Vec, - pub height: usize, - pub graph_height: usize, - pub timestamp: u64, - pub round_num: u64, - pub round_id: Timestamp, - pub round_exp: u8, - pub max_quorum: Option, -} - -impl Debug for GraphUnit { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("GraphUnit") - .field("id", &self.id) - .field("creator", &format!("V{}", self.creator.0)) - .field("height", &self.height) - .field("graph_height", &self.graph_height) - .field("vote", &self.vote) - .field("is_proposal", &self.is_proposal) - .field("timestamp", &self.timestamp) - .field("round_num", &self.round_num) - .field("round_id", &self.round_id) - .field("round_exp", &self.round_exp) - .field("max_quorum", &self.max_quorum) - .field("cited_units", &self.cited_units) - .finish() - } -} - -/// A struct helping in assigning readable IDs to blocks. -#[derive(Clone, Debug)] -struct BlockMapper { - hash_to_id: HashMap, - id_to_hash: HashMap, - last_id_by_height: HashMap, -} - -impl BlockMapper { - fn new() -> Self { - Self { - hash_to_id: HashMap::new(), - id_to_hash: HashMap::new(), - last_id_by_height: HashMap::new(), - } - } - - /// Inserts the new ID, updating the mappings as necessary. - fn insert(&mut self, hash: Digest, id: BlockId) { - self.hash_to_id.insert(hash, id); - self.id_to_hash.insert(id, hash); - let entry = self.last_id_by_height.entry(id.0).or_insert(id.1); - *entry = (*entry).max(id.1); - } - - /// Returns the block ID for the next block at the given height. - /// Usually, there will only be one block at a given height, but in some cases forks are - /// possible - in those cases, blocks at the same height will get sequential IDs. - fn next_id_for_height(&self, height: u64) -> BlockId { - BlockId( - height, - self.last_id_by_height - .get(&height) - .map(|idx| *idx + 1) - .unwrap_or(0), - ) - } - - /// Gets the readable block ID corresponding to the given hash. - fn get(&self, hash: &Digest) -> Option { - self.hash_to_id.get(hash).copied() - } - - /// Gets the block hash corresponding to the given ID. - #[allow(unused)] // Will be useful if we add features related to the blocks - fn get_by_id(&self, id: &BlockId) -> Option { - self.id_to_hash.get(id).copied() - } -} - -/// All the data needed for drawing the unit DAG. -#[derive(Clone, Debug)] -pub struct Graph { - units: ValidatorMap>, - reverse_edges: HashMap>, - #[allow(unused)] // Will be useful if we add features related to the blocks - blocks: BlockMapper, - weight_percentages: ValidatorMap, -} - -impl Graph { - /// Creates a `Graph` based on the `state`. - fn new(state: &State, start_time: Timestamp) -> Self { - let mut units: BTreeMap> = state - .weights() - .iter() - .enumerate() - .map(|(idx, _)| (ValidatorIndex::from(idx as u32), vec![])) - .collect(); - let mut reverse_edges: HashMap> = HashMap::new(); - let mut unit_ids_by_hash: HashMap = HashMap::new(); - let mut blocks = BlockMapper::new(); - - let mut units_set = Units { - set: HashSet::new(), - order: vec![], - }; - - units_set.collect_ancestor_units(state); - - eprintln!("num units: {}", units_set.order.len()); - - let max_round_exp = (state.params().max_round_length().millis() - / state.params().min_round_length().millis()) - .trailing_zeros(); - let max_round_length = state.params().min_round_length().millis() << max_round_exp; - let rounded_era_start = - Timestamp::from((start_time.millis() / max_round_length) * max_round_length); - - let mut highest_block: Option<(u64, Digest)> = None; - - for unit_hash in &units_set.order { - let unit = state.unit(unit_hash); - let block = state.block(&unit.block); - if highest_block.map_or(true, |(height, _)| height < block.height) { - highest_block = Some((block.height, unit.block)); - } - let block_id = if let Some(b_id) = blocks.get(&unit.block) { - b_id - } else { - let b_id = blocks.next_id_for_height(block.height); - blocks.insert(unit.block, b_id); - b_id - }; - let is_proposal = unit - .panorama - .iter_correct_hashes() - .all(|hash| state.unit(hash).block != unit.block); - let cited_units: Vec = unit - .panorama - .iter_correct_hashes() - .map(|hash| *unit_ids_by_hash.get(hash).unwrap()) - .collect(); - let graph_height = cited_units - .iter() - .map(|unit_id| &units.get(&unit_id.0).unwrap()[unit_id.1]) - .map(|g_unit| g_unit.graph_height) - .max() - .map(|max_height| max_height + 1) - .unwrap_or(0); - let unit_id = UnitId(unit.creator, units.get(&unit.creator).unwrap().len()); - - for cited_unit_id in &cited_units { - reverse_edges - .entry(*cited_unit_id) - .or_default() - .push(unit_id); - } - - let time_since_era_start = unit.timestamp.saturating_diff(rounded_era_start).millis(); - let round_num = time_since_era_start / state.params().min_round_length().millis(); - - let graph_unit = GraphUnit { - id: unit_id, - creator: unit.creator, - vote: block_id, - is_proposal, - cited_units, - height: unit.seq_number as usize, - graph_height, - timestamp: time_since_era_start, - round_num, - round_id: unit.round_id(), - round_exp: (unit.round_len().millis() / state.params().min_round_length().millis()) - .trailing_zeros() as u8, - max_quorum: None, - }; - unit_ids_by_hash.insert(*unit_hash, unit_id); - units.get_mut(&unit.creator).unwrap().push(graph_unit); - } - - // fill in max quora - if let Some((_hb_height, hb_hash)) = highest_block { - let hb_unit = state.unit(&hb_hash); - for bhash in state.ancestor_hashes(&hb_hash) { - let proposal_unit = state.unit(bhash); - let r_id = proposal_unit.round_id(); - - let (assigned_weight, latest) = - assigned_weight_and_latest_unit(state, &hb_unit.panorama, r_id); - - let max_quora = find_max_quora(state, bhash, &latest); - // deduplicate and sort max quora - let max_quora_set: BTreeSet<_> = max_quora.iter().copied().collect(); - let max_quora_rank_map: BTreeMap<_, _> = max_quora_set - .into_iter() - .rev() - .enumerate() - .map(|(rank, quorum)| (quorum, rank)) - .collect(); - - for unit in latest.iter().flatten() { - let gunit_id = unit_ids_by_hash.get(*unit).unwrap(); - let gunit = &mut units.get_mut(&gunit_id.0).unwrap()[gunit_id.1]; - let quorum_w = max_quora[gunit.creator]; - let rank = max_quora_rank_map[&quorum_w]; - let weight_percent = quorum_w.0 as f32 / assigned_weight.0 as f32 * 100.0; - gunit.max_quorum = Some(Quorum { - rank, - max_rank: max_quora_rank_map.len(), - weight_percent, - }); - } - } - } - - let weight_percentages: ValidatorMap = state - .weights() - .iter() - .map(|weight| weight.0 as f32 / state.total_weight().0 as f32 * 100.0) - .collect(); - - Self { - units: units.into_values().collect(), - reverse_edges, - blocks, - weight_percentages, - } - } - - /// Returns the unit under the given `unit_id`. - pub fn get(&self, unit_id: &UnitId) -> Option<&GraphUnit> { - self.units - .get(unit_id.0) - .and_then(|swimlane| swimlane.get(unit_id.1)) - } - - /// Returns the validator weights. - pub fn validator_weights(&self) -> &ValidatorMap { - &self.weight_percentages - } - - /// Iterates over all the units created by validators within `range_vid` and with graph heights - /// within `range_graph_height`. - pub fn iter_range( - &self, - range_vid: R1, - range_graph_height: R2, - ) -> impl Iterator - where - R1: RangeBounds + Clone, - R2: RangeBounds + Clone, - { - let range_vid_clone = range_vid.clone(); - self.units - .iter() - .enumerate() - .skip_while(move |(vid, _)| !range_vid.contains(vid)) - .take_while(move |(vid, _)| range_vid_clone.contains(vid)) - .flat_map(move |(_, swimlane)| { - let range_graph_height_clone1 = range_graph_height.clone(); - let range_graph_height_clone2 = range_graph_height.clone(); - swimlane - .iter() - .skip_while(move |unit| !range_graph_height_clone1.contains(&unit.graph_height)) - .take_while(move |unit| range_graph_height_clone2.contains(&unit.graph_height)) - }) - } -} - -fn main() { - let args = Args::parse(); - - let mut data = vec![]; - let mut file = File::open(&args.filename).unwrap(); - - if args.filename.ends_with(".gz") { - let mut gz = GzDecoder::new(file); - gz.read_to_end(&mut data).unwrap(); - } else { - file.read_to_end(&mut data).unwrap(); - } - - let dump: EraDump = bincode::deserialize(&data).unwrap(); - - eprintln!("{}", dump.id); - - let graph = Graph::new(&dump.highway_state, dump.start_time); - - for (index, (pub_key, _)) in dump.validators.iter().enumerate() { - eprintln!("{}: {}", index, pub_key); - } - - start_rendering(graph); -} - -/// Struct keeping the current state of some keys (the events only report the current state, so we -/// need to store the old state to know when it changes). -#[derive(Clone, Copy)] -struct KeyboardState { - /// State of the 'E' key. - e_state: bool, -} - -impl KeyboardState { - fn e_pressed(&mut self) -> bool { - let was_pressed = self.e_state; - self.e_state = true; - !was_pressed - } - - fn e_released(&mut self) { - self.e_state = false; - } -} - -/// Enum keeping the state of mouse input. -#[derive(Clone, Copy)] -enum MouseState { - /// Mouse is freely moving. - Free { position: (f64, f64) }, - /// The user is dragging something. - Dragging { last_position: (f64, f64) }, -} - -impl MouseState { - /// Handles a mouse move event. - /// Returns `Some(delta_x, delta_y)` if dragging is in progress. - fn handle_move(&mut self, new_position: (f64, f64)) -> Option<(f32, f32)> { - match self { - Self::Free { position } => { - *position = new_position; - None - } - Self::Dragging { last_position } => { - let delta_x = (new_position.0 - last_position.0) as f32; - let delta_y = (new_position.1 - last_position.1) as f32; - *last_position = new_position; - Some((delta_x, delta_y)) - } - } - } - - /// Switches between `Free` and `Dragging` based on the button presses. - fn handle_button(&mut self, button_down: bool) { - match (*self, button_down) { - (Self::Free { position }, true) => { - *self = Self::Dragging { - last_position: position, - }; - } - (Self::Dragging { last_position }, false) => { - *self = Self::Free { - position: last_position, - }; - } - _ => (), - } - } - - /// Returns the current position of the cursor. - fn cursor(&self) -> (f32, f32) { - match self { - Self::Free { position } => (position.0 as f32, position.1 as f32), - Self::Dragging { last_position } => (last_position.0 as f32, last_position.1 as f32), - } - } -} - -/// The main loop of the program. -fn start_rendering(graph: Graph) { - let event_loop = EventLoop::new(); - - let wb = WindowBuilder::new() - .with_title("Consensus Graph Visualization") - .with_maximized(true) - .with_resizable(true); - let cb = ContextBuilder::new(); - let display = Display::new(wb, cb, &event_loop).unwrap(); - - let mut renderer = Renderer::new(&display); - let mut mouse_state = MouseState::Free { - position: (0.0, 0.0), - }; - let mut keyboard_state = KeyboardState { e_state: false }; - - event_loop.run(move |ev, _, control_flow| { - match ev { - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => { - *control_flow = ControlFlow::Exit; - return; - } - WindowEvent::MouseWheel { delta, .. } => match delta { - MouseScrollDelta::LineDelta(_, vertical) => { - renderer.mouse_scroll(vertical); - } - MouseScrollDelta::PixelDelta(pixels) => { - renderer.mouse_scroll(pixels.y as f32 / 30.0); - } - }, - WindowEvent::KeyboardInput { input, .. } => { - match (input.virtual_keycode, input.state) { - (Some(VirtualKeyCode::E), ElementState::Pressed) => { - if keyboard_state.e_pressed() { - renderer.toggle_edges(); - } - } - (Some(VirtualKeyCode::E), ElementState::Released) => { - keyboard_state.e_released(); - } - _ => (), - } - } - WindowEvent::MouseInput { state, button, .. } => { - if let (state, MouseButton::Left) = (state, button) { - mouse_state.handle_button(matches!(state, ElementState::Pressed)); - } - } - WindowEvent::CursorMoved { position, .. } => { - if let Some(delta) = mouse_state.handle_move((position.x, position.y)) { - renderer.pan(delta.0, delta.1); - } - } - _ => (), - }, - Event::MainEventsCleared => { - let (cursor_x, cursor_y) = mouse_state.cursor(); - renderer.draw(&display, &graph, cursor_x, cursor_y); - } - _ => (), - } - *control_flow = ControlFlow::Poll; - }); -} diff --git a/utils/highway-state-grapher/src/renderer.rs b/utils/highway-state-grapher/src/renderer.rs deleted file mode 100644 index efbc712e0d..0000000000 --- a/utils/highway-state-grapher/src/renderer.rs +++ /dev/null @@ -1,450 +0,0 @@ -mod matrix; - -use std::{collections::HashSet, f32::consts::PI}; - -use casper_node::consensus::utils::ValidatorMap; -use glium::{ - implement_vertex, index, uniform, Display, DrawParameters, Frame, Program, Surface, - VertexBuffer, -}; -use glium_text_rusttype::{self, FontTexture, TextDisplay, TextSystem}; -use nalgebra::Vector2; - -use crate::{renderer::matrix::Matrix, Graph, GraphUnit, UnitId}; - -const VERTEX_SHADER_SRC: &str = r#" - #version 140 - - in vec2 position; - - uniform mat4 matrix; - uniform vec3 color; - out vec3 in_color; - - void main() { - gl_Position = matrix * vec4(position, 0.0, 1.0); - in_color = color; - } -"#; - -const FRAGMENT_SHADER_SRC: &str = r#" - #version 140 - - in vec3 in_color; - out vec4 color; - - void main() { - color = vec4(in_color, 1.0); - } -"#; - -const FONT_FILE: &[u8] = include_bytes!("../DejaVuSans.ttf"); - -#[derive(Debug, Clone, Copy)] -struct Vertex { - position: [f32; 2], -} - -implement_vertex!(Vertex, position); - -/// Rendering-specific data. -pub struct Renderer { - /// The coordinates at the center of the screen. - center: Vector2, - /// The width of the window, in pixels. - window_width: f32, - /// The current width of the viewport. - width: f32, - /// The shading program. - program: Program, - /// Stuff for rendering text. - text_system: TextSystem, - font: FontTexture, - - /// Pre-generated vertices for a unit. - unit_vertex_buffer: VertexBuffer, - interior_indices: index::NoIndices, - frame_indices: index::IndexBuffer, - - /// `True` if we're drawing edges. - edges_enabled: bool, -} - -const UNIT_WIDTH: f32 = 0.5; -const UNIT_HEIGHT: f32 = 0.4; -const CORNER_RADIUS: f32 = 0.05; -const LINE_WIDTH: f32 = 0.015; - -impl Renderer { - pub fn new(display: &Display) -> Self { - let text_system = TextSystem::new(display); - let font = - FontTexture::new(display, FONT_FILE, 32, FontTexture::ascii_character_list()).unwrap(); - - let (unit_vertex_buffer, interior_indices, frame_indices) = - Self::unit_vertex_buffer(display); - - Renderer { - center: Vector2::new(3.5, 2.5), - window_width: 3000.0, // will get updated on first frame draw - width: 8.0, - program: Program::from_source(display, VERTEX_SHADER_SRC, FRAGMENT_SHADER_SRC, None) - .unwrap(), - text_system, - font, - - unit_vertex_buffer, - interior_indices, - frame_indices, - edges_enabled: true, - } - } - - /// Creates vertices for a rounded rectangle. - fn unit_vertex_buffer( - display: &Display, - ) -> ( - VertexBuffer, - index::NoIndices, - index::IndexBuffer, - ) { - let mut shape = vec![]; - let n_vertices_corner = 8; - - let corner_radius = CORNER_RADIUS; - let width = UNIT_WIDTH; - let height = UNIT_HEIGHT; - - let corners = [ - ( - width / 2.0 - corner_radius, - height / 2.0 - corner_radius, - 0.0, - ), - ( - -width / 2.0 + corner_radius, - height / 2.0 - corner_radius, - PI * 0.5, - ), - ( - -width / 2.0 + corner_radius, - -height / 2.0 + corner_radius, - PI, - ), - ( - width / 2.0 - corner_radius, - -height / 2.0 + corner_radius, - PI * 1.5, - ), - ]; - - shape.push(Vertex { - position: [0.0, 0.0], - }); - for (x, y, phase) in corners { - for i in 0..n_vertices_corner { - let ang = 0.5 * PI * (i as f32) / n_vertices_corner as f32 + phase; - shape.push(Vertex { - position: [corner_radius * ang.cos() + x, corner_radius * ang.sin() + y], - }); - } - } - shape.push(shape[1]); - - ( - VertexBuffer::new(display, &shape).unwrap(), - index::NoIndices(index::PrimitiveType::TriangleFan), - index::IndexBuffer::new( - display, - index::PrimitiveType::LineLoop, - &(1..(shape.len() - 1) as u32).collect::>(), - ) - .unwrap(), - ) - } - - /// Draws the graph. - pub fn draw(&mut self, display: &Display, graph: &Graph, cursor_x: f32, cursor_y: f32) { - let mut target = display.draw(); - - let (size_x, size_y) = target.get_dimensions(); - self.window_width = size_x as f32; - - let (cursor_x, cursor_y) = self.convert_cursor(cursor_x, cursor_y, size_x, size_y); - - let aspect = (size_y as f32) / (size_x as f32); - - let height = self.width * aspect; - - let max_graph_height = (self.center.y + height / 2.0 + 1.0) as usize; - let min_graph_height = (self.center.y - height / 2.0 - 1.0).max(0.0) as usize; - - let max_validator_index = (self.center.x + self.width / 2.0 + 1.0) as usize; - let min_validator_index = (self.center.x - self.width / 2.0 - 1.0).max(0.0) as usize; - - target.clear_color(0.0, 0.0, 0.2, 1.0); - - let matrix = Matrix::translation(-self.center.x, -self.center.y) - * Matrix::scale(2.0 / self.width, 2.0 / height); - - let mut edges_to_draw = HashSet::new(); - let mut highlighted_edges_to_draw = HashSet::new(); - - for unit in graph.iter_range( - min_validator_index..=max_validator_index, - min_graph_height..=max_graph_height, - ) { - let set_to_insert = if Self::unit_contains_cursor(unit, cursor_x, cursor_y) { - &mut highlighted_edges_to_draw - } else { - &mut edges_to_draw - }; - for cited_unit in &unit.cited_units { - set_to_insert.insert((unit.id, *cited_unit)); - } - for dependent_unit in graph.reverse_edges.get(&unit.id).into_iter().flatten() { - set_to_insert.insert((*dependent_unit, unit.id)); - } - } - - // draw edges first, so that the units are drawn over them - if self.edges_enabled { - self.draw_edges(display, &mut target, &matrix, graph, edges_to_draw, false); - } - self.draw_edges( - display, - &mut target, - &matrix, - graph, - highlighted_edges_to_draw, - true, - ); - - for unit in graph.iter_range( - min_validator_index..=max_validator_index, - min_graph_height..=max_graph_height, - ) { - self.draw_unit(&mut target, unit, graph.validator_weights(), &matrix); - } - - target.finish().unwrap(); - } - - /// Converts the cursor coordinates in pixels into the scene coordinates. - fn convert_cursor(&self, cursor_x: f32, cursor_y: f32, size_x: u32, size_y: u32) -> (f32, f32) { - let size_x = size_x as f32; - let size_y = size_y as f32; - let delta_x = (cursor_x / size_x - 0.5) * self.width; - let delta_y = (0.5 - cursor_y / size_y) * self.width * size_y / size_x; - (self.center.x + delta_x, self.center.y + delta_y) - } - - /// Checks whether the cursor hovers over a unit. - fn unit_contains_cursor(unit: &GraphUnit, cursor_x: f32, cursor_y: f32) -> bool { - let (unit_x, unit_y) = Self::unit_pos(unit); - (unit_x - cursor_x).abs() < UNIT_WIDTH / 2.0 - && (unit_y - cursor_y).abs() < UNIT_HEIGHT / 2.0 - } - - /// Draws a unit. - fn draw_unit( - &mut self, - target: &mut Frame, - unit: &GraphUnit, - weights: &ValidatorMap, - view: &Matrix, - ) { - let (x, y) = Self::unit_pos(unit); - - let matrix2 = Matrix::translation(x, y) * *view; - - let color = match (unit.is_proposal, unit.max_quorum.as_ref()) { - (false, Some(quorum)) => { - if quorum.max_rank <= 1 { - Self::quorum_color_spectrum(0.0) - } else { - let frac = quorum.rank as f32 / (quorum.max_rank - 1) as f32; - Self::quorum_color_spectrum(frac) - } - } - (true, _) => [0.0_f32, 0.5, 0.5], - _ => [0.0_f32, 0.0, 0.2], - }; - - let uniforms = uniform! { - matrix: matrix2.inner(), - color: color, - }; - - target - .draw( - &self.unit_vertex_buffer, - self.interior_indices, - &self.program, - &uniforms, - &Default::default(), - ) - .unwrap(); - - let uniforms = uniform! { - matrix: matrix2.inner(), - color: [ 1.0_f32, 1.0, 0.0 ], - }; - - let draw_params = DrawParameters { - line_width: Some(LINE_WIDTH), - ..Default::default() - }; - - target - .draw( - &self.unit_vertex_buffer, - &self.frame_indices, - &self.program, - &uniforms, - &draw_params, - ) - .unwrap(); - - if self.width < 10.0 { - let text1 = format!("{:?}", unit.id); - let text2 = format!( - "Creator weight: {:3.1}%", - weights.get(unit.creator).unwrap() - ); - let text3 = format!("Vote: {:?}", unit.vote); - let text4 = format!("round_exp: {}", unit.round_exp); - let text5 = format!("round_id: {}", unit.round_id); - let text6 = format!("timestamp: {} (round {})", unit.timestamp, unit.round_num); - let text7 = if let Some(quorum) = unit.max_quorum.as_ref() { - format!("max quorum: {:3.1}%", quorum.weight_percent) - } else { - "".to_string() - }; - self.draw_text(target, -0.4, 0.7, &text1, 1.3, &matrix2); - self.draw_text(target, -0.8, 0.46, &text2, 0.8, &matrix2); - self.draw_text(target, -0.8, 0.22, &text3, 0.8, &matrix2); - self.draw_text(target, -0.8, -0.02, &text4, 0.8, &matrix2); - self.draw_text(target, -0.8, -0.26, &text5, 0.8, &matrix2); - self.draw_text(target, -0.8, -0.5, &text6, 0.8, &matrix2); - self.draw_text(target, -0.8, -0.74, &text7, 0.8, &matrix2); - } else { - let text = format!("{:?}", unit.id); - self.draw_text(target, -0.4, -0.15, &text, 3.0, &matrix2); - } - } - - /// Renders a string. - fn draw_text( - &self, - target: &mut Frame, - x: f32, - y: f32, - text: &str, - scale: f32, - matrix: &Matrix, - ) { - let basic_scale = UNIT_HEIGHT / 12.0; - let scale = basic_scale * scale; - let matrix = Matrix::scale(scale, scale) - * Matrix::translation(x * UNIT_WIDTH / 2.0, y * UNIT_HEIGHT / 2.0) - * *matrix; - let text = TextDisplay::new(&self.text_system, &self.font, text); - - glium_text_rusttype::draw( - &text, - &self.text_system, - target, - matrix.inner(), - (1.0, 1.0, 1.0, 1.0), - ) - .unwrap(); - } - - /// Draws the edges between units. - fn draw_edges( - &mut self, - display: &Display, - target: &mut Frame, - view: &Matrix, - graph: &Graph, - edges: HashSet<(UnitId, UnitId)>, - highlight: bool, - ) { - let mut vertices = vec![]; - - for (unit1, unit2) in edges { - let pos1 = Self::unit_pos(graph.get(&unit1).unwrap()); - let pos2 = Self::unit_pos(graph.get(&unit2).unwrap()); - - vertices.push(Vertex { - position: [pos1.0, pos1.1], - }); - vertices.push(Vertex { - position: [pos2.0, pos2.1], - }); - } - - let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); - let indices = index::NoIndices(index::PrimitiveType::LinesList); - - let color = if highlight { - [1.0_f32, 1.0, 1.0] - } else { - [1.0_f32, 1.0, 0.0] - }; - - let uniforms = uniform! { - matrix: view.inner(), - color: color, - }; - - let draw_parameters = DrawParameters { - line_width: Some(if highlight { - LINE_WIDTH * 2.0 - } else { - LINE_WIDTH - }), - ..Default::default() - }; - - target - .draw( - &vertex_buffer, - indices, - &self.program, - &uniforms, - &draw_parameters, - ) - .unwrap(); - } - - /// Returns the position of the units in scene coordinates. - fn unit_pos(unit: &GraphUnit) -> (f32, f32) { - let x = unit.creator.0 as f32; - let y = unit.graph_height as f32; - (x, y) - } - - /// Handles a mouse scroll event (zooms in or out). - pub fn mouse_scroll(&mut self, lines: f32) { - self.width *= 2.0_f32.powf(lines / 3.0); - } - - /// Handles a dragging event (pans the screen). - pub fn pan(&mut self, delta_x: f32, delta_y: f32) { - let scale = self.width / self.window_width; - self.center += Vector2::new(-delta_x * scale, delta_y * scale); - } - - pub fn toggle_edges(&mut self) { - self.edges_enabled = !self.edges_enabled; - } - - /// Returns a color for the max quorum based on its rank. - fn quorum_color_spectrum(frac: f32) -> [f32; 3] { - let r = if frac < 0.5 { frac } else { 1.0 }; - let g = if frac < 0.5 { 1.0 } else { 1.0 - frac }; - [r * 0.5, g * 0.5, 0.0] - } -} diff --git a/utils/highway-state-grapher/src/renderer/matrix.rs b/utils/highway-state-grapher/src/renderer/matrix.rs deleted file mode 100644 index ed2575869e..0000000000 --- a/utils/highway-state-grapher/src/renderer/matrix.rs +++ /dev/null @@ -1,84 +0,0 @@ -use std::ops; - -#[derive(Clone, Copy)] -pub struct Matrix { - coords: [[f32; 4]; 4], -} - -impl Matrix { - pub fn identity() -> Matrix { - Matrix { - coords: [ - [1.0, 0.0, 0.0, 0.0], - [0.0, 1.0, 0.0, 0.0], - [0.0, 0.0, 1.0, 0.0], - [0.0, 0.0, 0.0, 1.0], - ], - } - } - - pub fn inner(self) -> [[f32; 4]; 4] { - self.coords - } - - pub fn translation(x: f32, y: f32) -> Matrix { - let mut result = Matrix::identity(); - result.coords[3][0] = x; - result.coords[3][1] = y; - result - } - - pub fn scale(x: f32, y: f32) -> Matrix { - Matrix { - coords: [ - [x, 0.0, 0.0, 0.0], - [0.0, y, 0.0, 0.0], - [0.0, 0.0, 1.0, 0.0], - [0.0, 0.0, 0.0, 1.0], - ], - } - } -} - -impl ops::Add for Matrix { - type Output = Matrix; - - fn add(mut self, other: Matrix) -> Matrix { - for i in 0..4 { - for j in 0..4 { - self.coords[i][j] += other.coords[i][j]; - } - } - self - } -} - -impl ops::Sub for Matrix { - type Output = Matrix; - - fn sub(mut self, other: Matrix) -> Matrix { - for i in 0..4 { - for j in 0..4 { - self.coords[i][j] -= other.coords[i][j]; - } - } - self - } -} - -impl ops::Mul for Matrix { - type Output = Matrix; - - #[allow(clippy::needless_range_loop)] - fn mul(self, other: Matrix) -> Matrix { - let mut new_coords = [[0.0; 4]; 4]; - for i in 0..4 { - for j in 0..4 { - for k in 0..4 { - new_coords[i][j] += self.coords[i][k] * other.coords[k][j]; - } - } - } - Matrix { coords: new_coords } - } -} diff --git a/utils/nctl/README.md b/utils/nctl/README.md index 066d31bf4f..9e166ce30c 100644 --- a/utils/nctl/README.md +++ b/utils/nctl/README.md @@ -1,7 +1,7 @@ nctl =============== -CLI application to setup & control multiple local Casper networks. It is NOT intended for use in production networks. It is for TESTING ONLY +CLI application to setup & control multiple local Casper networks. What is nctl ? --------------------------------------