diff --git a/.ci/bench_bft_sync.sh b/.ci/bench_bft_sync.sh index 9cce21b8ef..148299e5fc 100755 --- a/.ci/bench_bft_sync.sh +++ b/.ci/bench_bft_sync.sh @@ -47,7 +47,7 @@ trap child_exit_handler CHLD # Define a trap handler that prints a message when an error occurs trap 'echo "⛔️ Error in $BASH_SOURCE at line $LINENO: \"$BASH_COMMAND\" failed (exit $?)"' ERR -# Shared flags betwen all nodes +# Shared flags between all nodes common_flags=( --nobanner --noupdater --nodisplay \ "--network=$network_id" @@ -96,10 +96,26 @@ SECONDS=0 # exit 1 # fi #done - + connect_time=$SECONDS echo "ℹ️ Nodes are fully connected (took $connect_time secs). Starting block sync measurement." +# Ensure the first node actually has the ledger snapshot. +# This should succeed instantly in most cases +SECONDS=0 +has_blocks=false +while (( SECONDS < 30 )); do + if check_heights 0 1 $min_height "$network_name" 0 false; then + has_blocks=true + break + fi +done + +if ! $has_blocks; then + echo "Node #0 has not reached the expected height. Maybe the ledger snapshot is corrupted or outdated?" + exit 1 +fi + # Check heights periodically with a timeout SECONDS=0 while (( SECONDS < max_wait )); do diff --git a/.ci/bench_p2p_sync.sh b/.ci/bench_p2p_sync.sh index dc15b5e52a..ca5ea5b186 100755 --- a/.ci/bench_p2p_sync.sh +++ b/.ci/bench_p2p_sync.sh @@ -145,7 +145,7 @@ echo "ℹ️ Nodes are fully connected (took $connect_time secs). Starting block SECONDS=0 has_blocks=false while (( SECONDS < 30 )); do - if check_heights 0 1 $min_height "$network_name" "0"; then + if check_heights 0 1 $min_height "$network_name" 0 false; then has_blocks=true break fi diff --git a/.ci/devnet_ci.sh b/.ci/devnet_ci.sh index fde88c4d9a..6c2f83c0c8 100755 --- a/.ci/devnet_ci.sh +++ b/.ci/devnet_ci.sh @@ -47,7 +47,7 @@ trap child_exit_handler CHLD # Define a trap handler that prints a message when an error occurs trap 'echo "⛔️ Error in $BASH_SOURCE at line $LINENO: \"$BASH_COMMAND\" failed (exit $?)"' ERR -# Flags used by all ndoes +# Flags used by all nodes common_flags=( --nodisplay --nobanner --noupdater "--network=$network_id" --verbosity=1 --allow-external-peers "--dev-num-validators=$total_validators" diff --git a/.ci/utils.sh b/.ci/utils.sh index fa323af02a..0fc7c85e81 100644 --- a/.ci/utils.sh +++ b/.ci/utils.sh @@ -44,6 +44,10 @@ function check_heights() { local min_height=$3 local network_name=$4 local elapsed=$5 + local print_success=$6 + + # Show the success message by default + : "${print_success:=true}" local all_reached=true local highest_height=0 @@ -63,7 +67,9 @@ function check_heights() { done if $all_reached; then - echo "✅ SUCCESS: All nodes reached minimum height of $min_height" + if $print_success; then + echo "✅ SUCCESS: All nodes reached minimum height of $min_height" + fi return 0 else if (( elapsed > 0 && ((elapsed % 60) == 0) )); then diff --git a/.circleci/config.yml b/.circleci/config.yml index f728ef6aa9..3d4183785e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -297,7 +297,7 @@ jobs: node-router: executor: rust-docker - resource_class: << pipeline.parameters.large >> + resource_class: << pipeline.parameters.xlarge >> steps: - run_serial: workspace_member: node/router diff --git a/Cargo.lock b/Cargo.lock index dc7c03c567..5bd7129d0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,6 +349,12 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.21.7" @@ -599,9 +605,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.48" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" dependencies = [ "clap_builder", "clap_derive", @@ -609,9 +615,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.48" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" dependencies = [ "anstream", "anstyle", @@ -621,9 +627,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.47" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", @@ -633,9 +639,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "colorchoice" @@ -847,6 +853,18 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[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 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -868,7 +886,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2 0.6.0", + "socket2 0.6.1", "windows-sys 0.59.0", ] @@ -1078,6 +1096,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -1140,6 +1159,19 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", +] + [[package]] name = "ed25519" version = "2.2.3" @@ -1171,6 +1203,24 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[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", + "ff", + "generic-array", + "group", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "encode_unicode" version = "1.0.0" @@ -1260,6 +1310,16 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "fiat-crypto" version = "0.2.9" @@ -1294,6 +1354,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.3.2" @@ -1447,12 +1513,13 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1473,21 +1540,21 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi", - "wasi 0.14.7+wasi-0.2.4", + "wasip2", "wasm-bindgen", ] @@ -1527,7 +1594,7 @@ dependencies = [ "futures-sink", "futures-timer", "futures-util", - "getrandom 0.3.3", + "getrandom 0.3.4", "no-std-compat", "nonzero_ext", "parking_lot", @@ -1539,6 +1606,17 @@ dependencies = [ "web-time", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "h2" version = "0.4.12" @@ -1581,7 +1659,7 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", ] [[package]] @@ -1589,6 +1667,11 @@ name = "hashbrown" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "headers" @@ -1632,6 +1715,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "home" version = "0.5.11" @@ -1825,7 +1917,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.0", + "socket2 0.6.1", "system-configuration", "tokio", "tower-service", @@ -2026,17 +2118,6 @@ dependencies = [ "syn 2.0.106", ] -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -2108,7 +2189,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] @@ -2137,6 +2218,18 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -2288,11 +2381,11 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe949189f46fabb938b3a9a0be30fdd93fd8a09260da863399a8cf3db756ec8" +checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.16.0", ] [[package]] @@ -2416,7 +2509,7 @@ checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "windows-sys 0.59.0", ] @@ -2889,7 +2982,7 @@ dependencies = [ "libc", "once_cell", "raw-cpuid", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "web-sys", "winapi", ] @@ -2922,7 +3015,7 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2 0.6.0", + "socket2 0.6.1", "thiserror 2.0.17", "tokio", "tracing", @@ -2936,7 +3029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", - "getrandom 0.3.3", + "getrandom 0.3.4", "lru-slab", "rand 0.9.2", "ring", @@ -2959,7 +3052,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.0", + "socket2 0.6.1", "tracing", "windows-sys 0.60.2", ] @@ -3041,7 +3134,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -3155,9 +3248,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a52d8d02cacdb176ef4678de6c052efb4b3da14b78e4db683a4252762be5433" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -3167,9 +3260,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722166aa0d7438abbaa4d5cc2c649dac844e8c56d82fb3d33e9c34b5cd268fc6" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -3178,15 +3271,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3160422bbd54dd5ecfdca71e5fd59b7b8fe2b1697ab2baf64f6d05dcc66d298" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.23" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "base64 0.22.1", "bytes", @@ -3228,6 +3321,16 @@ dependencies = [ "webpki-roots", ] +[[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.17.14" @@ -3455,6 +3558,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[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 = "security-framework" version = "2.11.1" @@ -3516,6 +3632,12 @@ version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +[[package]] +name = "seq-macro" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" + [[package]] name = "serde" version = "1.0.228" @@ -3855,7 +3977,7 @@ dependencies = [ "http 1.3.1", "indexmap 2.11.4", "locktick", - "lru 0.16.1", + "lru 0.16.2", "num_cpus", "once_cell", "parking_lot", @@ -3900,7 +4022,7 @@ dependencies = [ "indexmap 2.11.4", "itertools 0.14.0", "locktick", - "lru 0.16.1", + "lru 0.16.2", "mockall", "open", "parking_lot", @@ -3975,7 +4097,7 @@ dependencies = [ "anyhow", "indexmap 2.11.4", "locktick", - "lru 0.16.1", + "lru 0.16.2", "parking_lot", "snarkvm", "tracing", @@ -4012,7 +4134,7 @@ dependencies = [ "indexmap 2.11.4", "itertools 0.14.0", "locktick", - "lru 0.16.1", + "lru 0.16.2", "once_cell", "parking_lot", "snarkos-account", @@ -4185,7 +4307,7 @@ dependencies = [ [[package]] name = "snarkvm" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "anyhow", "dotenvy", @@ -4208,7 +4330,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "anyhow", @@ -4236,7 +4358,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms-cuda" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "blst", "cc", @@ -4247,7 +4369,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-account", "snarkvm-circuit-algorithms", @@ -4261,7 +4383,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-account" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-network", "snarkvm-circuit-types", @@ -4271,7 +4393,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-algorithms" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-types", "snarkvm-console-algorithms", @@ -4281,7 +4403,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-collections" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-types", @@ -4291,7 +4413,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "indexmap 2.11.4", "itertools 0.14.0", @@ -4309,12 +4431,12 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment-witness" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" [[package]] name = "snarkvm-circuit-network" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-collections", @@ -4325,7 +4447,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-program" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-account", "snarkvm-circuit-algorithms", @@ -4339,7 +4461,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-address", @@ -4354,7 +4476,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-address" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -4367,7 +4489,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-boolean" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-environment", "snarkvm-console-types-boolean", @@ -4376,7 +4498,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-field" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -4386,7 +4508,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-group" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -4398,7 +4520,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-integers" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -4410,7 +4532,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-scalar" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -4421,7 +4543,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-string" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -4433,7 +4555,7 @@ dependencies = [ [[package]] name = "snarkvm-console" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console-account", "snarkvm-console-algorithms", @@ -4446,7 +4568,7 @@ dependencies = [ [[package]] name = "snarkvm-console-account" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "bs58", "snarkvm-console-network", @@ -4457,9 +4579,11 @@ dependencies = [ [[package]] name = "snarkvm-console-algorithms" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "blake2s_simd", + "hex", + "k256", "smallvec", "snarkvm-console-types", "snarkvm-fields", @@ -4470,7 +4594,7 @@ dependencies = [ [[package]] name = "snarkvm-console-collections" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "rayon", @@ -4481,7 +4605,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "anyhow", "enum-iterator", @@ -4501,7 +4625,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network-environment" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "anyhow", "bech32", @@ -4519,7 +4643,7 @@ dependencies = [ [[package]] name = "snarkvm-console-program" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "enum-iterator", "enum_index", @@ -4527,6 +4651,7 @@ dependencies = [ "indexmap 2.11.4", "num-derive", "num-traits", + "seq-macro", "serde_json", "snarkvm-console-account", "snarkvm-console-algorithms", @@ -4539,7 +4664,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-address", @@ -4554,7 +4679,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-address" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -4565,7 +4690,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-boolean" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console-network-environment", ] @@ -4573,7 +4698,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-field" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -4583,7 +4708,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-group" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -4594,7 +4719,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-integers" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -4605,7 +4730,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-scalar" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -4616,7 +4741,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-string" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -4627,7 +4752,7 @@ dependencies = [ [[package]] name = "snarkvm-curves" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "rand 0.8.5", "rayon", @@ -4641,7 +4766,7 @@ dependencies = [ [[package]] name = "snarkvm-fields" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "anyhow", @@ -4658,13 +4783,13 @@ dependencies = [ [[package]] name = "snarkvm-ledger" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "anyhow", "indexmap 2.11.4", "locktick", - "lru 0.16.1", + "lru 0.16.2", "parking_lot", "rand 0.8.5", "rayon", @@ -4686,7 +4811,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-authority" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "anyhow", "rand 0.8.5", @@ -4698,7 +4823,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-block" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "anyhow", "indexmap 2.11.4", @@ -4720,7 +4845,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-committee" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "anyhow", "indexmap 2.11.4", @@ -4739,7 +4864,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-ledger-narwhal-batch-certificate", "snarkvm-ledger-narwhal-batch-header", @@ -4752,7 +4877,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-certificate" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "indexmap 2.11.4", "rayon", @@ -4765,7 +4890,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-header" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "indexmap 2.11.4", "rayon", @@ -4778,7 +4903,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-data" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "bytes", "serde_json", @@ -4789,7 +4914,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-subdag" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "indexmap 2.11.4", "rayon", @@ -4804,7 +4929,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "bytes", "serde_json", @@ -4817,7 +4942,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission-id" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "snarkvm-console", "snarkvm-ledger-puzzle", @@ -4826,14 +4951,14 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "anyhow", "bincode", "indexmap 2.11.4", "locktick", - "lru 0.16.1", + "lru 0.16.2", "parking_lot", "rand 0.8.5", "rand_chacha 0.3.1", @@ -4846,14 +4971,14 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle-epoch" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "anyhow", "colored 3.0.0", "indexmap 2.11.4", "locktick", - "lru 0.16.1", + "lru 0.16.2", "parking_lot", "rand 0.8.5", "rand_chacha 0.3.1", @@ -4869,7 +4994,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-query" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "anyhow", "async-trait", @@ -4886,7 +5011,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-store" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std-storage", "anyhow", @@ -4914,7 +5039,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-test-helpers" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "anyhow", @@ -4932,7 +5057,7 @@ dependencies = [ [[package]] name = "snarkvm-metrics" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "metrics", ] @@ -4940,7 +5065,7 @@ dependencies = [ [[package]] name = "snarkvm-parameters" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "anyhow", @@ -4963,14 +5088,14 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "anyhow", "indexmap 2.11.4", "itertools 0.14.0", "locktick", - "lru 0.16.1", + "lru 0.16.2", "parking_lot", "rand 0.8.5", "rayon", @@ -4996,7 +5121,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-process" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "colored 3.0.0", @@ -5021,8 +5146,9 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-program" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ + "enum-iterator", "indexmap 2.11.4", "paste", "rand 0.8.5", @@ -5039,7 +5165,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-snark" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "bincode", "serde_json", @@ -5052,7 +5178,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "aleo-std", "anyhow", @@ -5074,7 +5200,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities-derives" version = "4.2.1" -source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=58b326d#58b326dfa5808aeb08e354cd58da8f0c50dd38c7" +source = "git+https://github.com/ProvableHQ/snarkVM.git?rev=78a69b7#78a69b70387d917ed1c16a09741a5b6d16862f17" dependencies = [ "proc-macro2", "quote 1.0.41", @@ -5093,12 +5219,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -5322,7 +5448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix 1.1.2", "windows-sys 0.61.2", @@ -5504,29 +5630,26 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.47.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2 0.6.0", + "socket2 0.6.1", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote 1.0.41", @@ -6010,15 +6133,6 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" diff --git a/Cargo.toml b/Cargo.toml index 1f968c53b9..315598a9dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ default-features = false [workspace.dependencies.snarkvm] #path = "../snarkVM" git = "https://github.com/ProvableHQ/snarkVM.git" -rev = "58b326d" +rev = "78a69b7" #version = "=4.2.1" default-features = false diff --git a/node/bft/events/src/block_response.rs b/node/bft/events/src/block_response.rs index 2e85184cb5..fc2e8af014 100644 --- a/node/bft/events/src/block_response.rs +++ b/node/bft/events/src/block_response.rs @@ -15,12 +15,18 @@ use super::*; +use snarkvm::console::network::ConsensusVersion; + +/// Gateway/BFT version of `snarkos_router_messages::BlockResponse`. #[derive(Clone, PartialEq, Eq)] pub struct BlockResponse { /// The original block request. pub request: BlockRequest, /// The blocks. pub blocks: Data>, + /// The consensus version at the height of the *last* block in this response. + /// This enables detecting if the current node, or the peer, missed an upgrade. + pub latest_consensus_version: ConsensusVersion, } impl EventTrait for BlockResponse { @@ -40,7 +46,8 @@ impl EventTrait for BlockResponse { impl ToBytes for BlockResponse { fn write_le(&self, mut writer: W) -> IoResult<()> { self.request.write_le(&mut writer)?; - self.blocks.write_le(&mut writer) + self.blocks.write_le(&mut writer)?; + self.latest_consensus_version.write_le(&mut writer) } } @@ -48,8 +55,9 @@ impl FromBytes for BlockResponse { fn read_le(mut reader: R) -> IoResult { let request = BlockRequest::read_le(&mut reader)?; let blocks = Data::read_le(&mut reader)?; + let latest_consensus_version = FromBytes::read_le(&mut reader)?; - Ok(Self { request, blocks }) + Ok(Self { request, blocks, latest_consensus_version }) } } @@ -137,7 +145,9 @@ impl FromBytes for DataBlocks { #[cfg(test)] pub mod prop_tests { use crate::{BlockResponse, DataBlocks, block_request::prop_tests::any_block_request}; + use snarkvm::{ + console::network::ConsensusVersion, ledger::test_helpers::sample_genesis_block, prelude::{FromBytes, TestRng, ToBytes, block::Block, narwhal::Data}, }; @@ -161,7 +171,11 @@ pub mod prop_tests { pub fn any_block_response() -> BoxedStrategy> { (any_block_request(), any_data_blocks()) - .prop_map(|(request, data_blocks)| BlockResponse { request, blocks: Data::Object(data_blocks) }) + .prop_map(|(request, data_blocks)| BlockResponse { + request, + blocks: Data::Object(data_blocks), + latest_consensus_version: ConsensusVersion::V1, + }) .boxed() } diff --git a/node/bft/events/src/primary_ping.rs b/node/bft/events/src/primary_ping.rs index 76f90fe2c4..2315c34eef 100644 --- a/node/bft/events/src/primary_ping.rs +++ b/node/bft/events/src/primary_ping.rs @@ -19,24 +19,17 @@ use super::*; pub struct PrimaryPing { pub version: u32, pub block_locators: BlockLocators, - pub primary_certificate: Data>, + // The latest certificate of this primary. + // (can be `None` if the node has not participated in consensus yet or if the network has not created any blocks yet) + pub primary_certificate: Option>>, } -impl PrimaryPing { +impl From<(u32, BlockLocators, Option>)> for PrimaryPing { /// Initializes a new ping event. - pub const fn new( - version: u32, - block_locators: BlockLocators, - primary_certificate: Data>, + fn from( + (version, block_locators, primary_certificate): (u32, BlockLocators, Option>), ) -> Self { - Self { version, block_locators, primary_certificate } - } -} - -impl From<(u32, BlockLocators, BatchCertificate)> for PrimaryPing { - /// Initializes a new ping event. - fn from((version, block_locators, primary_certificate): (u32, BlockLocators, BatchCertificate)) -> Self { - Self::new(version, block_locators, Data::Object(primary_certificate)) + Self { version, block_locators, primary_certificate: primary_certificate.map(Data::Object) } } } @@ -54,8 +47,14 @@ impl ToBytes for PrimaryPing { self.version.write_le(&mut writer)?; // Write the block locators. self.block_locators.write_le(&mut writer)?; - // Write the primary certificate. - self.primary_certificate.write_le(&mut writer)?; + + // Write the primary certificate (if any). + if let Some(cert) = &self.primary_certificate { + 1u8.write_le(&mut writer)?; + cert.write_le(&mut writer)?; + } else { + 0u8.write_le(&mut writer)?; + } Ok(()) } @@ -67,11 +66,12 @@ impl FromBytes for PrimaryPing { let version = u32::read_le(&mut reader)?; // Read the block locators. let block_locators = BlockLocators::read_le(&mut reader)?; - // Read the primary certificate. - let primary_certificate = Data::read_le(&mut reader)?; + + // Read the primary certificate (if any). + let primary_certificate = if u8::read_le(&mut reader)? == 0 { None } else { Some(Data::read_le(&mut reader)?) }; // Return the ping event. - Ok(Self::new(version, block_locators, primary_certificate)) + Ok(Self { version, block_locators, primary_certificate }) } } @@ -94,7 +94,7 @@ pub mod prop_tests { pub fn any_primary_ping() -> BoxedStrategy> { (any::(), any_block_locators(), any_batch_certificate()) .prop_map(|(version, block_locators, batch_certificate)| { - PrimaryPing::from((version, block_locators, batch_certificate.clone())) + PrimaryPing::from((version, block_locators, Some(batch_certificate.clone()))) }) .boxed() } @@ -107,8 +107,8 @@ pub mod prop_tests { assert_eq!(primary_ping.version, decoded.version); assert_eq!(primary_ping.block_locators, decoded.block_locators); assert_eq!( - primary_ping.primary_certificate.deserialize_blocking().unwrap(), - decoded.primary_certificate.deserialize_blocking().unwrap(), + primary_ping.primary_certificate.unwrap().deserialize_blocking().unwrap(), + decoded.primary_certificate.unwrap().deserialize_blocking().unwrap(), ); } } diff --git a/node/bft/src/gateway.rs b/node/bft/src/gateway.rs index 99f75df097..bf012b4122 100644 --- a/node/bft/src/gateway.rs +++ b/node/bft/src/gateway.rs @@ -576,6 +576,9 @@ impl Gateway { bail!("Block request from '{peer_ip}' has an excessive range ({start_height}..{end_height})") } + // End height is exclusive. + let latest_consensus_version = N::CONSENSUS_VERSION(end_height - 1)?; + let self_ = self.clone(); let blocks = match task::spawn_blocking(move || { // Retrieve the blocks within the requested range. @@ -594,17 +597,18 @@ impl Gateway { let self_ = self.clone(); tokio::spawn(async move { // Send the `BlockResponse` message to the peer. - let event = Event::BlockResponse(BlockResponse { request: block_request, blocks }); + let event = Event::BlockResponse(BlockResponse { + request: block_request, + blocks, + latest_consensus_version, + }); Transport::send(&self_, peer_ip, event).await; }); Ok(true) } - Event::BlockResponse(block_response) => { + Event::BlockResponse(BlockResponse { request, blocks, latest_consensus_version }) => { // Process the block response. Except for some tests, there is always a sync sender. if let Some(sync_sender) = self.sync_sender.get() { - // Retrieve the block response. - let BlockResponse { request, blocks } = block_response; - // Check the response corresponds to a request. if !self.cache.remove_outbound_block_request(peer_ip, &request) { bail!("Unsolicited block response from '{peer_ip}'") @@ -627,7 +631,9 @@ impl Gateway { // Ensure the block response is well-formed. blocks.ensure_response_is_well_formed(peer_ip, request.start_height, request.end_height)?; // Send the blocks to the sync module. - if let Err(err) = sync_sender.insert_block_response(peer_ip, blocks.0).await { + if let Err(err) = + sync_sender.insert_block_response(peer_ip, blocks.0, latest_consensus_version).await + { warn!("Unable to process block response from '{peer_ip}' - {err}"); } } @@ -661,9 +667,7 @@ impl Gateway { self.disconnect(peer_ip); Ok(false) } - Event::PrimaryPing(ping) => { - let PrimaryPing { version, block_locators, primary_certificate } = ping; - + Event::PrimaryPing(PrimaryPing { version, block_locators, primary_certificate }) => { // Ensure the event version is not outdated. if version < Event::::VERSION { bail!("Dropping '{peer_ip}' on event version {version} (outdated)"); @@ -677,8 +681,10 @@ impl Gateway { } } - // Send the batch certificates to the primary. - let _ = self.primary_sender().tx_primary_ping.send((peer_ip, primary_certificate)).await; + if let Some(certificate) = primary_certificate { + // Send the batch certificates to the primary. + let _ = self.primary_sender().tx_primary_ping.send((peer_ip, certificate)).await; + } Ok(true) } Event::TransmissionRequest(request) => { diff --git a/node/bft/src/helpers/channels.rs b/node/bft/src/helpers/channels.rs index 19bac87a56..e8c5635113 100644 --- a/node/bft/src/helpers/channels.rs +++ b/node/bft/src/helpers/channels.rs @@ -231,7 +231,8 @@ pub fn init_worker_channels() -> (WorkerSender, WorkerReceiver #[derive(Debug)] pub struct SyncSender { - pub tx_block_sync_insert_block_response: mpsc::Sender<(SocketAddr, Vec>, oneshot::Sender>)>, + pub tx_block_sync_insert_block_response: + mpsc::Sender<(SocketAddr, Vec>, ConsensusVersion, oneshot::Sender>)>, pub tx_block_sync_remove_peer: mpsc::Sender, pub tx_block_sync_update_peer_locators: mpsc::Sender<(SocketAddr, BlockLocators, oneshot::Sender>)>, pub tx_certificate_request: mpsc::Sender<(SocketAddr, CertificateRequest)>, @@ -253,14 +254,21 @@ impl SyncSender { } /// Sends the request to insert a new block response. - pub async fn insert_block_response(&self, peer_ip: SocketAddr, blocks: Vec>) -> Result<()> { + pub async fn insert_block_response( + &self, + peer_ip: SocketAddr, + blocks: Vec>, + latest_consensus_version: ConsensusVersion, + ) -> Result<()> { // Initialize a callback sender and receiver. let (callback_sender, callback_receiver) = oneshot::channel(); // Send the request to advance with sync blocks. // This `tx_block_sync_advance_with_sync_blocks.send()` call // causes the `rx_block_sync_advance_with_sync_blocks.recv()` call // in one of the loops in [`Sync::run()`] to return. - self.tx_block_sync_insert_block_response.send((peer_ip, blocks, callback_sender)).await?; + self.tx_block_sync_insert_block_response + .send((peer_ip, blocks, latest_consensus_version, callback_sender)) + .await?; // Await the callback to continue. callback_receiver.await? } @@ -268,7 +276,8 @@ impl SyncSender { #[derive(Debug)] pub struct SyncReceiver { - pub rx_block_sync_insert_block_response: mpsc::Receiver<(SocketAddr, Vec>, oneshot::Sender>)>, + pub rx_block_sync_insert_block_response: + mpsc::Receiver<(SocketAddr, Vec>, ConsensusVersion, oneshot::Sender>)>, pub rx_block_sync_remove_peer: mpsc::Receiver, pub rx_block_sync_update_peer_locators: mpsc::Receiver<(SocketAddr, BlockLocators, oneshot::Sender>)>, pub rx_certificate_request: mpsc::Receiver<(SocketAddr, CertificateRequest)>, diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 542b6b18e5..571bb3418c 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -1236,12 +1236,7 @@ impl Primary { } } - // Determine if the primary certificate was found. - match certificate { - Some(certificate) => certificate, - // Skip this iteration of the loop (do not send a primary ping). - None => continue, - } + certificate }; // Construct the primary ping. diff --git a/node/bft/src/sync/mod.rs b/node/bft/src/sync/mod.rs index eff35bf4db..8b08a5ad74 100644 --- a/node/bft/src/sync/mod.rs +++ b/node/bft/src/sync/mod.rs @@ -25,8 +25,12 @@ use snarkos_node_bft_events::{CertificateRequest, CertificateResponse, Event}; use snarkos_node_bft_ledger_service::LedgerService; use snarkos_node_router::PeerPoolHandling; use snarkos_node_sync::{BLOCK_REQUEST_BATCH_DELAY, BlockSync, Ping, PrepareSyncRequest, locators::BlockLocators}; + use snarkvm::{ - console::{network::Network, types::Field}, + console::{ + network::{ConsensusVersion, Network}, + types::Field, + }, ledger::{authority::Authority, block::Block, narwhal::BatchCertificate}, prelude::{cfg_into_iter, cfg_iter}, }; @@ -234,8 +238,10 @@ impl Sync { // which causes the `rx_block_sync_advance_with_sync_blocks.recv()` call below to return. let self_ = self.clone(); self.spawn(async move { - while let Some((peer_ip, blocks, callback)) = rx_block_sync_insert_block_response.recv().await { - callback.send(self_.insert_block_response(peer_ip, blocks).await).ok(); + while let Some((peer_ip, blocks, latest_consensus_version, callback)) = + rx_block_sync_insert_block_response.recv().await + { + callback.send(self_.insert_block_response(peer_ip, blocks, latest_consensus_version).await).ok(); } }); @@ -342,9 +348,14 @@ impl Sync { // Callbacks used when receiving messages from the Gateway impl Sync { /// We received a block response and can (possibly) advance synchronization. - async fn insert_block_response(&self, peer_ip: SocketAddr, blocks: Vec>) -> Result<()> { + async fn insert_block_response( + &self, + peer_ip: SocketAddr, + blocks: Vec>, + latest_consensus_version: ConsensusVersion, + ) -> Result<()> { // Verify that the response is valid and add it to block sync. - self.block_sync.insert_block_responses(peer_ip, blocks) + self.block_sync.insert_block_responses(peer_ip, blocks, latest_consensus_version) // No need to advance block sync here, as the new response will // notify the incoming task. @@ -561,7 +572,10 @@ impl Sync { // The height is incremented as blocks are added. let mut current_height = start_height; - trace!("Try advancing with block responses (at block {current_height})"); + trace!( + "Trying to advance blocks with BFT (starting at block {current_height}, current sync speed is {})", + self.block_sync.get_sync_speed() + ); // If we already were within GC or successfully caught up with GC, try to advance BFT normally again. loop { @@ -586,13 +600,13 @@ impl Sync { cleanup(start_height, current_height, None) } else { - info!("Block sync is too far behind other validators. Syncing without BFT."); - // For non-BFT sync we need to start at the current height of the ledger,as blocks are immediately // added to it and not queue up in `latest_block_responses`. let start_height = ledger_height; let mut current_height = start_height; + trace!("Trying to advance blocks without BFT (starting at block {current_height})"); + // For sanity, update the sync height before starting. // (if this is lower or equal to the current sync height, this is a noop) self.block_sync.set_sync_height(start_height); diff --git a/node/router/messages/src/block_response.rs b/node/router/messages/src/block_response.rs index 20b03cb9d5..b12d324e31 100644 --- a/node/router/messages/src/block_response.rs +++ b/node/router/messages/src/block_response.rs @@ -28,6 +28,9 @@ pub struct BlockResponse { pub request: BlockRequest, /// The blocks. pub blocks: Data>, + /// The consensus version at the height of the *last* block in this response. + /// This enables detecting if the current node, or the peer, missed an upgrade. + pub latest_consensus_version: ConsensusVersion, } impl MessageTrait for BlockResponse { @@ -47,15 +50,17 @@ impl MessageTrait for BlockResponse { impl ToBytes for BlockResponse { fn write_le(&self, mut writer: W) -> io::Result<()> { self.request.write_le(&mut writer)?; - self.blocks.write_le(writer) + self.blocks.write_le(&mut writer)?; + self.latest_consensus_version.write_le(&mut writer) } } impl FromBytes for BlockResponse { fn read_le(mut reader: R) -> io::Result { let request = BlockRequest::read_le(&mut reader)?; - let blocks = Data::read_le(reader)?; - Ok(Self { request, blocks }) + let blocks = Data::read_le(&mut reader)?; + let latest_consensus_version = FromBytes::read_le(&mut reader)?; + Ok(Self { request, blocks, latest_consensus_version }) } } @@ -64,7 +69,7 @@ pub mod prop_tests { use crate::{BlockResponse, DataBlocks, block_request::prop_tests::any_block_request}; use snarkvm::{ ledger::test_helpers::sample_genesis_block, - prelude::{block::Block, narwhal::Data}, + prelude::{ConsensusVersion, block::Block, narwhal::Data}, utilities::{FromBytes, TestRng, ToBytes}, }; @@ -87,7 +92,11 @@ pub mod prop_tests { pub fn any_block_response() -> BoxedStrategy> { (any_block_request(), any_data_blocks()) - .prop_map(|(request, data_blocks)| BlockResponse { request, blocks: Data::Object(data_blocks) }) + .prop_map(|(request, data_blocks)| BlockResponse { + request, + blocks: Data::Object(data_blocks), + latest_consensus_version: ConsensusVersion::V1, + }) .boxed() } diff --git a/node/router/src/inbound.rs b/node/router/src/inbound.rs index 8efaea796c..9b4233ab0a 100644 --- a/node/router/src/inbound.rs +++ b/node/router/src/inbound.rs @@ -30,6 +30,7 @@ use crate::{ }; use snarkos_node_tcp::protocols::Reading; use snarkvm::prelude::{ + ConsensusVersion, Network, block::{Block, Header, Transaction}, puzzle::Solution, @@ -124,9 +125,7 @@ pub trait Inbound: Reading + Outbound { false => bail!("Peer '{peer_ip}' sent an invalid block request"), } } - Message::BlockResponse(message) => { - let BlockResponse { request, blocks } = message; - + Message::BlockResponse(BlockResponse { request, blocks, latest_consensus_version }) => { // Remove the block request, checking if this node previously sent a block request to this peer. if !self.router().cache.remove_outbound_block_request(peer_ip, &request) { bail!("Peer '{peer_ip}' is not following the protocol (unexpected block response)") @@ -150,7 +149,7 @@ pub trait Inbound: Reading + Outbound { // Process the block response. let node = self.clone(); - match spawn_blocking(move || node.block_response(peer_ip, blocks.0)).await? { + match spawn_blocking(move || node.block_response(peer_ip, blocks.0, latest_consensus_version)).await? { true => Ok(true), false => bail!("Peer '{peer_ip}' sent an invalid block response"), } @@ -310,7 +309,12 @@ pub trait Inbound: Reading + Outbound { fn block_request(&self, peer_ip: SocketAddr, _message: BlockRequest) -> bool; /// Handles a `BlockResponse` message. - fn block_response(&self, peer_ip: SocketAddr, _blocks: Vec>) -> bool; + fn block_response( + &self, + peer_ip: SocketAddr, + blocks: Vec>, + latest_consensus_version: ConsensusVersion, + ) -> bool; /// Handles a `PeerRequest` message. fn peer_request(&self, peer_ip: SocketAddr) -> bool { diff --git a/node/router/tests/common/router.rs b/node/router/tests/common/router.rs index 746571a87d..17aef56d29 100644 --- a/node/router/tests/common/router.rs +++ b/node/router/tests/common/router.rs @@ -42,6 +42,7 @@ use snarkos_node_tcp::{ protocols::{Disconnect, Handshake, OnConnect, Reading, Writing}, }; use snarkvm::prelude::{ + ConsensusVersion, Field, Network, block::{Block, Header, Transaction}, @@ -207,7 +208,12 @@ impl Inbound for TestRouter { } /// Handles a `BlockResponse` message. - fn block_response(&self, _peer_ip: SocketAddr, _blocks: Vec>) -> bool { + fn block_response( + &self, + _peer_ip: SocketAddr, + _blocks: Vec>, + _latest_consensus_version: ConsensusVersion, + ) -> bool { true } diff --git a/node/src/client/router.rs b/node/src/client/router.rs index 87f0ed99fa..891da7e7e2 100644 --- a/node/src/client/router.rs +++ b/node/src/client/router.rs @@ -32,8 +32,9 @@ use snarkos_node_router::{ }; use snarkos_node_tcp::{Connection, ConnectionSide, Tcp}; use snarkvm::{ - ledger::narwhal::Data, - prelude::{Network, block::Transaction}, + console::network::{ConsensusVersion, Network}, + ledger::{block::Transaction, narwhal::Data}, + utilities::{log_error, log_warning}, }; use std::{io, net::SocketAddr}; @@ -179,6 +180,15 @@ impl> Inbound for Client { fn block_request(&self, peer_ip: SocketAddr, message: BlockRequest) -> bool { let BlockRequest { start_height, end_height } = &message; + // Get the latest consensus version, i.e., the one for the last block's height. + let latest_consensus_version = match N::CONSENSUS_VERSION(end_height - 1) { + Ok(version) => version, + Err(err) => { + log_error(&err.context("Failed to retrieve consensus version")); + return false; + } + }; + // Retrieve the blocks within the requested range. let blocks = match self.ledger.get_blocks(*start_height..*end_height) { Ok(blocks) => Data::Object(DataBlocks(blocks)), @@ -187,16 +197,25 @@ impl> Inbound for Client { return false; } }; + // Send the `BlockResponse` message to the peer. - self.router().send(peer_ip, Message::BlockResponse(BlockResponse { request: message, blocks })); + self.router().send( + peer_ip, + Message::BlockResponse(BlockResponse { request: message, blocks, latest_consensus_version }), + ); true } /// Handles a `BlockResponse` message. - fn block_response(&self, peer_ip: SocketAddr, blocks: Vec>) -> bool { + fn block_response( + &self, + peer_ip: SocketAddr, + blocks: Vec>, + latest_consensus_version: ConsensusVersion, + ) -> bool { // We do not need to explicitly sync here because insert_block_response, will wake up the sync task. - if let Err(err) = self.sync.insert_block_responses(peer_ip, blocks) { - warn!("Failed to insert block response: {err}"); + if let Err(err) = self.sync.insert_block_responses(peer_ip, blocks, latest_consensus_version) { + log_warning(&err.context("Failed to insert block response")); false } else { true diff --git a/node/src/prover/router.rs b/node/src/prover/router.rs index c4fcf7773c..69d9aa7b2a 100644 --- a/node/src/prover/router.rs +++ b/node/src/prover/router.rs @@ -26,7 +26,7 @@ use snarkos_node_router::messages::{ UnconfirmedTransaction, }; use snarkos_node_tcp::{Connection, ConnectionSide, Tcp}; -use snarkvm::prelude::{Field, Network, Zero, block::Transaction}; +use snarkvm::prelude::{ConsensusVersion, Field, Network, Zero, block::Transaction}; use std::{io, net::SocketAddr}; @@ -167,7 +167,12 @@ impl> Inbound for Prover { } /// Handles a `BlockResponse` message. - fn block_response(&self, peer_ip: SocketAddr, _blocks: Vec>) -> bool { + fn block_response( + &self, + peer_ip: SocketAddr, + _blocks: Vec>, + _latest_consensus_version: ConsensusVersion, + ) -> bool { debug!("Disconnecting '{peer_ip}' for the following reason - {:?}", DisconnectReason::ProtocolViolation); false } diff --git a/node/src/validator/router.rs b/node/src/validator/router.rs index ca384f5bd2..75bc5d3449 100644 --- a/node/src/validator/router.rs +++ b/node/src/validator/router.rs @@ -30,8 +30,9 @@ use snarkos_node_router::{ }; use snarkos_node_tcp::{Connection, ConnectionSide, Tcp}; use snarkvm::{ - ledger::narwhal::Data, - prelude::{Network, block::Transaction, error}, + console::network::{ConsensusVersion, Network}, + ledger::{block::Transaction, narwhal::Data}, + utilities::{error, log_error}, }; use std::{io, net::SocketAddr}; @@ -177,6 +178,15 @@ impl> Inbound for Validator { fn block_request(&self, peer_ip: SocketAddr, message: BlockRequest) -> bool { let BlockRequest { start_height, end_height } = &message; + // Get the latest consensus version, i.e., the one for the last block's height. + let latest_consensus_version = match N::CONSENSUS_VERSION(end_height - 1) { + Ok(version) => version, + Err(err) => { + log_error(&err.context("Failed to retrieve consensus version")); + return false; + } + }; + // Retrieve the blocks within the requested range. let blocks = match self.ledger.get_blocks(*start_height..*end_height) { Ok(blocks) => Data::Object(DataBlocks(blocks)), @@ -186,12 +196,20 @@ impl> Inbound for Validator { } }; // Send the `BlockResponse` message to the peer. - self.router().send(peer_ip, Message::BlockResponse(BlockResponse { request: message, blocks })); + self.router().send( + peer_ip, + Message::BlockResponse(BlockResponse { request: message, blocks, latest_consensus_version }), + ); true } /// Handles a `BlockResponse` message. - fn block_response(&self, peer_ip: SocketAddr, _blocks: Vec>) -> bool { + fn block_response( + &self, + peer_ip: SocketAddr, + _blocks: Vec>, + _latest_consensus_version: ConsensusVersion, + ) -> bool { warn!("Received a block response through P2P, not BFT, from {peer_ip}"); false } diff --git a/node/sync/src/block_sync.rs b/node/sync/src/block_sync.rs index 0bc4e1dba1..a69fd04745 100644 --- a/node/sync/src/block_sync.rs +++ b/node/sync/src/block_sync.rs @@ -21,7 +21,12 @@ use snarkos_node_bft_ledger_service::LedgerService; use snarkos_node_router::{PeerPoolHandling, messages::DataBlocks}; use snarkos_node_sync_communication_service::CommunicationService; use snarkos_node_sync_locators::{CHECKPOINT_INTERVAL, NUM_RECENT_BLOCKS}; -use snarkvm::prelude::{Network, block::Block}; + +use snarkvm::{ + console::network::{ConsensusVersion, Network}, + prelude::block::Block, + utilities::ensure_equals, +}; use anyhow::{Result, bail, ensure}; use indexmap::{IndexMap, IndexSet}; @@ -367,7 +372,7 @@ impl BlockSync { } }; - debug!("Sending {len} block requests to peers {peers:?}", len = requests.len(), peers = sync_peers.keys()); + debug!("Sending {len} block requests to peer(s) at {peers:?}", len = requests.len(), peers = sync_peers.keys()); // Use a randomly sampled subset of the sync IPs. let sync_ips: IndexSet<_> = @@ -447,7 +452,24 @@ impl BlockSync { /// Note, that this only queues the response. After this, you most likely want to call `Self::try_advancing_block_synchronization`. /// #[inline] - pub fn insert_block_responses(&self, peer_ip: SocketAddr, blocks: Vec>) -> Result<()> { + pub fn insert_block_responses( + &self, + peer_ip: SocketAddr, + blocks: Vec>, + latest_consensus_version: ConsensusVersion, + ) -> Result<()> { + let Some(last_height) = blocks.as_slice().last().map(|b| b.height()) else { + bail!("Empty block response"); + }; + + let expected_consensus_version = N::CONSENSUS_VERSION(last_height)?; + + ensure_equals!( + expected_consensus_version, + latest_consensus_version, + "the peer's consensus version for height {last_height} does not match ours" + ); + // Insert the candidate blocks into the sync pool. for block in blocks { if let Err(error) = self.insert_block_response(peer_ip, block) { @@ -505,7 +527,7 @@ impl BlockSync { let mut current_height = self.ledger.latest_block_height(); let start_height = current_height; trace!( - "Try advancing with block responses (at block {current_height}, current sync speed is {})", + "Trying to advance with block responses (starting at block {current_height}, current sync speed is {})", self.get_sync_speed() ); @@ -689,7 +711,7 @@ impl BlockSync { } } - // Update `is_synced`. + // Update sync status. if let Some(greatest_peer_height) = self.locators.read().values().map(|l| l.latest_locator_height()).max() { self.sync_state.write().set_greatest_peer_height(greatest_peer_height); } @@ -761,24 +783,18 @@ impl BlockSync { ); print_requests(); - - // Return an empty list of block requests. - (Default::default(), Default::default()) } else if max_new_blocks_to_request == 0 { trace!( "Already reached the maximum number of outstanding blocks ({max_outstanding_block_requests}). Will not issue more." ); print_requests(); - - // Return an empty list of block requests. - (Default::default(), Default::default()) } else if let Some((sync_peers, min_common_ancestor)) = self.find_sync_peers_inner(current_height) { // Retrieve the highest block height. let greatest_peer_height = sync_peers.values().map(|l| l.latest_locator_height()).max().unwrap_or(0); // Update the state of `is_block_synced` for the sync module. self.sync_state.write().set_greatest_peer_height(greatest_peer_height); // Return the list of block requests. - ( + return ( self.construct_requests( &sync_peers, current_height, @@ -787,21 +803,19 @@ impl BlockSync { greatest_peer_height, ), sync_peers, - ) + ); } else { - // Update `is_block_synced` if there are no pending requests or responses. - if self.requests.read().is_empty() { - trace!("All requests have been processed. Will set block synced to true."); - // Update the state of `is_block_synced` for the sync module. - // TODO(kaimast): remove this workaround - self.sync_state.write().set_greatest_peer_height(0); + let num_requests = self.requests.read().len(); + if num_requests == 0 { + trace!("No new blocks can be requested, and there are no outstanding requests remaining."); } else { - trace!("No new blocks can be requests, but there are still outstanding requests."); + trace!("No new blocks can be requested, but there are still {num_requests} outstanding requests."); + print_requests(); } - - // Return an empty list of block requests. - (Default::default(), Default::default()) } + + // Return an empty list of block requests. + (Default::default(), Default::default()) } /// Should only be called by validators when they successfully process a block request. @@ -1029,39 +1043,45 @@ impl BlockSync { // requests immediately if there are no other peers at a given time. // Further, this only closes the first gap. So multiple calls to this might be needed. let sync_height = self.get_sync_height(); - if let Some(next_height) = next_request_height { - let start = sync_height + 1; - // Is there a gap? - if next_height > start { - // Only request the given range, so there are no overlaps with other requests. - let end = next_height; // exclusive - let max_new_blocks_to_request = end - start; + // If there are no requests remaining, we do not need to re-issue requests, but can just issue them regularly. + let next_height = next_request_height?; - let Some((sync_peers, min_common_ancestor)) = self.find_sync_peers_inner(start) else { - warn!("Block requests timed out, but found no other peers to re-request from"); - return None; - }; - - // Retrieve the highest block height. - let greatest_peer_height = sync_peers.values().map(|l| l.latest_locator_height()).max().unwrap_or(0); - - debug!("Re-requesting blocks starting at height {start}"); - - return Some(( - self.construct_requests( - &sync_peers, - sync_height, - min_common_ancestor, - max_new_blocks_to_request, - greatest_peer_height, - ), - sync_peers, - )); - } + // Only issue block requests if there is a gap at the beginning. + let start = sync_height + 1; + if next_height <= start { + return None; } - None + // Only request the given range, so there are no overlaps with other requests. + let end = next_height; // exclusive + let max_new_blocks_to_request = end - start; + + let Some((sync_peers, min_common_ancestor)) = self.find_sync_peers_inner(start) else { + // Once there are new peers, the sync task will be woken up and (if needed) will retry. + warn!("Block requests timed out, but found no other peers to re-request from"); + return None; + }; + + // Retrieve the highest block height. + let greatest_peer_height = sync_peers.values().map(|l| l.latest_locator_height()).max().unwrap_or(0); + + // (Try to) construct the requests. + let requests = self.construct_requests( + &sync_peers, + sync_height, + min_common_ancestor, + max_new_blocks_to_request, + greatest_peer_height, + ); + + // If the ledger advanced concurrenctly, there may be no requests to issue after all. + if let Some((height, _)) = requests.as_slice().first() { + debug!("Re-requesting blocks starting at height {height}"); + Some((requests, sync_peers)) + } else { + None + } } /// Finds the peers to sync from and the shared common ancestor, starting at the give height. @@ -1156,7 +1176,8 @@ impl BlockSync { let mut start_height = sync_height + 1; loop { - if requests.contains_key(&start_height) { + // Do not issue requests that already exist or would be obsolete. + if requests.contains_key(&start_height) || self.ledger.latest_block_height() >= start_height { start_height += 1; } else { break; @@ -1187,7 +1208,7 @@ impl BlockSync { for height in start_height..end_height { // Ensure the current height is not in the ledger or already requested. if let Err(err) = self.check_block_request(height) { - trace!("Failed to issue new request for height {height}: {err}"); + trace!("{err}"); // If the sequence of block requests is interrupted, then return early. // Otherwise, continue until the first start height that is new. diff --git a/node/sync/src/block_sync/sync_state.rs b/node/sync/src/block_sync/sync_state.rs index ba6b480555..a50c3f9c53 100644 --- a/node/sync/src/block_sync/sync_state.rs +++ b/node/sync/src/block_sync/sync_state.rs @@ -17,6 +17,13 @@ use super::MAX_BLOCKS_BEHIND; use std::{cmp::Ordering, time::Instant}; +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum SyncStatus { + Unsynced, // Never synced or no peers + Syncing, // In progress + Synced, // Fully synced with peers +} + #[derive(Clone)] pub(super) struct SyncState { /// The height we synced to already @@ -28,20 +35,14 @@ pub(super) struct SyncState { greatest_peer_height: Option, /// Are we synced? /// Allows keeping track of when the sync state changes. - is_synced: bool, + status: SyncStatus, /// Last time the sync state changed last_change: Instant, } impl Default for SyncState { fn default() -> Self { - Self { - sync_height: 0, - greatest_peer_height: None, - // Start as "synced" by default. Otherwise, validators will never propose certificates. - is_synced: true, - last_change: Instant::now(), - } + Self { sync_height: 0, greatest_peer_height: None, status: SyncStatus::Unsynced, last_change: Instant::now() } } } @@ -55,7 +56,7 @@ impl SyncState { /// Did we catch up with the greatest known peer height? /// This will return false if we never synced from a peer. pub fn is_block_synced(&self) -> bool { - self.is_synced + self.status == SyncStatus::Synced } /// Returns `true` if there a blocks to sync from other nodes. @@ -116,44 +117,62 @@ impl SyncState { /// Updates the state of `is_block_synced` for the sync module. fn update_is_block_synced(&mut self) { trace!( - "Updating is_block_synced: greatest_peer_height={greatest_peer:?}, current_height={current}, is_synced={is_synced}", + "Updating is_block_synced: greatest_peer_height={greatest_peer:?}, current_height={current}, status={status:?}", greatest_peer = self.greatest_peer_height, current = self.sync_height, - is_synced = self.is_synced, + status = self.status, ); let num_blocks_behind = self.num_blocks_behind(); - let old_sync_val = self.is_synced; + let old_status = self.status; // If there are no block locators, we consider ourselves synced. // Otherwise, validators will never propose certificates. - let new_sync_val = num_blocks_behind.is_none_or(|num| num <= MAX_BLOCKS_BEHIND); - - // Print a message if the state changed - if new_sync_val != old_sync_val { - // Measure how long sync took. - let now = Instant::now(); - let elapsed = now.saturating_duration_since(self.last_change).as_secs(); - self.last_change = now; - - if new_sync_val { - let elapsed = - if elapsed < 60 { format!("{elapsed} seconds") } else { format!("{} minutes", elapsed / 60) }; + let new_status = match num_blocks_behind { + Some(num) if num <= MAX_BLOCKS_BEHIND => SyncStatus::Synced, + Some(_) => SyncStatus::Syncing, + None => SyncStatus::Unsynced, + }; + + // Return early if the state is unchanged + if new_status == old_status { + return; + } - debug!("Block sync state changed to \"synced\". It took {elapsed} to catch up with the network."); - } else { + // Measure how long sync took. + let now = Instant::now(); + let elapsed = now.saturating_duration_since(self.last_change).as_secs(); + + self.status = new_status; + self.last_change = now; + + match self.status { + SyncStatus::Synced => { + if old_status == SyncStatus::Syncing { + let elapsed = + if elapsed < 60 { format!("{elapsed} seconds") } else { format!("{} minutes", elapsed / 60) }; + + debug!("Block sync state changed to \"synced\". It took {elapsed} to catch up with the network."); + } else { + // If we move directly from unsynced to synced, it means we connected to a peer with a lower height. + // In this case it does not make sense to print how long sync took. + debug!("Block sync state changed to \"synced\"."); + } + } + SyncStatus::Syncing => { // num_blocks_behind should never be None at this point, // but we still use `unwrap_or` just in case. let behind_msg = num_blocks_behind.map(|n| n.to_string()).unwrap_or("unknown".to_string()); debug!("Block sync state changed to \"syncing\". We are {behind_msg} blocks behind."); } + SyncStatus::Unsynced => { + debug!("Block sync state changed to \"unsynced\". Connect more peers to resume block sync."); + } } - self.is_synced = new_sync_val; - // Update the `IS_SYNCED` metric. #[cfg(feature = "metrics")] - metrics::gauge(metrics::bft::IS_SYNCED, new_sync_val); + metrics::gauge(metrics::bft::IS_SYNCED, self.status == SyncStatus::Synced); } }