diff --git a/Cargo.lock b/Cargo.lock index fd5dc32b093..fb03b941466 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", "once_cell", @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" dependencies = [ "anstyle", "anstyle-parse", @@ -115,9 +115,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "arrayref" @@ -179,18 +179,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -296,9 +296,9 @@ checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -353,13 +353,13 @@ dependencies = [ "lazycell", "log", "peeking_take_while", - "prettyplease 0.2.15", + "prettyplease 0.2.16", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.41", + "syn 2.0.48", "which", ] @@ -401,9 +401,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 = "bitvec" @@ -462,9 +462,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.2.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9897ef0f1bd2362169de6d7e436ea2237dc1085d7d1e4db75f4be34d86f309d1" +checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" dependencies = [ "borsh-derive", "cfg_aliases", @@ -472,15 +472,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.2.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478b41ff04256c5c8330f3dfdaaae2a5cc976a8e75088bafa4625b0d0208de8c" +checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" dependencies = [ "once_cell", - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "syn_derive", ] @@ -570,9 +570,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" +checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" dependencies = [ "serde", ] @@ -629,9 +629,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "41daef31d7a747c5c847246f36de49ced6f7403b4cdabc807a97b5cc184cda7a" dependencies = [ "android-tzdata", "iana-time-zone", @@ -639,7 +639,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -668,9 +668,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", @@ -690,9 +690,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.11" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -700,9 +700,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -719,7 +719,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -790,9 +790,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -817,7 +817,7 @@ dependencies = [ "clap 2.34.0", "criterion-plot", "csv", - "itertools", + "itertools 0.10.5", "lazy_static", "num-traits", "oorandom", @@ -839,50 +839,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] name = "crossbeam-channel" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", ] [[package]] name = "crossbeam-utils" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -940,7 +932,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -952,7 +944,7 @@ dependencies = [ "prost 0.11.9", "serde", "serde_bytes", - "tenderdash-proto 0.14.0-dev.1 (git+https://github.com/dashpay/rs-tenderdash-abci)", + "tenderdash-proto", "tonic", "tonic-build", ] @@ -964,7 +956,7 @@ dependencies = [ "dapi-grpc", "heck", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -988,7 +980,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -999,7 +991,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1026,11 +1018,11 @@ source = "git+https://github.com/dashpay/rust-dashcore?branch=master#35a166e7625 [[package]] name = "dashcore-rpc" version = "0.15.1" -source = "git+https://github.com/dashpay/rust-dashcore-rpc?branch=master#016e3af953fe92e0e58a8fe2b3958334e318b6c0" +source = "git+https://github.com/dashpay/rust-dashcore-rpc?branch=master#d7df63efcd59815bb9a5bbc05d6c82dfc24df2c6" dependencies = [ "dashcore-private", "dashcore-rpc-json", - "env_logger 0.10.1", + "env_logger 0.10.2", "hex", "jsonrpc", "log", @@ -1041,7 +1033,7 @@ dependencies = [ [[package]] name = "dashcore-rpc-json" version = "0.15.1" -source = "git+https://github.com/dashpay/rust-dashcore-rpc?branch=master#016e3af953fe92e0e58a8fe2b3958334e318b6c0" +source = "git+https://github.com/dashpay/rust-dashcore-rpc?branch=master#d7df63efcd59815bb9a5bbc05d6c82dfc24df2c6" dependencies = [ "bincode 2.0.0-rc.3", "dashcore", @@ -1107,9 +1099,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", "serde", @@ -1193,7 +1185,7 @@ dependencies = [ "hex", "indexmap 2.1.0", "integer-encoding 4.0.0", - "itertools", + "itertools 0.10.5", "json-patch", "jsonptr", "jsonschema", @@ -1225,7 +1217,7 @@ name = "drive" version = "1.0.0-dev.3" dependencies = [ "anyhow", - "base64 0.21.5", + "base64 0.21.7", "bs58 0.5.0", "byteorder", "chrono", @@ -1242,7 +1234,7 @@ dependencies = [ "indexmap 1.9.3", "integer-encoding 4.0.0", "intmap", - "itertools", + "itertools 0.10.5", "moka", "nohash-hasher", "platform-version", @@ -1266,7 +1258,7 @@ dependencies = [ "bytes", "chrono", "ciborium", - "clap 4.4.11", + "clap 4.4.18", "dapi-grpc", "dashcore-rpc", "delegate", @@ -1279,7 +1271,7 @@ dependencies = [ "hex", "indexmap 1.9.3", "integer-encoding 4.0.0", - "itertools", + "itertools 0.10.5", "lazy_static", "metrics", "metrics-exporter-prometheus", @@ -1294,12 +1286,12 @@ dependencies = [ "rust_decimal_macros", "serde", "serde_json", - "serde_with 3.4.0", + "serde_with 3.5.0", "sha2", "simple-signer", "strategy-tests", "tempfile", - "tenderdash-abci 0.14.0-dev.1 (git+https://github.com/dashpay/rs-tenderdash-abci?tag=v0.14.0-dev.2)", + "tenderdash-abci", "thiserror", "tokio", "tokio-util", @@ -1320,7 +1312,7 @@ dependencies = [ "lazy_static", "serde", "serde_json", - "tenderdash-abci 0.14.0-dev.1 (git+https://github.com/dashpay/rs-tenderdash-abci)", + "tenderdash-abci", "thiserror", "tracing", ] @@ -1394,7 +1386,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1412,9 +1404,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -1613,9 +1605,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1628,9 +1620,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -1638,15 +1630,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1655,9 +1647,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -1676,32 +1668,32 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -1727,9 +1719,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -1765,7 +1757,7 @@ dependencies = [ "indexmap 1.9.3", "integer-encoding 3.0.4", "intmap", - "itertools", + "itertools 0.10.5", "nohash-hasher", "serde", "tempfile", @@ -1836,14 +1828,14 @@ version = "1.0.0-rc.2" source = "git+https://github.com/dashpay/grovedb?rev=b40dd1a35f852c81caeda2d3c2910c40fae3a67f#b40dd1a35f852c81caeda2d3c2910c40fae3a67f" dependencies = [ "hex", - "itertools", + "itertools 0.10.5", ] [[package]] name = "h2" -version = "0.3.22" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -1879,7 +1871,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.7", ] [[package]] @@ -1905,9 +1897,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "hex" @@ -1975,9 +1967,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -1990,7 +1982,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.5", "tokio", "tower-service", "tracing", @@ -2011,9 +2003,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2106,7 +2098,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.4", "libc", "windows-sys 0.48.0", ] @@ -2119,13 +2111,13 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ - "hermit-abi 0.3.3", - "rustix 0.38.28", - "windows-sys 0.48.0", + "hermit-abi 0.3.4", + "rustix 0.38.30", + "windows-sys 0.52.0", ] [[package]] @@ -2146,6 +2138,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" @@ -2231,7 +2232,7 @@ source = "git+https://github.com/fominok/jsonschema-rs?branch=feat-unevaluated-p dependencies = [ "ahash 0.7.7", "anyhow", - "base64 0.13.1", + "base64 0.21.7", "bytecount", "fancy-regex", "fraction", @@ -2264,24 +2265,24 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "lhash" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6df04c84bd3f83849dd23c51be4cbb22a02d80ebdea22741558fe30127d837ae" +checksum = "744a4c881f502e98c2241d2e5f50040ac73b30194d64452bb6260393b53f0dc9" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -2302,9 +2303,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" dependencies = [ "cc", "pkg-config", @@ -2319,9 +2320,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -2351,9 +2352,9 @@ dependencies = [ [[package]] name = "mach2" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" dependencies = [ "libc", ] @@ -2383,18 +2384,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "metrics" @@ -2402,7 +2394,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.7", "metrics-macros", "portable-atomic", ] @@ -2413,7 +2405,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "hyper", "indexmap 1.9.3", "ipnet", @@ -2427,13 +2419,13 @@ dependencies = [ [[package]] name = "metrics-macros" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" +checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -2532,7 +2524,7 @@ dependencies = [ "tagptr", "thiserror", "triomphe", - "uuid 1.6.1", + "uuid 1.7.0", ] [[package]] @@ -2622,7 +2614,7 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -2673,7 +2665,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.4", "libc", ] @@ -2700,9 +2692,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] @@ -2805,7 +2797,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -2832,9 +2824,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "platform-serialization" @@ -2850,7 +2842,7 @@ version = "1.0.0-dev.3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "virtue 0.0.14", ] @@ -2880,7 +2872,7 @@ name = "platform-value-convertible" version = "1.0.0-dev.3" dependencies = [ "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -2896,14 +2888,14 @@ version = "1.0.0-dev.3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "platforms" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "plotters" @@ -2975,7 +2967,7 @@ checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "float-cmp", - "itertools", + "itertools 0.10.5", "normalize-line-endings", "predicates-core", "regex", @@ -3019,12 +3011,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -3039,12 +3031,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.21.0", ] [[package]] @@ -3073,9 +3064,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -3108,7 +3099,7 @@ checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", "heck", - "itertools", + "itertools 0.10.5", "lazy_static", "log", "multimap", @@ -3130,16 +3121,16 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck", - "itertools", + "itertools 0.11.0", "log", "multimap", "once_cell", "petgraph", - "prettyplease 0.2.15", + "prettyplease 0.2.16", "prost 0.12.3", "prost-types 0.12.3", "regex", - "syn 2.0.41", + "syn 2.0.48", "tempfile", "which", ] @@ -3151,7 +3142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", @@ -3164,10 +3155,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools", + "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -3237,9 +3228,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -3291,9 +3282,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -3301,9 +3292,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3320,13 +3311,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.4", "regex-syntax 0.8.2", ] @@ -3341,9 +3332,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" dependencies = [ "aho-corasick", "memchr", @@ -3409,7 +3400,7 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid 1.6.1", + "uuid 1.7.0", ] [[package]] @@ -3458,7 +3449,7 @@ name = "rs-sdk" version = "1.0.0-dev.3" dependencies = [ "async-trait", - "base64 0.21.5", + "base64 0.21.7", "bincode 2.0.0-rc.3", "ciborium", "dapi-grpc", @@ -3558,14 +3549,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.13", "windows-sys 0.52.0", ] @@ -3599,7 +3590,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", ] [[package]] @@ -3635,11 +3626,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3719,18 +3710,18 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] @@ -3747,9 +3738,9 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] @@ -3766,20 +3757,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "indexmap 2.1.0", "itoa", @@ -3789,13 +3780,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -3816,16 +3807,16 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "f58c3a1b3e418f61c25b2aeb43fc6c95eaa252b8cecdda67f401943e9e08d33f" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "chrono", "hex", "serde", "serde_json", - "serde_with_macros 3.4.0", + "serde_with_macros 3.5.0", "time", ] @@ -3838,19 +3829,19 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "d2068b437a31fc68f25dd7edc296b078f04b45145c199d8eed9866e45f1ff274" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -3875,9 +3866,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" @@ -3945,9 +3936,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" @@ -4065,9 +4056,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.41" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -4083,7 +4074,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4118,42 +4109,21 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", "fastrand 2.0.1", "redox_syscall", - "rustix 0.38.28", - "windows-sys 0.48.0", -] - -[[package]] -name = "tenderdash-abci" -version = "0.14.0-dev.1" -source = "git+https://github.com/dashpay/rs-tenderdash-abci?tag=v0.14.0-dev.2#6ebfaa31052f7ad538d6589323e5daf7e5e55999" -dependencies = [ - "bytes", - "futures", - "hex", - "lhash", - "prost 0.12.3", - "semver", - "tenderdash-proto 0.14.0-dev.1 (git+https://github.com/dashpay/rs-tenderdash-abci?tag=v0.14.0-dev.2)", - "thiserror", - "tokio", - "tokio-util", - "tracing", - "tracing-subscriber", - "url", - "uuid 1.6.1", + "rustix 0.38.30", + "windows-sys 0.52.0", ] [[package]] name = "tenderdash-abci" -version = "0.14.0-dev.1" -source = "git+https://github.com/dashpay/rs-tenderdash-abci#b4df6543efb0457a477db30153131495da1b8bbb" +version = "0.14.0-dev.5" +source = "git+https://github.com/dashpay/rs-tenderdash-abci?tag=v0.14.0-dev.5#556f3a9b6724bdbe44acf8045cd87144a997bccb" dependencies = [ "bytes", "futures", @@ -4161,20 +4131,20 @@ dependencies = [ "lhash", "prost 0.12.3", "semver", - "tenderdash-proto 0.14.0-dev.1 (git+https://github.com/dashpay/rs-tenderdash-abci)", + "tenderdash-proto", "thiserror", "tokio", "tokio-util", "tracing", "tracing-subscriber", "url", - "uuid 1.6.1", + "uuid 1.7.0", ] [[package]] name = "tenderdash-proto" -version = "0.14.0-dev.1" -source = "git+https://github.com/dashpay/rs-tenderdash-abci?tag=v0.14.0-dev.2#6ebfaa31052f7ad538d6589323e5daf7e5e55999" +version = "0.14.0-dev.5" +source = "git+https://github.com/dashpay/rs-tenderdash-abci?tag=v0.14.0-dev.5#556f3a9b6724bdbe44acf8045cd87144a997bccb" dependencies = [ "bytes", "chrono", @@ -4185,46 +4155,14 @@ dependencies = [ "prost 0.12.3", "serde", "subtle-encoding", - "tenderdash-proto-compiler 0.14.0-dev.1 (git+https://github.com/dashpay/rs-tenderdash-abci?tag=v0.14.0-dev.2)", + "tenderdash-proto-compiler", "time", ] -[[package]] -name = "tenderdash-proto" -version = "0.14.0-dev.1" -source = "git+https://github.com/dashpay/rs-tenderdash-abci#b4df6543efb0457a477db30153131495da1b8bbb" -dependencies = [ - "bytes", - "chrono", - "derive_more", - "flex-error", - "num-derive", - "num-traits", - "prost 0.12.3", - "serde", - "subtle-encoding", - "tenderdash-proto-compiler 0.14.0-dev.1 (git+https://github.com/dashpay/rs-tenderdash-abci)", - "time", -] - -[[package]] -name = "tenderdash-proto-compiler" -version = "0.14.0-dev.1" -source = "git+https://github.com/dashpay/rs-tenderdash-abci?tag=v0.14.0-dev.2#6ebfaa31052f7ad538d6589323e5daf7e5e55999" -dependencies = [ - "fs_extra", - "prost-build 0.12.3", - "regex", - "tempfile", - "ureq", - "walkdir", - "zip", -] - [[package]] name = "tenderdash-proto-compiler" -version = "0.14.0-dev.1" -source = "git+https://github.com/dashpay/rs-tenderdash-abci#b4df6543efb0457a477db30153131495da1b8bbb" +version = "0.14.0-dev.5" +source = "git+https://github.com/dashpay/rs-tenderdash-abci?tag=v0.14.0-dev.5#556f3a9b6724bdbe44acf8045cd87144a997bccb" dependencies = [ "fs_extra", "prost-build 0.12.3", @@ -4237,9 +4175,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -4283,22 +4221,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.51" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.51" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4313,9 +4251,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ "deranged", "itoa", @@ -4333,9 +4271,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" dependencies = [ "time-core", ] @@ -4367,9 +4305,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -4402,7 +4340,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4455,9 +4393,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" [[package]] name = "toml_edit" @@ -4472,9 +4410,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap 2.1.0", "toml_datetime", @@ -4490,7 +4428,7 @@ dependencies = [ "async-stream", "async-trait", "axum", - "base64 0.21.5", + "base64 0.21.7", "bytes", "futures-core", "futures-util", @@ -4577,7 +4515,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4676,9 +4614,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -4731,7 +4669,7 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "flate2", "log", "once_cell", @@ -4766,9 +4704,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ "getrandom", "rand", @@ -4856,7 +4794,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -4890,7 +4828,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4909,7 +4847,7 @@ dependencies = [ "async-trait", "dpp", "hex", - "itertools", + "itertools 0.10.5", "js-sys", "log", "num_enum", @@ -4959,7 +4897,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.28", + "rustix 0.38.30", ] [[package]] @@ -4995,11 +4933,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -5136,9 +5074,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.28" +version = "0.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" dependencies = [ "memchr", ] @@ -5171,22 +5109,22 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zerocopy" -version = "0.7.31" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.31" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] diff --git a/Dockerfile b/Dockerfile index 756e0ae73bb..497877cd49d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -236,7 +236,7 @@ RUN mkdir -p /var/log/dash \ /var/lib/dash/rs-drive-abci/db COPY --from=build-drive-abci /artifacts/drive-abci /usr/bin/drive-abci -COPY --from=build-drive-abci /platform/packages/rs-drive-abci/.env.example /var/lib/dash/rs-drive-abci/.env +COPY --from=build-drive-abci /platform/packages/rs-drive-abci/.env.mainnet /var/lib/dash/rs-drive-abci/.env # Create a volume VOLUME /var/lib/dash/rs-drive-abci/db diff --git a/packages/dapi-grpc/Cargo.toml b/packages/dapi-grpc/Cargo.toml index 0b07aa24268..5936b3fce84 100644 --- a/packages/dapi-grpc/Cargo.toml +++ b/packages/dapi-grpc/Cargo.toml @@ -30,7 +30,7 @@ tonic = { version = "0.9.2", features = [ ], default-features = false } serde = { version = "1.0.171", optional = true, features = ["derive"] } serde_bytes = { version = "0.11.12", optional = true } -tenderdash-proto = { git = "https://github.com/dashpay/rs-tenderdash-abci" } +tenderdash-proto = { git = "https://github.com/dashpay/rs-tenderdash-abci", tag = "v0.14.0-dev.5" } dapi-grpc-macros = { path = "../rs-dapi-grpc-macros" } platform-version = { path = "../rs-platform-version" } diff --git a/packages/dashmate/configs/defaults/getBaseConfigFactory.js b/packages/dashmate/configs/defaults/getBaseConfigFactory.js index 2339a592cd5..e7d67da2552 100644 --- a/packages/dashmate/configs/defaults/getBaseConfigFactory.js +++ b/packages/dashmate/configs/defaults/getBaseConfigFactory.js @@ -168,6 +168,11 @@ export default function getBaseConfigFactory(homeDir) { validatorSet: { llmqType: 4, }, + chainLock: { + llmqType: 2, + dkgInterval: 288, + llmqSize: 400, + }, epochTime: 788400, }, tenderdash: { diff --git a/packages/dashmate/configs/defaults/getLocalConfigFactory.js b/packages/dashmate/configs/defaults/getLocalConfigFactory.js index 56b87efabc3..b5462511965 100644 --- a/packages/dashmate/configs/defaults/getLocalConfigFactory.js +++ b/packages/dashmate/configs/defaults/getLocalConfigFactory.js @@ -68,6 +68,11 @@ export default function getLocalConfigFactory(getBaseConfig) { validatorSet: { llmqType: 106, }, + chainLock: { + llmqType: 100, + dkgInterval: 24, + llmqSize: 3, + }, }, }, }, diff --git a/packages/dashmate/configs/defaults/getTestnetConfigFactory.js b/packages/dashmate/configs/defaults/getTestnetConfigFactory.js index 7ea6d6f3f3f..83bdb95383c 100644 --- a/packages/dashmate/configs/defaults/getTestnetConfigFactory.js +++ b/packages/dashmate/configs/defaults/getTestnetConfigFactory.js @@ -53,6 +53,11 @@ export default function getTestnetConfigFactory(homeDir, getBaseConfig) { validatorSet: { llmqType: 6, }, + chainLock: { + llmqType: 1, + dkgInterval: 24, + llmqSize: 50, + }, }, tenderdash: { p2p: { diff --git a/packages/dashmate/configs/getConfigFileMigrationsFactory.js b/packages/dashmate/configs/getConfigFileMigrationsFactory.js index e13d4acc19d..b68d792c31b 100644 --- a/packages/dashmate/configs/getConfigFileMigrationsFactory.js +++ b/packages/dashmate/configs/getConfigFileMigrationsFactory.js @@ -413,6 +413,15 @@ export default function getConfigFileMigrationsFactory(homeDir, defaultConfigs) options.platform.drive.tenderdash.genesis = defaultConfigs.get(name).get('platform.drive.tenderdash.genesis'); } options.platform.dapi.api.docker.deploy = base.get('platform.dapi.api.docker.deploy'); + + let baseConfigName = name; + if (options.group !== null && defaultConfigs.has(options.group)) { + baseConfigName = options.group; + } else if (!defaultConfigs.has(baseConfigName)) { + baseConfigName = 'testnet'; + } + + options.platform.drive.abci.chainLock = defaultConfigs.get(baseConfigName).get('platform.drive.abci.chainLock'); }); return configFile; diff --git a/packages/dashmate/docker-compose.yml b/packages/dashmate/docker-compose.yml index 5dcdba9f8fb..d5edfc86ffe 100644 --- a/packages/dashmate/docker-compose.yml +++ b/packages/dashmate/docker-compose.yml @@ -47,14 +47,11 @@ services: volumes: - drive_abci_data:/var/lib/dash/rs-drive-abci/db environment: - - BLOCK_SPACING_MS=3000 # TODO: sync with tenderdash - CHAIN_ID=${PLATFORM_DRIVE_TENDERDASH_GENESIS_CHAIN_ID:-devnet} - CORE_JSON_RPC_USERNAME=${CORE_RPC_USER:?err} - CORE_JSON_RPC_PASSWORD=${CORE_RPC_PASSWORD:?err} - CORE_JSON_RPC_HOST=core - CORE_JSON_RPC_PORT=${CORE_RPC_PORT:?err} - - CORE_ZMQ_HOST=core - - CORE_ZMQ_PORT=29998 - DPNS_MASTER_PUBLIC_KEY=${PLATFORM_DPNS_MASTER_PUBLIC_KEY} - DPNS_SECOND_PUBLIC_KEY=${PLATFORM_DPNS_SECOND_PUBLIC_KEY} - DASHPAY_MASTER_PUBLIC_KEY=${PLATFORM_DASHPAY_MASTER_PUBLIC_KEY} @@ -66,10 +63,10 @@ services: - MASTERNODE_REWARD_SHARES_SECOND_PUBLIC_KEY=${PLATFORM_MASTERNODE_REWARD_SHARES_SECOND_PUBLIC_KEY} - WITHDRAWALS_MASTER_PUBLIC_KEY=${PLATFORM_WITHDRAWALS_MASTER_PUBLIC_KEY} - WITHDRAWALS_SECOND_PUBLIC_KEY=${PLATFORM_WITHDRAWALS_SECOND_PUBLIC_KEY} - - QUORUM_SIZE=5 # TODO: sync with Tenderdash - - QUORUM_TYPE=${PLATFORM_DRIVE_ABCI_VALIDATOR_SET_LLMQ_TYPE:?err} - - NETWORK=${NETWORK:?err} - - TENDERDASH_P2P_PORT=${PLATFORM_DRIVE_TENDERDASH_P2P_PORT:?err} + - VALIDATOR_SET_QUORUM_TYPE=${PLATFORM_DRIVE_ABCI_VALIDATOR_SET_LLMQ_TYPE:?err} + - CHAIN_LOCK_QUORUM_TYPE=${PLATFORM_DRIVE_ABCI_CHAIN_LOCK_LLMQ_TYPE:?err} + - CHAIN_LOCK_QUORUM_WINDOW=${PLATFORM_DRIVE_ABCI_CHAIN_LOCK_DKG_INTERVAL:?err} + - CHAIN_LOCK_QUORUM_SIZE=${PLATFORM_DRIVE_ABCI_CHAIN_LOCK_LLMQ_SIZE:?err} stop_grace_period: 30s env_file: # Logger settings diff --git a/packages/dashmate/src/config/configJsonSchema.js b/packages/dashmate/src/config/configJsonSchema.js index 90d2b9fe0c7..3892fc6fe0b 100644 --- a/packages/dashmate/src/config/configJsonSchema.js +++ b/packages/dashmate/src/config/configJsonSchema.js @@ -525,13 +525,33 @@ export default { additionalProperties: false, required: ['llmqType'], }, + chainLock: { + type: 'object', + properties: { + llmqType: { + type: 'number', + // https://github.com/dashpay/dashcore-lib/blob/843176fed9fc81feae43ccf319d99e2dd942fe1f/lib/constants/index.js#L50-L99 + enum: [1, 2, 3, 4, 5, 6, 100, 101, 102, 103, 104, 105, 106, 107], + }, + llmqSize: { + type: 'integer', + minimum: 0, + }, + dkgInterval: { + type: 'integer', + minimum: 0, + }, + }, + additionalProperties: false, + required: ['llmqType', 'llmqSize', 'dkgInterval'], + }, epochTime: { type: 'integer', minimum: 180, }, }, additionalProperties: false, - required: ['docker', 'logs', 'validatorSet', 'epochTime'], + required: ['docker', 'logs', 'validatorSet', 'chainLock', 'epochTime'], }, tenderdash: { type: 'object', diff --git a/packages/rs-drive-abci/.env.local b/packages/rs-drive-abci/.env.local new file mode 100644 index 00000000000..c131e8c2401 --- /dev/null +++ b/packages/rs-drive-abci/.env.local @@ -0,0 +1,63 @@ +# ABCI host and port to listen +ABCI_BIND_ADDRESS="tcp://0.0.0.0:26658" +ABCI_PROMETHEUS_BIND_ADDRESS="http://0.0.0.0:29090" + +# stderr logging for humans +ABCI_LOG_STDOUT_DESTINATION=stdout +ABCI_LOG_STDOUT_LEVEL=info +ABCI_LOG_STDOUT_FORMAT=pretty +ABCI_LOG_STDOUT_COLOR=true + +DB_PATH=/tmp/db + +# Cache size for Data Contracts +DATA_CONTRACTS_GLOBAL_CACHE_SIZE=500 +DATA_CONTRACTS_BLOCK_CACHE_SIZE=200 + +# DashCore JSON-RPC host, port and credentials +# Read more: https://dashcore.readme.io/docs/core-api-ref-remote-procedure-calls +CORE_JSON_RPC_HOST=127.0.0.1 +CORE_JSON_RPC_PORT=9998 +CORE_JSON_RPC_USERNAME=dashrpc +CORE_JSON_RPC_PASSWORD=password + +INITIAL_CORE_CHAINLOCKED_HEIGHT=1243 + +# https://github.com/dashevo/dashcore-lib/blob/286c33a9d29d33f05d874c47a9b33764a0be0cf1/lib/constants/index.js#L42-L57 +VALIDATOR_SET_QUORUM_TYPE=llmq_test +VALIDATOR_SET_QUORUM_SIZE=3 +VALIDATOR_SET_ROTATION_BLOCK_COUNT=64 + +CHAIN_LOCK_QUORUM_TYPE=llmq_test +CHAIN_LOCK_QUORUM_WINDOW=24 +CHAIN_LOCK_QUORUM_SIZE=3 + +# DPNS Contract + +DPNS_MASTER_PUBLIC_KEY=02649a81b760e8635dd3a4fad8911388ed09d7c1680558a890180d4edc8bcece7e +DPNS_SECOND_PUBLIC_KEY=03f5ea3ab4bf594c28997eb8f83873532275ac2edd36e586b137ed42d15d510948 + +# Dashpay Contract + +DASHPAY_MASTER_PUBLIC_KEY=022d6d70c9d24d03904713db17fb74c9201801ba0e3aed0f5d91e89df388e94aa6 +DASHPAY_SECOND_PUBLIC_KEY=028c0a26c87b2e7f1aebbbeace9e687d774e037f5b50a6905b5f6fa24495b502cd + +# Feature flags contract + +FEATURE_FLAGS_MASTER_PUBLIC_KEY=034ee04c509083ecd09e76fa53e0b5331b39120c19607cd04c4f167707dbb42302 +FEATURE_FLAGS_SECOND_PUBLIC_KEY=03c755ae1b79dbcc79020aad3ccdfcb142fc6e74f1afc220fca1e275a87aa12cf8 + +# Masternode reward shares contract + +MASTERNODE_REWARD_SHARES_MASTER_PUBLIC_KEY=02099cc210c7b6c7f566099046ddc92615342db326184940bf3811026ea328c85e +MASTERNODE_REWARD_SHARES_SECOND_PUBLIC_KEY=02bf55f97f189895da29824781053140ee66b2bf47760246504fbe502985096af5 + +# Withdrawals contract + +WITHDRAWALS_MASTER_PUBLIC_KEY=027057cdf58628635ef7b75e6b6c90dd996a16929cd68130e16b9328d429e5e03a +WITHDRAWALS_SECOND_PUBLIC_KEY=022084d827fea4823a69aa7c8d3e02fe780eaa0ef1e5e9841af395ba7e40465ab6 + +EPOCH_TIME_LENGTH_S=788400 + +CHAIN_ID=devnet +BLOCK_SPACING_MS=5000 diff --git a/packages/rs-drive-abci/.env.example b/packages/rs-drive-abci/.env.mainnet similarity index 87% rename from packages/rs-drive-abci/.env.example rename to packages/rs-drive-abci/.env.mainnet index 6bde9c76a6b..a6733bc78b6 100644 --- a/packages/rs-drive-abci/.env.example +++ b/packages/rs-drive-abci/.env.mainnet @@ -10,9 +10,6 @@ ABCI_LOG_STDOUT_COLOR=true DB_PATH=/tmp/db -# GroveDB database file -GROVEDB_LATEST_FILE=${DB_PATH}/latest_state - # Cache size for Data Contracts DATA_CONTRACTS_GLOBAL_CACHE_SIZE=500 DATA_CONTRACTS_BLOCK_CACHE_SIZE=200 @@ -29,16 +26,15 @@ CORE_ZMQ_HOST=127.0.0.1 CORE_ZMQ_PORT=29998 CORE_ZMQ_CONNECTION_RETRIES=16 -NETWORK=testnet - INITIAL_CORE_CHAINLOCKED_HEIGHT=1243 # https://github.com/dashevo/dashcore-lib/blob/286c33a9d29d33f05d874c47a9b33764a0be0cf1/lib/constants/index.js#L42-L57 -VALIDATOR_SET_LLMQ_TYPE=100 -VALIDATOR_SET_QUORUM_ROTATION_BLOCK_COUNT=64 +VALIDATOR_SET_LLMQ_TYPE=llmq_100_67 +VALIDATOR_SET_QUORUM_SIZE=100 +VALIDATOR_SET_ROTATION_BLOCK_COUNT=64 -DKG_INTERVAL=24 -MIN_QUORUM_VALID_MEMBERS=3 +CHAIN_LOCK_QUORUM_TYPE=llmq_400_60 +CHAIN_LOCK_QUORUM_WINDOW=288 # DPNS Contract @@ -65,10 +61,7 @@ MASTERNODE_REWARD_SHARES_SECOND_PUBLIC_KEY=02bf55f97f189895da29824781053140ee66b WITHDRAWALS_MASTER_PUBLIC_KEY=027057cdf58628635ef7b75e6b6c90dd996a16929cd68130e16b9328d429e5e03a WITHDRAWALS_SECOND_PUBLIC_KEY=022084d827fea4823a69aa7c8d3e02fe780eaa0ef1e5e9841af395ba7e40465ab6 -TENDERDASH_P2P_PORT=26656 - EPOCH_TIME_LENGTH_S=788400 -QUORUM_SIZE=5 -QUORUM_TYPE=llmq_25_67 + CHAIN_ID=devnet -BLOCK_SPACING_MS=3000 +BLOCK_SPACING_MS=5000 diff --git a/packages/rs-drive-abci/.env.testnet b/packages/rs-drive-abci/.env.testnet new file mode 100644 index 00000000000..202a78efafb --- /dev/null +++ b/packages/rs-drive-abci/.env.testnet @@ -0,0 +1,62 @@ +# ABCI host and port to listen +ABCI_BIND_ADDRESS="tcp://0.0.0.0:26658" +ABCI_PROMETHEUS_BIND_ADDRESS="http://0.0.0.0:29090" + +# stderr logging for humans +ABCI_LOG_STDOUT_DESTINATION=stdout +ABCI_LOG_STDOUT_LEVEL=info +ABCI_LOG_STDOUT_FORMAT=pretty +ABCI_LOG_STDOUT_COLOR=true + +DB_PATH=/tmp/db + +# Cache size for Data Contracts +DATA_CONTRACTS_GLOBAL_CACHE_SIZE=500 +DATA_CONTRACTS_BLOCK_CACHE_SIZE=200 + +# DashCore JSON-RPC host, port and credentials +# Read more: https://dashcore.readme.io/docs/core-api-ref-remote-procedure-calls +CORE_JSON_RPC_HOST=127.0.0.1 +CORE_JSON_RPC_PORT=9998 +CORE_JSON_RPC_USERNAME=dashrpc +CORE_JSON_RPC_PASSWORD=password + +INITIAL_CORE_CHAINLOCKED_HEIGHT=1243 + +# https://github.com/dashevo/dashcore-lib/blob/286c33a9d29d33f05d874c47a9b33764a0be0cf1/lib/constants/index.js#L42-L57 +VALIDATOR_SET_LLMQ_TYPE=llmq_25_67 +VALIDATOR_SET_QUORUM_SIZE=25 +VALIDATOR_SET_ROTATION_BLOCK_COUNT=64 + +CHAIN_LOCK_QUORUM_TYPE=llmq_50_60 +CHAIN_LOCK_QUORUM_WINDOW=24 + +# DPNS Contract + +DPNS_MASTER_PUBLIC_KEY=02649a81b760e8635dd3a4fad8911388ed09d7c1680558a890180d4edc8bcece7e +DPNS_SECOND_PUBLIC_KEY=03f5ea3ab4bf594c28997eb8f83873532275ac2edd36e586b137ed42d15d510948 + +# Dashpay Contract + +DASHPAY_MASTER_PUBLIC_KEY=022d6d70c9d24d03904713db17fb74c9201801ba0e3aed0f5d91e89df388e94aa6 +DASHPAY_SECOND_PUBLIC_KEY=028c0a26c87b2e7f1aebbbeace9e687d774e037f5b50a6905b5f6fa24495b502cd + +# Feature flags contract + +FEATURE_FLAGS_MASTER_PUBLIC_KEY=034ee04c509083ecd09e76fa53e0b5331b39120c19607cd04c4f167707dbb42302 +FEATURE_FLAGS_SECOND_PUBLIC_KEY=03c755ae1b79dbcc79020aad3ccdfcb142fc6e74f1afc220fca1e275a87aa12cf8 + +# Masternode reward shares contract + +MASTERNODE_REWARD_SHARES_MASTER_PUBLIC_KEY=02099cc210c7b6c7f566099046ddc92615342db326184940bf3811026ea328c85e +MASTERNODE_REWARD_SHARES_SECOND_PUBLIC_KEY=02bf55f97f189895da29824781053140ee66b2bf47760246504fbe502985096af5 + +# Withdrawals contract + +WITHDRAWALS_MASTER_PUBLIC_KEY=027057cdf58628635ef7b75e6b6c90dd996a16929cd68130e16b9328d429e5e03a +WITHDRAWALS_SECOND_PUBLIC_KEY=022084d827fea4823a69aa7c8d3e02fe780eaa0ef1e5e9841af395ba7e40465ab6 + +EPOCH_TIME_LENGTH_S=788400 + +CHAIN_ID=devnet +BLOCK_SPACING_MS=5000 diff --git a/packages/rs-drive-abci/Cargo.toml b/packages/rs-drive-abci/Cargo.toml index 9d8657b555e..ea9f1bf5658 100644 --- a/packages/rs-drive-abci/Cargo.toml +++ b/packages/rs-drive-abci/Cargo.toml @@ -58,7 +58,7 @@ tracing-subscriber = { version = "0.3.16", default-features = false, features = "tracing-log", ], optional = false } atty = { version = "0.2.14", optional = false } -tenderdash-abci = { git = "https://github.com/dashpay/rs-tenderdash-abci", tag = "v0.14.0-dev.2" } +tenderdash-abci = { git = "https://github.com/dashpay/rs-tenderdash-abci", tag = "v0.14.0-dev.5" } lazy_static = "1.4.0" itertools = { version = "0.10.5" } file-rotate = { version = "0.7.3" } diff --git a/packages/rs-drive-abci/src/abci/error.rs b/packages/rs-drive-abci/src/abci/error.rs index ce2016900ca..800ee6eaed0 100644 --- a/packages/rs-drive-abci/src/abci/error.rs +++ b/packages/rs-drive-abci/src/abci/error.rs @@ -45,6 +45,14 @@ pub enum AbciError { #[error("bad commit signature: {0}")] BadCommitSignature(String), + /// The chain lock received was invalid + #[error("invalid chain lock: {0}")] + InvalidChainLock(String), + + /// The chain lock received was invalid + #[error("chain lock is for a block not known by core: {0}")] + ChainLockedBlockNotKnownByCore(String), + /// Error returned by Tenderdash-abci library #[error("tenderdash: {0}")] Tenderdash(#[from] tenderdash_abci::Error), diff --git a/packages/rs-drive-abci/src/abci/handler/mod.rs b/packages/rs-drive-abci/src/abci/handler/mod.rs index 2c96f03ad1a..fc935446f65 100644 --- a/packages/rs-drive-abci/src/abci/handler/mod.rs +++ b/packages/rs-drive-abci/src/abci/handler/mod.rs @@ -52,6 +52,7 @@ use tenderdash_abci::proto::abci::{ RequestProcessProposal, RequestQuery, ResponseCheckTx, ResponseFinalizeBlock, ResponseInitChain, ResponsePrepareProposal, ResponseProcessProposal, ResponseQuery, TxRecord, }; +use tenderdash_abci::proto::types::CoreChainLock; use tenderdash_abci::proto::types::VoteExtensionType; use super::AbciError; @@ -95,7 +96,7 @@ where } let state_app_hash = state_guard - .last_block_app_hash() + .last_committed_block_app_hash() .map(|app_hash| app_hash.to_vec()) .unwrap_or_default(); @@ -104,7 +105,7 @@ where let response = proto::ResponseInfo { data: "".to_string(), app_version: latest_platform_version.protocol_version as u64, - last_block_height: state_guard.last_block_height() as i64, + last_block_height: state_guard.last_committed_block_height() as i64, version: env!("CARGO_PKG_VERSION").to_string(), last_block_app_hash: state_app_hash.clone(), }; @@ -115,7 +116,7 @@ where block_version = request.block_version, p2p_version = request.p2p_version, app_hash = hex::encode(state_app_hash), - height = state_guard.last_block_height(), + height = state_guard.last_committed_block_height(), "Handshake with consensus engine", ); @@ -179,9 +180,15 @@ where // propose one // This is done before all else + let state = self.platform.state.read().unwrap(); + + let last_committed_core_height = state.last_committed_core_height(); + let core_chain_lock_update = match self.platform.core_rpc.get_best_chain_lock() { Ok(latest_chain_lock) => { - if request.core_chain_locked_height < latest_chain_lock.core_block_height { + if state.last_committed_block_info().is_none() + || latest_chain_lock.block_height > last_committed_core_height + { Some(latest_chain_lock) } else { None @@ -190,6 +197,8 @@ where Err(_) => None, }; + drop(state); + // Filter out transactions exceeding max_block_size let mut transactions_exceeding_max_block_size = Vec::new(); { @@ -217,10 +226,12 @@ where // todo: find a way to re-enable this without destroying CI tracing::debug!( "propose chain lock update to height {} at block {}", - core_chain_lock_update.core_block_height, + core_chain_lock_update.block_height, request.height ); - block_proposal.core_chain_locked_height = core_chain_lock_update.core_block_height; + block_proposal.core_chain_locked_height = core_chain_lock_update.block_height; + } else { + block_proposal.core_chain_locked_height = last_committed_core_height; } // Prepare transaction @@ -245,7 +256,7 @@ where // Running the proposal executes all the state transitions for the block let run_result = self .platform - .run_block_proposal(block_proposal, transaction)?; + .run_block_proposal(block_proposal, true, transaction)?; if !run_result.is_valid() { // This is a system error, because we are proposing @@ -328,7 +339,11 @@ where tx_results, app_hash: app_hash.to_vec(), tx_records, - core_chain_lock_update, + core_chain_lock_update: core_chain_lock_update.map(|chain_lock| CoreChainLock { + core_block_hash: chain_lock.block_hash.to_byte_array().to_vec(), + core_block_height: chain_lock.block_height, + signature: chain_lock.signature.to_bytes().to_vec(), + }), validator_set_update, // TODO: implement consensus param updates consensus_param_updates: None, @@ -372,7 +387,7 @@ where let mut drop_block_execution_context = false; if let Some(block_execution_context) = block_execution_context_guard.as_mut() { - // We are already in a block + // We are already in a block, or in init chain. // This only makes sense if we were the proposer unless we are at a future round if block_execution_context.block_state_info().round() != (request.round as u32) { // We were not the proposer, and we should process something new @@ -511,20 +526,16 @@ where }; let transaction = transaction_guard.as_ref().unwrap(); - // We can take the core chain lock update here because it won't be used anywhere else - if let Some(_c) = request.core_chain_lock_update.take() { - //todo: if there is a core chain lock update we need to validate it - } - // Running the proposal executes all the state transitions for the block - let run_result = self - .platform - .run_block_proposal((&request).try_into()?, transaction)?; + let run_result = + self.platform + .run_block_proposal((&request).try_into()?, false, transaction)?; if !run_result.is_valid() { // This was an error running this proposal, tell tenderdash that the block isn't valid let response = ResponseProcessProposal { status: proto::response_process_proposal::ProposalStatus::Reject.into(), + app_hash: [0; 32].to_vec(), // we must send 32 bytes ..Default::default() }; @@ -880,7 +891,7 @@ where key: vec![], value: vec![], proof_ops: None, - height: self.platform.state.read().unwrap().height() as i64, + height: self.platform.state.read().unwrap().last_committed_height() as i64, codespace: "".to_string(), }; @@ -916,7 +927,7 @@ where key: vec![], value: data, proof_ops: None, - height: self.platform.state.read().unwrap().height() as i64, + height: self.platform.state.read().unwrap().last_committed_height() as i64, codespace: "".to_string(), }; diff --git a/packages/rs-drive-abci/src/config.rs b/packages/rs-drive-abci/src/config.rs index f325924e25f..1667097503d 100644 --- a/packages/rs-drive-abci/src/config.rs +++ b/packages/rs-drive-abci/src/config.rs @@ -76,41 +76,12 @@ impl Default for CoreRpcConfig { } /// Configuration for Dash Core related things -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] #[serde(default)] pub struct CoreConfig { /// Core RPC config #[serde(flatten)] pub rpc: CoreRpcConfig, - - /// DKG interval - pub dkg_interval: String, // String due to https://github.com/softprops/envy/issues/26 - /// Minimum number of valid members to use the quorum - pub min_quorum_valid_members: String, // String due to https://github.com/softprops/envy/issues/26 -} - -impl CoreConfig { - /// return dkg_interval - pub fn dkg_interval(&self) -> u32 { - self.dkg_interval - .parse::() - .expect("DKG_INTERVAL is not an int") - } - /// Returns minimal number of quorum members - pub fn min_quorum_valid_members(&self) -> u32 { - self.min_quorum_valid_members - .parse::() - .expect("MIN_QUORUM_VALID_MEMBERS is not an int") - } -} -impl Default for CoreConfig { - fn default() -> Self { - Self { - dkg_interval: String::from("24"), - min_quorum_valid_members: String::from("3"), - rpc: Default::default(), - } - } } /// Configuration of the execution part of Dash Platform. @@ -128,10 +99,10 @@ pub struct ExecutionConfig { /// How often should quorums change? #[serde( - default = "ExecutionConfig::default_validator_set_quorum_rotation_block_count", + default = "ExecutionConfig::default_validator_set_rotation_block_count", deserialize_with = "from_str_or_number" )] - pub validator_set_quorum_rotation_block_count: u32, + pub validator_set_rotation_block_count: u32, /// How long in seconds should an epoch last /// It might last a lot longer if the chain is halted @@ -190,12 +161,23 @@ pub struct PlatformConfig { pub execution: ExecutionConfig, /// The default quorum type - pub quorum_type: String, + pub validator_set_quorum_type: String, + + /// The quorum type used for verifying chain locks + pub chain_lock_quorum_type: String, + + /// The validator set quorum size + pub validator_set_quorum_size: u16, - /// The default quorum size - pub quorum_size: u16, + /// The chain lock quorum size + pub chain_lock_quorum_size: u16, - // todo: this should probably be coming from Tenderdash config + /// The window for chain locks + /// On Mainnet Chain Locks are signed using 400_60: One quorum in every 288 blocks and activeQuorumCount is 4. + /// On Testnet Chain Locks are signed using 50_60: One quorum in every 24 blocks and activeQuorumCount is 24. + pub chain_lock_quorum_window: u32, + + // todo: this should probably be coming from Tenderdash config. It's a test only param /// Approximately how often are blocks produced pub block_spacing_ms: u64, @@ -221,7 +203,7 @@ impl ExecutionConfig { true } - fn default_validator_set_quorum_rotation_block_count() -> u32 { + fn default_validator_set_rotation_block_count() -> u32 { 15 } @@ -237,15 +219,36 @@ impl PlatformConfig { } /// Return type of quorum - pub fn quorum_type(&self) -> QuorumType { - let found = if let Ok(t) = self.quorum_type.trim().parse::() { + pub fn validator_set_quorum_type(&self) -> QuorumType { + let found = if let Ok(t) = self.validator_set_quorum_type.trim().parse::() { QuorumType::from(t) } else { - QuorumType::from(self.quorum_type.as_str()) + QuorumType::from(self.validator_set_quorum_type.as_str()) }; if found == QuorumType::UNKNOWN { - panic!("config: unsupported QUORUM_TYPE: {}", self.quorum_type); + panic!( + "config: unsupported QUORUM_TYPE: {}", + self.validator_set_quorum_type + ); + } + + found + } + + /// Return type of quorum for validating chain locks + pub fn chain_lock_quorum_type(&self) -> QuorumType { + let found = if let Ok(t) = self.chain_lock_quorum_type.trim().parse::() { + QuorumType::from(t) + } else { + QuorumType::from(self.chain_lock_quorum_type.as_str()) + }; + + if found == QuorumType::UNKNOWN { + panic!( + "config: unsupported QUORUM_TYPE: {}", + self.chain_lock_quorum_type + ); } found @@ -279,8 +282,8 @@ impl Default for ExecutionConfig { Self { use_document_triggers: ExecutionConfig::default_use_document_triggers(), verify_sum_trees: ExecutionConfig::default_verify_sum_trees(), - validator_set_quorum_rotation_block_count: - ExecutionConfig::default_validator_set_quorum_rotation_block_count(), + validator_set_rotation_block_count: + ExecutionConfig::default_validator_set_rotation_block_count(), epoch_time_length_s: ExecutionConfig::default_epoch_time_length_s(), } } @@ -288,9 +291,55 @@ impl Default for ExecutionConfig { impl Default for PlatformConfig { fn default() -> Self { + Self::default_mainnet() + } +} + +#[allow(missing_docs)] +impl PlatformConfig { + pub fn default_local() -> Self { + Self { + validator_set_quorum_type: "llmq_test_platform".to_string(), + chain_lock_quorum_type: "llmq_test".to_string(), + validator_set_quorum_size: 3, + chain_lock_quorum_size: 3, + chain_lock_quorum_window: 24, + block_spacing_ms: 5000, + drive: Default::default(), + abci: Default::default(), + core: Default::default(), + execution: Default::default(), + db_path: PathBuf::from("/var/lib/dash-platform/data"), + testing_configs: PlatformTestConfig::default(), + initial_protocol_version: 1, + } + } + + pub fn default_testnet() -> Self { + Self { + validator_set_quorum_type: "llmq_25_67".to_string(), + chain_lock_quorum_type: "llmq_50_60".to_string(), + validator_set_quorum_size: 25, + chain_lock_quorum_size: 50, + chain_lock_quorum_window: 24, + block_spacing_ms: 5000, + drive: Default::default(), + abci: Default::default(), + core: Default::default(), + execution: Default::default(), + db_path: PathBuf::from("/var/lib/dash-platform/data"), + testing_configs: PlatformTestConfig::default(), + initial_protocol_version: 1, + } + } + + pub fn default_mainnet() -> Self { Self { - quorum_type: "llmq_100_67".to_string(), - quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_400_60".to_string(), + validator_set_quorum_size: 100, + chain_lock_quorum_size: 400, + chain_lock_quorum_window: 288, block_spacing_ms: 5000, drive: Default::default(), abci: Default::default(), @@ -341,7 +390,7 @@ mod tests { #[test] fn test_config_from_env() { // ABCI log configs are parsed manually, so they deserve separate handling - // Notat that STDOUT is also defined in .env.example, but env var should overwrite it. + // Note that STDOUT is also defined in .env.example, but env var should overwrite it. let vectors = &[ ("STDOUT", "pretty"), ("UPPERCASE", "json"), @@ -354,14 +403,14 @@ mod tests { env::set_var(format!("ABCI_LOG_{}_FORMAT", vector.0), vector.1); } - let envfile = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".env.example"); + let envfile = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".env.local"); dotenvy::from_path(envfile.as_path()).expect("cannot load .env file"); - assert_eq!("5", env::var("QUORUM_SIZE").unwrap()); + assert_eq!("/tmp/db", env::var("DB_PATH").unwrap()); let config = super::PlatformConfig::from_env().expect("expected config from env"); assert!(config.execution.verify_sum_trees); - assert_ne!(config.quorum_type(), QuorumType::UNKNOWN); + assert_ne!(config.validator_set_quorum_type(), QuorumType::UNKNOWN); for id in vectors { matches!(config.abci.log[id.0].destination, LogDestination::Bytes); } diff --git a/packages/rs-drive-abci/src/core/wait_for_core_to_sync/v0/mod.rs b/packages/rs-drive-abci/src/core/wait_for_core_to_sync/v0/mod.rs index 47e8dbbc8dd..d1f79b1e55d 100644 --- a/packages/rs-drive-abci/src/core/wait_for_core_to_sync/v0/mod.rs +++ b/packages/rs-drive-abci/src/core/wait_for_core_to_sync/v0/mod.rs @@ -17,6 +17,14 @@ pub fn wait_for_core_to_sync_v0( tracing::info!(?core_rpc, "waiting for core rpc to start"); while !cancel.is_cancelled() { + let has_chain_locked = match core_rpc.get_best_chain_lock() { + Ok(_) => true, + Err(error) => { + tracing::warn!(?error, "cannot get best chain lock"); + false + } + }; + let mn_sync_status = match core_rpc.masternode_sync_status() { Ok(status) => status, Err(error) => { @@ -25,7 +33,7 @@ pub fn wait_for_core_to_sync_v0( } }; - if !mn_sync_status.is_synced || !mn_sync_status.is_blockchain_synced { + if !has_chain_locked || !mn_sync_status.is_synced || !mn_sync_status.is_blockchain_synced { std::thread::sleep(CORE_SYNC_STATUS_CHECK_TIMEOUT); tracing::info!("waiting for core to sync..."); diff --git a/packages/rs-drive-abci/src/error/mod.rs b/packages/rs-drive-abci/src/error/mod.rs index 3658a8169dc..27300dc32cd 100644 --- a/packages/rs-drive-abci/src/error/mod.rs +++ b/packages/rs-drive-abci/src/error/mod.rs @@ -3,6 +3,7 @@ use crate::error::execution::ExecutionError; use crate::error::serialization::SerializationError; use crate::logging; use dashcore_rpc::Error as CoreRpcError; +use dpp::bls_signatures::BlsError; use dpp::platform_value::Error as ValueError; use dpp::version::PlatformVersionError; use drive::dpp::ProtocolError; @@ -36,6 +37,9 @@ pub enum Error { /// Core RPC Error #[error("core rpc error: {0}")] CoreRpc(#[from] CoreRpcError), + /// BLS Error + #[error("BLS error: {0}")] + BLSError(#[from] BlsError), /// Serialization Error #[error("serialization: {0}")] Serialization(#[from] SerializationError), diff --git a/packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs b/packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs index 7c0cf75f7a6..51b6db63523 100644 --- a/packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs @@ -150,7 +150,7 @@ where { // Verify commit - let quorum_type = self.config.quorum_type(); + let quorum_type = self.config.validator_set_quorum_type(); let commit = Commit::new_from_cleaned( commit_info.clone(), block_id, diff --git a/packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs b/packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs index 01b951d49e1..aee3c50528a 100644 --- a/packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs +++ b/packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs @@ -23,6 +23,7 @@ where /// # Arguments /// /// * `block_proposal` - The block proposal to be processed. + /// * `known_from_us` - Do we know that we made this block proposal? /// * `transaction` - The transaction associated with the block proposal. /// /// # Returns @@ -40,6 +41,7 @@ where pub fn run_block_proposal( &self, block_proposal: block_proposal::v0::BlockProposal, + known_from_us: bool, transaction: &Transaction, ) -> Result, Error> { @@ -57,6 +59,7 @@ where { 0 => self.run_block_proposal_v0( block_proposal, + known_from_us, epoch_info.into(), transaction, platform_version, diff --git a/packages/rs-drive-abci/src/execution/engine/run_block_proposal/v0/mod.rs b/packages/rs-drive-abci/src/execution/engine/run_block_proposal/v0/mod.rs index 2408b92005f..b10494886a9 100644 --- a/packages/rs-drive-abci/src/execution/engine/run_block_proposal/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/engine/run_block_proposal/v0/mod.rs @@ -31,6 +31,7 @@ use crate::platform_types::epoch_info::v0::{EpochInfoV0Getters, EpochInfoV0Metho use crate::platform_types::epoch_info::EpochInfo; use crate::platform_types::platform::Platform; use crate::platform_types::platform_state::v0::PlatformStateV0Methods; +use crate::platform_types::verify_chain_lock_result::v0::VerifyChainLockResult; use crate::rpc::core::CoreRPCLike; impl Platform @@ -46,6 +47,7 @@ where /// # Arguments /// /// * `block_proposal` - The block proposal to be processed. + /// * `known_from_us` - Do we know that we made this block proposal?. /// * `transaction` - The transaction associated with the block proposal. /// /// # Returns @@ -63,6 +65,7 @@ where pub(super) fn run_block_proposal_v0( &self, block_proposal: block_proposal::v0::BlockProposal, + known_from_us: bool, epoch_info: EpochInfo, transaction: &Transaction, platform_version: &PlatformVersion, @@ -80,11 +83,11 @@ where block_proposal.round, ); - let last_block_time_ms = state.last_block_time_ms(); + let last_block_time_ms = state.last_committed_block_time_ms(); let last_block_height = - state.known_height_or(self.config.abci.genesis_height.saturating_sub(1)); + state.last_committed_known_height_or(self.config.abci.genesis_height.saturating_sub(1)); let last_block_core_height = - state.known_core_height_or(self.config.abci.genesis_core_height); + state.last_committed_known_core_height_or(self.config.abci.genesis_core_height); let hpmn_list_len = state.hpmn_list_len(); let mut block_platform_state = state.clone(); @@ -110,6 +113,7 @@ where // destructure the block proposal let block_proposal::v0::BlockProposal { core_chain_locked_height, + core_chain_lock_update, proposed_app_version, proposer_pro_tx_hash, validator_set_quorum_hash, @@ -122,6 +126,90 @@ where .expect("current epoch index should be in range"), ); + // If there is a core chain lock update, we should start by verifying it + if let Some(core_chain_lock_update) = core_chain_lock_update.as_ref() { + if !known_from_us { + let verification_result = self.verify_chain_lock( + block_state_info.round, // the round is to allow us to bypass local verification in case of chain stall + &block_platform_state, + core_chain_lock_update, + true, // if it's not known from us, then we should try submitting it + platform_version, + ); + + let VerifyChainLockResult { + chain_lock_signature_is_deserializable, + found_valid_locally, + found_valid_by_core, + core_is_synced, + } = match verification_result { + Ok(verification_result) => verification_result, + Err(Error::Execution(e)) => { + // This will happen only if an internal version error + return Err(Error::Execution(e)); + } + Err(e) => { + // This will happen only if a core rpc error + return Ok(ValidationResult::new_with_error( + AbciError::InvalidChainLock(e.to_string()).into(), + )); + } + }; + + if !chain_lock_signature_is_deserializable { + return Ok(ValidationResult::new_with_error( + AbciError::InvalidChainLock(format!( + "received a chain lock for height {} that has a signature that can not be deserialized {:?}", + block_info.height, core_chain_lock_update, + )) + .into(), + )); + } + + if let Some(found_valid_locally) = found_valid_locally { + // This means we are able to check if the chain lock is valid + if !found_valid_locally { + // The signature was not valid + return Ok(ValidationResult::new_with_error( + AbciError::InvalidChainLock(format!( + "received a chain lock for height {} that we figured out was invalid based on platform state {:?}", + block_info.height, core_chain_lock_update, + )) + .into(), + )); + } + } + + if let Some(found_valid_by_core) = found_valid_by_core { + // This means we asked core if the chain lock was valid + if !found_valid_by_core { + // Core said it wasn't valid + return Ok(ValidationResult::new_with_error( + AbciError::InvalidChainLock(format!( + "received a chain lock for height {} that is invalid based on a core request {:?}", + block_info.height, core_chain_lock_update, + )) + .into(), + )); + } + } + + if let Some(core_is_synced) = core_is_synced { + // Core is just not synced + if !core_is_synced { + // The submission was not accepted by core + return Ok(ValidationResult::new_with_error( + AbciError::ChainLockedBlockNotKnownByCore(format!( + "received a chain lock for height {} that we could not accept because core is not synced {:?}", + block_info.height, core_chain_lock_update, + )) + .into(), + )); + } + } + } + } + // Update the masternode list and create masternode identities and also update the active quorums self.update_core_info( Some(&state), diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_end/validator_set_update/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/block_end/validator_set_update/v0/mod.rs index 3a1ead24fb3..27b5fc37147 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_end/validator_set_update/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_end/validator_set_update/v0/mod.rs @@ -27,10 +27,7 @@ where let mut perform_rotation = false; if block_execution_context.block_state_info().height() - % self - .config - .execution - .validator_set_quorum_rotation_block_count as u64 + % self.config.execution.validator_set_rotation_block_count as u64 == 0 { tracing::debug!( diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_core_info/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_core_info/v0/mod.rs index 467af1138b2..912114b1bba 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_core_info/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_core_info/v0/mod.rs @@ -1,5 +1,6 @@ use crate::error::Error; use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::v0::PlatformStateV0Methods; use crate::platform_types::platform_state::PlatformState; use crate::rpc::core::CoreRPCLike; use dpp::block::block_info::BlockInfo; @@ -40,6 +41,12 @@ where transaction: &Transaction, platform_version: &PlatformVersion, ) -> Result<(), Error> { + // the core height of the block platform state is the last committed + if !is_init_chain && block_platform_state.last_committed_core_height() == core_block_height + { + // if we get the same height that we know we do not need to update core info + return Ok(()); + } self.update_masternode_list( platform_state, block_platform_state, @@ -51,6 +58,7 @@ where )?; self.update_quorum_info( + platform_state, block_platform_state, core_block_height, false, diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs index fc0f4c3ea94..b6c447fa75b 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs @@ -90,7 +90,7 @@ where // baseBlock must be a chain height and not 0 None } else { - let state_core_height = state.core_height(); + let state_core_height = state.last_committed_core_height(); if core_block_height == state_core_height { return Ok(update_state_masternode_list_outcome::v0::UpdateStateMasternodeListOutcome::default()); // no need to do anything diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/v0/mod.rs index e9372043b18..f60a9159944 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/v0/mod.rs @@ -40,10 +40,10 @@ where transaction: &Transaction, platform_version: &PlatformVersion, ) -> Result<(), Error> { - if let Some(last_commited_block_info) = + if let Some(last_committed_block_info) = block_platform_state.last_committed_block_info().as_ref() { - if core_block_height == last_commited_block_info.basic_info().core_height { + if core_block_height == last_committed_block_info.basic_info().core_height { tracing::debug!( method = "update_masternode_list_v0", "no update mnl at height {}", @@ -56,7 +56,7 @@ where method = "update_masternode_list_v0", "update mnl to height {} at block {}", core_block_height, - block_platform_state.core_height() + block_platform_state.last_committed_core_height() ); //todo: there's a weird condition that can happen if we are not on init chain, but we are // in the genesis and we are not on round 0, and the core height changed diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_quorum_info/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_quorum_info/mod.rs index 535f5e5ff0c..87510c71171 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_quorum_info/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_quorum_info/mod.rs @@ -26,6 +26,7 @@ where /// on success, or an `Error` on failure. pub(in crate::execution::platform_events::core_based_updates) fn update_quorum_info( &self, + platform_state: Option<&PlatformState>, block_platform_state: &mut PlatformState, core_block_height: u32, start_from_scratch: bool, @@ -38,6 +39,7 @@ where .update_quorum_info { 0 => self.update_quorum_info_v0( + platform_state, block_platform_state, core_block_height, start_from_scratch, diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_quorum_info/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_quorum_info/v0/mod.rs index 24130b279d4..26035b5e200 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_quorum_info/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_quorum_info/v0/mod.rs @@ -9,6 +9,7 @@ use crate::platform_types::validator_set::v0::{ValidatorSetV0, ValidatorSetV0Get use crate::platform_types::validator_set::ValidatorSet; use crate::rpc::core::CoreRPCLike; +use dpp::bls_signatures::PublicKey as BlsPublicKey; use dpp::dashcore::QuorumHash; use tracing::Level; @@ -29,6 +30,7 @@ where /// on success, or an `Error` on failure. pub(super) fn update_quorum_info_v0( &self, + platform_state: Option<&PlatformState>, block_platform_state: &mut PlatformState, core_block_height: u32, start_from_scratch: bool, @@ -37,11 +39,11 @@ where if start_from_scratch { tracing::debug!("update quorum info from scratch up to {core_block_height}"); - } else if core_block_height != block_platform_state.core_height() { + } else if core_block_height != block_platform_state.last_committed_core_height() { tracing::debug!( - previous_core_block_height = block_platform_state.core_height(), + previous_core_block_height = block_platform_state.last_committed_core_height(), "update quorum info from {} to {}", - block_platform_state.core_height(), + block_platform_state.last_committed_core_height(), core_block_height ); } else { @@ -50,39 +52,49 @@ where return Ok(()); // no need to do anything } + // We request the quorum list from the current core block height, this is because we also keep + // the previous chain lock validating quorum. Core will sign from 8 blocks before the current + // core block height, so often we will use the previous chain lock validating quorums instead. + let mut extended_quorum_list = self .core_rpc .get_quorum_listextended(Some(core_block_height))?; + let validator_set_quorum_type = self.config.validator_set_quorum_type(); + let chain_lock_quorum_type = self.config.chain_lock_quorum_type(); + let validator_quorums_list: BTreeMap<_, _> = extended_quorum_list .quorums_by_type - .remove(&self.config.quorum_type()) + .remove(&validator_set_quorum_type) .ok_or(Error::Execution(ExecutionError::DashCoreBadResponseError( format!( "expected quorums of type {}, but did not receive any from Dash Core", - self.config.quorum_type + self.config.validator_set_quorum_type ), )))? .into_iter() .collect(); + let mut removed_a_validator_set = false; + // Remove validator_sets entries that are no longer valid for the core block height block_platform_state .validator_sets_mut() .retain(|quorum_hash, _| { - let has_quorum = validator_quorums_list.contains_key::(quorum_hash); + let retain = validator_quorums_list.contains_key::(quorum_hash); + removed_a_validator_set |= !retain; - if has_quorum { + if !retain { tracing::trace!( ?quorum_hash, - quorum_type = ?self.config.quorum_type(), - "remove validator set {} with quorum type {}", + quorum_type = ?self.config.validator_set_quorum_type(), + "removed validator set {} with quorum type {}", quorum_hash, - self.config.quorum_type() + self.config.validator_set_quorum_type() ) } - has_quorum + retain }); // Fetch quorum info and their keys from the RPC for new quorums @@ -94,9 +106,11 @@ where .contains_key::(key) }) .map(|(key, _)| { - let quorum_info_result = - self.core_rpc - .get_quorum_info(self.config.quorum_type(), key, None)?; + let quorum_info_result = self.core_rpc.get_quorum_info( + self.config.validator_set_quorum_type(), + key, + None, + )?; Ok((*key, quorum_info_result)) }) @@ -124,16 +138,18 @@ where tracing::trace!( ?validator_set, ?quorum_hash, - quorum_type = ?self.config.quorum_type(), + quorum_type = ?self.config.validator_set_quorum_type(), "add new validator set {} with quorum type {}", quorum_hash, - self.config.quorum_type() + self.config.validator_set_quorum_type() ); Ok((quorum_hash, validator_set)) }) .collect::, Error>>()?; + let added_a_validator_set = !new_validator_sets.is_empty(); + // Add new validator_sets entries block_platform_state .validator_sets_mut() @@ -154,6 +170,138 @@ where } }); + if validator_set_quorum_type == chain_lock_quorum_type { + // Remove validator_sets entries that are no longer valid for the core block height + if removed_a_validator_set || added_a_validator_set { + let chain_lock_validating_quorums = block_platform_state + .validator_sets() + .iter() + .map(|(quorum_hash, validator_set)| { + ( + quorum_hash.clone(), + validator_set.threshold_public_key().clone(), + ) + }) + .collect(); + let previous_quorums = block_platform_state + .replace_chain_lock_validating_quorums(chain_lock_validating_quorums); + tracing::trace!("updated chain lock validating quorums to current validator set",); + // the only case where there will be no platform_state is init chain where we + if platform_state.is_some() { + block_platform_state.set_previous_chain_lock_validating_quorums( + block_platform_state.last_committed_core_height(), + core_block_height, + block_platform_state + .previous_height_chain_lock_validating_quorums() + .map(|(_, previous_change_height, _, _)| *previous_change_height), + previous_quorums, + ); + } + } + } else { + let chain_lock_quorums_list: BTreeMap<_, _> = extended_quorum_list + .quorums_by_type + .remove(&chain_lock_quorum_type) + .ok_or(Error::Execution(ExecutionError::DashCoreBadResponseError( + format!( + "expected quorums of type {}, but did not receive any from Dash Core", + self.config.chain_lock_quorum_type + ), + )))? + .into_iter() + .map(|(quorum_hash, extended_quorum_details)| { + (quorum_hash, extended_quorum_details.quorum_index) + }) + .collect(); + + let mut removed_a_chain_lock_validating_quorum = false; + + // Remove chain_lock_validating_quorums entries that are no longer valid for the core block height + block_platform_state + .chain_lock_validating_quorums_mut() + .retain(|quorum_hash, _| { + let retain = chain_lock_quorums_list.contains_key::(quorum_hash); + if !retain { + tracing::trace!( + ?quorum_hash, + quorum_type = ?chain_lock_quorum_type, + "removed old chain lock quorum {} with quorum type {}", + quorum_hash, + chain_lock_quorum_type + ); + } + removed_a_chain_lock_validating_quorum |= !retain; + retain + }); + + // Fetch quorum info and their keys from the RPC for new quorums + let quorum_infos = chain_lock_quorums_list + .iter() + .filter(|(key, _)| { + !block_platform_state + .chain_lock_validating_quorums() + .contains_key::(key) + }) + .map(|(key, _)| { + let quorum_info_result = + self.core_rpc + .get_quorum_info(chain_lock_quorum_type, key, None)?; + + Ok((*key, quorum_info_result)) + }) + .collect::, Error>>()?; + + let added_a_chain_lock_validating_quorum = !quorum_infos.is_empty(); + + if added_a_chain_lock_validating_quorum { + // Map to chain lock validating quorums + let new_chain_lock_quorums = quorum_infos + .into_iter() + .map(|(quorum_hash, info_result)| { + let public_key = match BlsPublicKey::from_bytes( + info_result.quorum_public_key.as_slice(), + ) + .map_err(ExecutionError::BlsErrorFromDashCoreResponse) + { + Ok(public_key) => public_key, + Err(e) => return Err(e.into()), + }; + + tracing::trace!( + ?public_key, + ?quorum_hash, + quorum_type = ?chain_lock_quorum_type, + "add new chain lock quorum {} with quorum type {}", + quorum_hash, + chain_lock_quorum_type + ); + + Ok((quorum_hash, public_key)) + }) + .collect::, Error>>()?; + + // Add new validator_sets entries + block_platform_state + .chain_lock_validating_quorums_mut() + .extend(new_chain_lock_quorums); + } + + if added_a_chain_lock_validating_quorum || removed_a_chain_lock_validating_quorum { + if let Some(old_state) = platform_state { + let previous_chain_lock_validating_quorums = + old_state.chain_lock_validating_quorums().clone(); + block_platform_state.set_previous_chain_lock_validating_quorums( + block_platform_state.last_committed_core_height(), + core_block_height, + block_platform_state + .previous_height_chain_lock_validating_quorums() + .map(|(_, previous_change_height, _, _)| *previous_change_height), + previous_chain_lock_validating_quorums, + ); + } + } + } + Ok(()) } } diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/choose_quorum/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/choose_quorum/mod.rs new file mode 100644 index 00000000000..f939ef727ce --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/choose_quorum/mod.rs @@ -0,0 +1,76 @@ +mod v0; + +use crate::error::execution::ExecutionError; +use crate::error::Error; +use dashcore_rpc::dashcore_rpc_json::QuorumType; +use dpp::bls_signatures::PublicKey as BlsPublicKey; +use dpp::dashcore::{ChainLock, QuorumHash}; +use dpp::platform_value::Bytes32; +use std::collections::BTreeMap; + +use crate::platform_types::platform::Platform; + +use crate::rpc::core::CoreRPCLike; + +use dpp::version::PlatformVersion; + +pub type ReversedQuorumHashBytes = Vec; + +impl Platform +where + C: CoreRPCLike, +{ + /// Based on DIP8 deterministically chooses a pseudorandom quorum from the list of quorums + /// + pub fn choose_quorum<'a>( + llmq_quorum_type: QuorumType, + quorums: &'a BTreeMap, + request_id: &[u8; 32], + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive_abci + .methods + .core_chain_lock + .choose_quorum + { + 0 => Ok(Self::choose_quorum_v0( + llmq_quorum_type, + quorums, + request_id, + )), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "choose_quorum".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Based on DIP8 deterministically chooses a pseudorandom quorum from the list of quorums + /// + pub fn choose_quorum_thread_safe<'a, const T: usize>( + llmq_quorum_type: QuorumType, + quorums: &'a BTreeMap, + request_id: &[u8; 32], + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive_abci + .methods + .core_chain_lock + .choose_quorum + { + 0 => Ok(Self::choose_quorum_thread_safe_v0( + llmq_quorum_type, + quorums, + request_id, + )), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "choose_quorum_thread_safe".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/choose_quorum/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/choose_quorum/v0/mod.rs new file mode 100644 index 00000000000..8fd8156732c --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/choose_quorum/v0/mod.rs @@ -0,0 +1,359 @@ +use dashcore_rpc::dashcore_rpc_json::QuorumType; +use dpp::bls_signatures::PublicKey as BlsPublicKey; +use dpp::dashcore::hashes::{sha256d, Hash, HashEngine}; +use dpp::dashcore::{ChainLock, QuorumHash}; +use std::collections::BTreeMap; + +use crate::platform_types::platform::Platform; + +use crate::rpc::core::CoreRPCLike; + +use crate::execution::platform_events::core_chain_lock::choose_quorum::ReversedQuorumHashBytes; + +impl Platform { + /// Based on DIP8 deterministically chooses a pseudorandom quorum from the list of quorums + pub(super) fn choose_quorum_v0<'a>( + llmq_quorum_type: QuorumType, + quorums: &'a BTreeMap, + request_id: &[u8; 32], + ) -> Option<(ReversedQuorumHashBytes, &'a BlsPublicKey)> { + // Scoring system logic + let mut scores: Vec<(ReversedQuorumHashBytes, &BlsPublicKey, [u8; 32])> = Vec::new(); + + for (quorum_hash, public_key) in quorums { + let mut quorum_hash_bytes = quorum_hash.to_byte_array().to_vec(); + + // Only the quorum hash needs reversal. + quorum_hash_bytes.reverse(); + + let mut hasher = sha256d::Hash::engine(); + + // Serialize and hash the LLMQ type + hasher.input(&[llmq_quorum_type as u8]); + + // Serialize and add the quorum hash + hasher.input(quorum_hash_bytes.as_slice()); + + // Serialize and add the selection hash from the chain lock + hasher.input(request_id.as_slice()); + + // Finalize the hash + let hash_result = sha256d::Hash::from_engine(hasher); + scores.push((quorum_hash_bytes, public_key, hash_result.into())); + } + + if scores.is_empty() { + None + } else { + scores.sort_by_key(|k| k.2); + + let (quorum_hash, key, _) = scores.remove(0); + + Some((quorum_hash, key)) + } + } + + /// Based on DIP8 deterministically chooses a pseudorandom quorum from the list of quorums + pub(super) fn choose_quorum_thread_safe_v0<'a, const T: usize>( + llmq_quorum_type: QuorumType, + quorums: &'a BTreeMap, + request_id: &[u8; 32], + ) -> Option<(ReversedQuorumHashBytes, &'a [u8; T])> { + // Scoring system logic + let mut scores: Vec<(ReversedQuorumHashBytes, &[u8; T], [u8; 32])> = Vec::new(); + + for (quorum_hash, key) in quorums { + let mut quorum_hash_bytes = quorum_hash.to_byte_array().to_vec(); + + // Only the quorum hash needs reversal. + quorum_hash_bytes.reverse(); + + let mut hasher = sha256d::Hash::engine(); + + // Serialize and hash the LLMQ type + hasher.input(&[llmq_quorum_type as u8]); + + // Serialize and add the quorum hash + hasher.input(quorum_hash_bytes.as_slice()); + + // Serialize and add the selection hash from the chain lock + hasher.input(request_id.as_slice()); + + // Finalize the hash + let hash_result = sha256d::Hash::from_engine(hasher); + scores.push((quorum_hash_bytes, key, hash_result.into())); + } + + scores.sort_by_key(|k| k.2); + scores.pop().map(|(hash, key, _)| (hash, key)) + } +} + +#[cfg(test)] +mod tests { + use crate::platform_types::platform::Platform; + use crate::rpc::core::{CoreRPCLike, MockCoreRPCLike}; + use dashcore_rpc::dashcore_rpc_json::QuorumType; + use dpp::bls_signatures::PublicKey as BlsPublicKey; + use dpp::dashcore::hashes::Hash; + use dpp::dashcore::QuorumHash; + use std::collections::BTreeMap; + + #[test] + fn test_choose_quorum() { + // Active quorums: + let quorum_hash1 = QuorumHash::from_slice( + hex::decode("000000dc07d722238a994116c3395c334211d9864ff5b37c3be51d5fdda66223") + .unwrap() + .as_slice(), + ) + .unwrap(); + let quorum_hash2 = QuorumHash::from_slice( + hex::decode("000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071") + .unwrap() + .as_slice(), + ) + .unwrap(); + let quorum_hash3 = QuorumHash::from_slice( + hex::decode("0000006faac9003919a6d5456a0a46ae10db517f572221279f0540b79fd9cf1b") + .unwrap() + .as_slice(), + ) + .unwrap(); + let quorum_hash4 = QuorumHash::from_slice( + hex::decode("0000000e6d15a11825211c943c4a995c44ebb2b0834b7848c2e080b48ca0148e") + .unwrap() + .as_slice(), + ) + .unwrap(); + let quorums = BTreeMap::from([ + (quorum_hash1, BlsPublicKey::generate()), + (quorum_hash2, BlsPublicKey::generate()), + (quorum_hash3, BlsPublicKey::generate()), + (quorum_hash4, BlsPublicKey::generate()), + ]); + + // + // ############### + // llmqType[1] requestID[bdcf9fb3ef01209a09db19170a1950775afb5f824c5f0662b9cdae2bf3bb36d5] -> 0000000e6d15a11825211c943c4a995c44ebb2b0834b7848c2e080b48ca0148e + // llmqType[4] requestID[bdcf9fb3ef01209a09db19170a1950775afb5f824c5f0662b9cdae2bf3bb36d5] -> 000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071 + // llmqType[5] requestID[bdcf9fb3ef01209a09db19170a1950775afb5f824c5f0662b9cdae2bf3bb36d5] -> 000000dc07d722238a994116c3395c334211d9864ff5b37c3be51d5fdda66223 + // llmqType[100] requestID[bdcf9fb3ef01209a09db19170a1950775afb5f824c5f0662b9cdae2bf3bb36d5] -> 0000000e6d15a11825211c943c4a995c44ebb2b0834b7848c2e080b48ca0148e + + let mut request_id: [u8; 32] = + hex::decode("bdcf9fb3ef01209a09db19170a1950775afb5f824c5f0662b9cdae2bf3bb36d5") + .unwrap() + .try_into() + .unwrap(); + + request_id.reverse(); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::Llmq50_60, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "0000000e6d15a11825211c943c4a995c44ebb2b0834b7848c2e080b48ca0148e" + ); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::Llmq100_67, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071" + ); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::Llmq60_75, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "000000dc07d722238a994116c3395c334211d9864ff5b37c3be51d5fdda66223" + ); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::LlmqTest, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "0000000e6d15a11825211c943c4a995c44ebb2b0834b7848c2e080b48ca0148e" + ); + + // ############### + // llmqType[1] requestID[b06aa45eb35423f988e36c022967b4c02bb719b037717df13fa57c0f503d8a20] -> 0000000e6d15a11825211c943c4a995c44ebb2b0834b7848c2e080b48ca0148e + // llmqType[4] requestID[b06aa45eb35423f988e36c022967b4c02bb719b037717df13fa57c0f503d8a20] -> 000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071 + // llmqType[5] requestID[b06aa45eb35423f988e36c022967b4c02bb719b037717df13fa57c0f503d8a20] -> 000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071 + // llmqType[100] requestID[b06aa45eb35423f988e36c022967b4c02bb719b037717df13fa57c0f503d8a20] -> 0000006faac9003919a6d5456a0a46ae10db517f572221279f0540b79fd9cf1b + + let mut request_id: [u8; 32] = + hex::decode("b06aa45eb35423f988e36c022967b4c02bb719b037717df13fa57c0f503d8a20") + .unwrap() + .try_into() + .unwrap(); + + request_id.reverse(); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::Llmq50_60, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "0000000e6d15a11825211c943c4a995c44ebb2b0834b7848c2e080b48ca0148e" + ); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::Llmq100_67, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071" + ); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::Llmq60_75, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071" + ); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::LlmqTest, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "0000006faac9003919a6d5456a0a46ae10db517f572221279f0540b79fd9cf1b" + ); + + // ############### + // llmqType[1] requestID[2fc41ef02a3216e4311805a9a11405a41a8d7a9f179526b4f6f2866bff009a10] -> 000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071 + // llmqType[4] requestID[2fc41ef02a3216e4311805a9a11405a41a8d7a9f179526b4f6f2866bff009a10] -> 0000000e6d15a11825211c943c4a995c44ebb2b0834b7848c2e080b48ca0148e + // llmqType[5] requestID[2fc41ef02a3216e4311805a9a11405a41a8d7a9f179526b4f6f2866bff009a10] -> 000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071 + // llmqType[100] requestID[2fc41ef02a3216e4311805a9a11405a41a8d7a9f179526b4f6f2866bff009a10] -> 000000dc07d722238a994116c3395c334211d9864ff5b37c3be51d5fdda66223 + + let mut request_id: [u8; 32] = + hex::decode("2fc41ef02a3216e4311805a9a11405a41a8d7a9f179526b4f6f2866bff009a10") + .unwrap() + .try_into() + .unwrap(); + + request_id.reverse(); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::Llmq50_60, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071" + ); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::Llmq100_67, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "0000000e6d15a11825211c943c4a995c44ebb2b0834b7848c2e080b48ca0148e" + ); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::Llmq60_75, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "000000bd5639c21dd8abf60253c3fe0343d87a9762b5b8f57e2b4ea1523fd071" + ); + + let mut quorum = Platform::::choose_quorum_v0( + QuorumType::LlmqTest, + &quorums, + &request_id, + ) + .unwrap() + .0; + + quorum.reverse(); + + assert_eq!( + hex::encode(quorum), + "000000dc07d722238a994116c3395c334211d9864ff5b37c3be51d5fdda66223" + ); + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/mod.rs new file mode 100644 index 00000000000..59abfb78f6b --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/mod.rs @@ -0,0 +1,54 @@ +use crate::error::execution::ExecutionError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::rpc::core::CoreRPCLike; +use dashcore_rpc::dashcore::ChainLock; +use dpp::version::PlatformVersion; + +/// Version 0 +pub mod v0; + +/// As we ask to make sure that core is synced to the chain lock, we get back one of 3 +pub enum CoreSyncStatus { + /// Core is synced + CoreIsSynced, + /// Core is 1 or 2 blocks off, we should retry shortly + CoreAlmostSynced, + /// Core is more than 2 blocks off + CoreNotSynced, +} + +impl Platform +where + C: CoreRPCLike, +{ + /// The point of this call is to make sure core is synced. + /// Before this call we had previously validated that the chain lock is valid. + /// Right now the core height should be the same as the chain lock height. + /// + /// Todo: In the future: The core height passed here is the core height that we need to be able to validate all + /// asset lock proofs. + /// It should be chosen by taking the highest height of all state transitions that require core. + /// State transitions that require core are: + /// *Identity Create State transition + /// *Identity Top up State transition + pub fn make_sure_core_is_synced_to_chain_lock( + &self, + chain_lock: &ChainLock, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .methods + .core_chain_lock + .make_sure_core_is_synced_to_chain_lock + { + 0 => self.make_sure_core_is_synced_to_chain_lock_v0(chain_lock, platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "make_sure_core_is_synced_to_chain_lock".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/v0/mod.rs new file mode 100644 index 00000000000..68fafb20204 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/v0/mod.rs @@ -0,0 +1,37 @@ +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::rpc::core::CoreRPCLike; +use dashcore_rpc::dashcore::ChainLock; +use dpp::version::PlatformVersion; +use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus; +use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus::{CoreIsSynced, CoreAlmostSynced, CoreNotSynced}; + +impl Platform +where + C: CoreRPCLike, +{ + /// The point of this call is to make sure core is synced. + /// Before this call we had previously validated that the chain lock is valid. + pub(super) fn make_sure_core_is_synced_to_chain_lock_v0( + &self, + chain_lock: &ChainLock, + platform_version: &PlatformVersion, + ) -> Result { + let given_chain_lock_height = chain_lock.block_height; + // We need to make sure core is synced to the core height we see as valid for the state transitions + let best_chain_locked_height = self.core_rpc.submit_chain_lock(chain_lock)?; + Ok(if best_chain_locked_height >= given_chain_lock_height { + CoreIsSynced + } else if best_chain_locked_height - given_chain_lock_height + <= platform_version + .drive_abci + .methods + .core_chain_lock + .recent_block_count_amount + { + CoreAlmostSynced + } else { + CoreNotSynced + }) + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/mod.rs new file mode 100644 index 00000000000..a44b48464e8 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/mod.rs @@ -0,0 +1,5 @@ +mod choose_quorum; +mod make_sure_core_is_synced_to_chain_lock; +mod verify_chain_lock; +mod verify_chain_lock_locally; +mod verify_chain_lock_through_core; diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock/mod.rs new file mode 100644 index 00000000000..038a7365ac8 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock/mod.rs @@ -0,0 +1,50 @@ +mod v0; + +use crate::error::execution::ExecutionError; +use crate::error::Error; +use dpp::dashcore::ChainLock; + +use crate::platform_types::platform::Platform; + +use crate::rpc::core::CoreRPCLike; + +use crate::platform_types::platform_state::PlatformState; +use crate::platform_types::verify_chain_lock_result::v0::VerifyChainLockResult; +use dpp::version::PlatformVersion; + +impl Platform +where + C: CoreRPCLike, +{ + /// Verify the chain lock + /// If submit is true, we try to submit the chain lock if it is considered valid or we can not check to see if it is + /// valid on platform. + pub fn verify_chain_lock( + &self, + round: u32, + platform_state: &PlatformState, + chain_lock: &ChainLock, + make_sure_core_is_synced: bool, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .methods + .core_chain_lock + .verify_chain_lock + { + 0 => self.verify_chain_lock_v0( + round, + platform_state, + chain_lock, + make_sure_core_is_synced, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "verify_chain_lock".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock/v0/mod.rs new file mode 100644 index 00000000000..136ba114e0f --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock/v0/mod.rs @@ -0,0 +1,157 @@ +use crate::error::Error; +use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus; +use crate::execution::platform_events::core_chain_lock::verify_chain_lock::VerifyChainLockResult; +use dpp::dashcore::ChainLock; +use dpp::version::PlatformVersion; +use std::thread::sleep; +use std::time::Duration; + +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; + +use crate::rpc::core::CoreRPCLike; + +const CORE_ALMOST_SYNCED_RETRIES: u32 = 5; +const CORE_ALMOST_SYNCED_SLEEP_TIME: u64 = 200; + +impl Platform +where + C: CoreRPCLike, +{ + pub(super) fn verify_chain_lock_v0( + &self, + round: u32, + platform_state: &PlatformState, + chain_lock: &ChainLock, + make_sure_core_is_synced: bool, + platform_version: &PlatformVersion, + ) -> Result { + // first we try to verify the chain lock locally + match self.verify_chain_lock_locally(round, platform_state, chain_lock, platform_version) { + Ok(Some(valid)) => { + if valid && make_sure_core_is_synced { + match self.make_sure_core_is_synced_to_chain_lock(chain_lock, platform_version) + { + Ok(sync_status) => { + match sync_status { + CoreSyncStatus::CoreIsSynced => Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: Some(true), + found_valid_by_core: None, + core_is_synced: Some(true), + }), + CoreSyncStatus::CoreAlmostSynced => { + for _i in 0..CORE_ALMOST_SYNCED_RETRIES { + // The chain lock is valid we just need to sleep a bit and retry + sleep(Duration::from_millis(CORE_ALMOST_SYNCED_SLEEP_TIME)); + let best_chain_locked = + self.core_rpc.get_best_chain_lock()?; + if best_chain_locked.block_height >= chain_lock.block_height + { + return Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: Some(valid), + found_valid_by_core: Some(true), + core_is_synced: Some(true), + }); + } + } + Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: Some(true), + found_valid_by_core: Some(true), + core_is_synced: Some(false), + }) + } + CoreSyncStatus::CoreNotSynced => Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: Some(valid), + found_valid_by_core: Some(true), + core_is_synced: Some(false), + }), + } + } + Err(Error::CoreRpc(..)) => { + //ToDO (important), separate errors from core, connection Errors -> Err, others should be part of the result + Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: Some(valid), + found_valid_by_core: Some(false), + core_is_synced: None, //we do not know + }) + } + Err(e) => Err(e), + } + } else { + Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: Some(valid), + found_valid_by_core: None, + core_is_synced: None, + }) + } + } + Ok(None) => { + // we were not able to verify locally + let (verified, status) = self.verify_chain_lock_through_core( + chain_lock, + make_sure_core_is_synced, + platform_version, + )?; + + if let Some(sync_status) = status { + // if we had make_sure_core_is_synced set to true + match sync_status { + CoreSyncStatus::CoreIsSynced => Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: None, + found_valid_by_core: None, + core_is_synced: Some(true), + }), + CoreSyncStatus::CoreAlmostSynced => { + for _i in 0..CORE_ALMOST_SYNCED_RETRIES { + // The chain lock is valid we just need to sleep a bit and retry + sleep(Duration::from_millis(CORE_ALMOST_SYNCED_SLEEP_TIME)); + let best_chain_locked = self.core_rpc.get_best_chain_lock()?; + if best_chain_locked.block_height >= chain_lock.block_height { + return Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: None, + found_valid_by_core: Some(true), + core_is_synced: Some(true), + }); + } + } + Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: None, + found_valid_by_core: Some(true), + core_is_synced: Some(false), + }) + } + CoreSyncStatus::CoreNotSynced => Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: None, + found_valid_by_core: Some(true), + core_is_synced: Some(false), + }), + } + } else { + Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: true, + found_valid_locally: None, + found_valid_by_core: Some(verified), + core_is_synced: None, + }) + } + } + Err(Error::BLSError(_)) => Ok(VerifyChainLockResult { + chain_lock_signature_is_deserializable: false, + found_valid_locally: None, + found_valid_by_core: None, + core_is_synced: None, + }), + Err(e) => Err(e), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_locally/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_locally/mod.rs new file mode 100644 index 00000000000..21df37ba30e --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_locally/mod.rs @@ -0,0 +1,47 @@ +mod v0; + +use crate::error::execution::ExecutionError; +use crate::error::Error; +use dpp::dashcore::ChainLock; + +use crate::platform_types::platform::Platform; + +use crate::rpc::core::CoreRPCLike; + +use crate::config::PlatformConfig; +use crate::platform_types::platform_state::PlatformState; +use dpp::version::PlatformVersion; + +impl Platform +where + C: CoreRPCLike, +{ + /// Returning None here means we were unable to verify the chain lock because of an absence of + /// the quorum + pub fn verify_chain_lock_locally( + &self, + round: u32, + platform_state: &PlatformState, + chain_lock: &ChainLock, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive_abci + .methods + .core_chain_lock + .verify_chain_lock_locally + { + 0 => self.verify_chain_lock_locally_v0( + round, + platform_state, + chain_lock, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "verify_chain_lock_locally".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_locally/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_locally/v0/mod.rs new file mode 100644 index 00000000000..815532e8694 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_locally/v0/mod.rs @@ -0,0 +1,315 @@ +use dpp::block::block_info::BlockInfo; +use dpp::bls_signatures::G2Element; +use dpp::dashcore::consensus::Encodable; +use dpp::dashcore::hashes::{sha256d, Hash, HashEngine}; +use dpp::dashcore::{ChainLock, QuorumSigningRequestId, VarInt}; + +use crate::error::Error; + +use crate::platform_types::platform::Platform; + +use crate::rpc::core::CoreRPCLike; + +use crate::config::PlatformConfig; +use crate::platform_types::platform_state::v0::PlatformStateV0Methods; +use crate::platform_types::platform_state::PlatformState; +use dpp::version::PlatformVersion; + +const CHAIN_LOCK_REQUEST_ID_PREFIX: &str = "clsig"; + +const SIGN_OFFSET: u32 = 8; + +impl Platform +where + C: CoreRPCLike, +{ + /// Returning None here means we were unable to verify the chain lock because of an absence of + /// the quorum + pub fn verify_chain_lock_locally_v0( + &self, + round: u32, + platform_state: &PlatformState, + chain_lock: &ChainLock, + platform_version: &PlatformVersion, + ) -> Result, Error> { + // First verify that the signature conforms to a signature + let signature = G2Element::from_bytes(chain_lock.signature.as_bytes())?; + + // we attempt to verify the chain lock locally + let chain_lock_height = chain_lock.block_height; + + let window_width = self.config.chain_lock_quorum_window; + + // The last block in the window where the quorums would be the same + let last_block_in_window = platform_state.last_committed_core_height() + - platform_state.last_committed_core_height() % window_width + + window_width + - 1; + + let verification_height = chain_lock_height.saturating_sub(SIGN_OFFSET); + + if verification_height > last_block_in_window { + tracing::debug!( + ?chain_lock, + "h:{} r:{} skipped message_digest for chain lock at core height {} is {}, verification height {}, last block in window {}", + platform_state.last_committed_block_height() + 1, + round, + chain_lock.block_height, + platform_state.last_committed_core_height(), + verification_height, + last_block_in_window, + ); + return Ok(None); // the chain lock is too far in the future or the past to verify locally + } + + let (probable_quorums, second_to_check_quorums, should_be_verifiable) = if let Some(( + previous_quorum_height, + change_quorum_height, + previous_quorums_change_height, + previous_quorums, + )) = + platform_state.previous_height_chain_lock_validating_quorums() + { + if chain_lock_height > 8 && verification_height >= *change_quorum_height { + // in this case we are sure that we should be targeting the current quorum + // We updated core chain lock height from 100 to 105, new chain lock comes in for block 114 + // ------- 100 (previous_quorum_height) ------ 105 (change_quorum_height) ------ 106 (new chain lock verification height 114 - 8) + // We are sure that we should use current quorums + // If we have + // ------- 100 (previous_quorum_height) ------ 105 (change_quorum_height) ------ 105 (new chain lock verification height 113 - 8) + // We should also use current quorums, this is because at 105 we are sure new chain lock validating quorums are active + (platform_state.chain_lock_validating_quorums(), None, true) + } else if chain_lock_height > 8 && verification_height <= *previous_quorum_height { + let should_be_verifiable = previous_quorums_change_height + .map(|previous_quorums_change_height| { + verification_height > previous_quorums_change_height + }) + .unwrap_or(false); + // In this case the quorums were changed recently meaning that we should use the previous quorums to verify the chain lock + // We updated core chain lock height from 100 to 105, new chain lock comes in for block 106 + // -------- 98 (new chain lock verification height 106 - 8) ------- 100 (previous_quorum_height) ------ 105 (change_quorum_height) + // We are sure that we should use previous quorums + // If we have + // -------- 100 (new chain lock verification height 108 - 8) ------- 100 (previous_quorum_height) ------ 105 (change_quorum_height) + // We should also use previous quorums, this is because at 100 we are sure the old quorum set was active + (previous_quorums, None, should_be_verifiable) + } else { + let should_be_verifiable = previous_quorums_change_height + .map(|previous_quorums_change_height| { + verification_height > previous_quorums_change_height + }) + .unwrap_or(false); + // we are in between, so we don't actually know if it was the old one or the new one to be used. + // ------- 100 (previous_quorum_height) ------ 104 (new chain lock verification height 112 - 8) -------105 (change_quorum_height) + // we should just try both, starting with the current quorums + ( + platform_state.chain_lock_validating_quorums(), + Some(previous_quorums), + should_be_verifiable, + ) + } + } else { + (platform_state.chain_lock_validating_quorums(), None, false) + }; + + // From DIP 8: https://github.com/dashpay/dips/blob/master/dip-0008.md#finalization-of-signed-blocks + // The request id is SHA256("clsig", blockHeight) and the message hash is the block hash of the previously successful attempt. + + let mut engine = QuorumSigningRequestId::engine(); + + engine.input(&[CHAIN_LOCK_REQUEST_ID_PREFIX.len() as u8]); + engine.input(CHAIN_LOCK_REQUEST_ID_PREFIX.as_bytes()); + engine.input(chain_lock.block_height.to_le_bytes().as_slice()); + + let request_id = QuorumSigningRequestId::from_engine(engine); + + tracing::trace!( + ?chain_lock, + "request id for chain lock at height {} is {}", + chain_lock.block_height, + hex::encode(request_id.as_byte_array()) + ); + + // Based on the deterministic masternode list at the given height, a quorum must be selected that was active at the time this block was mined + + let quorum = Platform::::choose_quorum( + self.config.chain_lock_quorum_type(), + probable_quorums, + request_id.as_ref(), + platform_version, + )?; + + let Some((quorum_hash, public_key)) = quorum else { + return Ok(None); + }; + + // The signature must verify against the quorum public key and SHA256(llmqType, quorumHash, SHA256(height), blockHash). llmqType and quorumHash must be taken from the quorum selected in 1. + + let mut engine = sha256d::Hash::engine(); + + engine.input(&[self.config.chain_lock_quorum_type() as u8]); + engine.input(quorum_hash.as_slice()); + engine.input(request_id.as_byte_array()); + engine.input(chain_lock.block_hash.as_byte_array()); + + let message_digest = sha256d::Hash::from_engine(engine); + + let mut chain_lock_verified = public_key.verify(&signature, message_digest.as_ref()); + + tracing::debug!( + ?chain_lock, + "h:{} r:{} message_digest for chain lock at core height {} is {}, quorum hash is {}, block hash is {}, chain lock was {}, last committed core height {}, verification height {}, last block in window {}", + platform_state.last_committed_block_height() + 1, + round, + chain_lock.block_height, + hex::encode(message_digest.as_byte_array()), + hex::encode(quorum_hash.as_slice()), + hex::encode(chain_lock.block_hash.as_byte_array()), + if chain_lock_verified { "verified"} else {"not verified"}, + platform_state.last_committed_core_height(), + verification_height, + last_block_in_window, + ); + + if !chain_lock_verified { + // We should also check the other quorum, as there could be the situation where the core height wasn't updated every block. + if let Some(second_to_check_quorums) = second_to_check_quorums { + let quorum = Platform::::choose_quorum( + self.config.chain_lock_quorum_type(), + second_to_check_quorums, + request_id.as_ref(), + platform_version, + )?; + + let Some((quorum_hash, public_key)) = quorum else { + // we return that we are not able to verify + return Ok(None); + }; + + // The signature must verify against the quorum public key and SHA256(llmqType, quorumHash, SHA256(height), blockHash). llmqType and quorumHash must be taken from the quorum selected in 1. + + let mut engine = sha256d::Hash::engine(); + + engine.input(&[self.config.chain_lock_quorum_type() as u8]); + engine.input(quorum_hash.as_slice()); + engine.input(request_id.as_byte_array()); + engine.input(chain_lock.block_hash.as_byte_array()); + + let message_digest = sha256d::Hash::from_engine(engine); + + chain_lock_verified = public_key.verify(&signature, message_digest.as_ref()); + + tracing::debug!( + ?chain_lock, + "h:{} r:{} tried second quorums message_digest for chain lock at height {} is {}, quorum hash is {}, block hash is {}, chain lock was {}", + platform_state.last_committed_block_height() + 1, + round, + chain_lock.block_height, + hex::encode(message_digest.as_byte_array()), + hex::encode(quorum_hash.as_slice()), + hex::encode(chain_lock.block_hash.as_byte_array()), + if chain_lock_verified { "verified"} else {"not verified"} + ); + if !chain_lock_verified { + tracing::debug!( + "chain lock was invalid for both recent and old chain lock quorums" + ); + } + } else if platform_state + .previous_height_chain_lock_validating_quorums() + .is_none() + { + // we don't have old quorums, this means our node is very new. + tracing::debug!( + "we had no previous quorums locally, we should validate through core", + ); + return Ok(None); + } else if !should_be_verifiable { + tracing::debug!( + "we were in a situation where it would be possible we didn't have all quorums and we couldn't verify locally, we should validate through core", + ); + return Ok(None); + } else if round >= 10 { + tracing::debug!("high round when chain lock was invalid, asking core to verify"); + } else { + tracing::debug!("chain lock was invalid, and we deemed there was no reason to check old quorums"); + } + } + + return Ok(Some(chain_lock_verified)); + } +} + +#[cfg(test)] +mod tests { + use crate::execution::platform_events::core_chain_lock::verify_chain_lock_locally::v0::CHAIN_LOCK_REQUEST_ID_PREFIX; + use dpp::dashcore::hashes::{sha256d, Hash, HashEngine}; + use dpp::dashcore::QuorumSigningRequestId; + + #[test] + fn verify_request_id() { + assert_eq!( + hex::encode(CHAIN_LOCK_REQUEST_ID_PREFIX.as_bytes()), + "636c736967" + ); + assert_eq!(hex::encode(122u32.to_le_bytes()), "7a000000"); + + let mut engine = QuorumSigningRequestId::engine(); + + engine.input(&[CHAIN_LOCK_REQUEST_ID_PREFIX.len() as u8]); + engine.input(CHAIN_LOCK_REQUEST_ID_PREFIX.as_bytes()); + engine.input(122u32.to_le_bytes().as_slice()); + + let request_id = QuorumSigningRequestId::from_engine(engine); + + assert_eq!( + hex::encode(request_id.as_byte_array()), + "e1a9d40e5145fdc168819125b5ae1b8f12d5115471624eb363a6c7a3693be2e6" + ); + + // + // let mut chain_lock_verified = public_key.verify(&signature, message_digest.as_ref()); + } + + #[test] + fn verify_message_digest() { + let mut engine = QuorumSigningRequestId::engine(); + + engine.input(&[CHAIN_LOCK_REQUEST_ID_PREFIX.len() as u8]); + engine.input(CHAIN_LOCK_REQUEST_ID_PREFIX.as_bytes()); + engine.input(956087u32.to_le_bytes().as_slice()); + + let request_id = QuorumSigningRequestId::from_engine(engine); + + assert_eq!( + hex::encode(request_id.as_byte_array()), + "ea04b27adfaa698487aee46b922fb8f1c77a562787b6afe65eecf7e685888928" + ); + + let mut block_hash = + hex::decode("000000d94ea7ac4f86c5f583e7da0feb90b9f8d038f25e55cc305524c5327266") + .unwrap(); + let mut quorum_hash = + hex::decode("0000009d376e73a22aa997bb6542bd1fc3018f61c2301a817126a737ffdcdc80") + .unwrap(); + + block_hash.reverse(); + quorum_hash.reverse(); + + let mut engine = sha256d::Hash::engine(); + + engine.input(&[1u8]); + engine.input(quorum_hash.as_slice()); + engine.input(request_id.to_byte_array().as_slice()); + engine.input(block_hash.as_slice()); + + let mut message_digest = sha256d::Hash::from_engine(engine).as_byte_array().to_vec(); + + message_digest.reverse(); + + assert_eq!( + hex::encode(message_digest.as_slice()), + "5ec53e83b8ff390b970e28db21da5b8e45fbe3b69d9f11a2c39062769b1f5e47" + ); + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/mod.rs new file mode 100644 index 00000000000..e7c585498d7 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/mod.rs @@ -0,0 +1,39 @@ +mod v0; + +use crate::error::execution::ExecutionError; +use crate::error::Error; +use dpp::dashcore::ChainLock; + +use crate::platform_types::platform::Platform; + +use crate::rpc::core::CoreRPCLike; + +use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus; +use dpp::version::PlatformVersion; + +impl Platform +where + C: CoreRPCLike, +{ + /// Verify the chain lock through core + pub fn verify_chain_lock_through_core( + &self, + chain_lock: &ChainLock, + submit: bool, + platform_version: &PlatformVersion, + ) -> Result<(bool, Option), Error> { + match platform_version + .drive_abci + .methods + .core_chain_lock + .verify_chain_lock_through_core + { + 0 => self.verify_chain_lock_through_core_v0(chain_lock, submit, platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "verify_chain_lock_through_core".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/v0/mod.rs new file mode 100644 index 00000000000..063794afc13 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/v0/mod.rs @@ -0,0 +1,43 @@ +use crate::error::Error; +use dpp::dashcore::ChainLock; +use dpp::version::PlatformVersion; +use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus; +use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus::{CoreAlmostSynced, CoreIsSynced, CoreNotSynced}; + +use crate::platform_types::platform::Platform; + +use crate::rpc::core::CoreRPCLike; + +impl Platform +where + C: CoreRPCLike, +{ + /// Verify the chain lock through core v0 + pub fn verify_chain_lock_through_core_v0( + &self, + chain_lock: &ChainLock, + submit: bool, + platform_version: &PlatformVersion, + ) -> Result<(bool, Option), Error> { + if submit { + let given_chain_lock_height = chain_lock.block_height; + + let best_chain_locked_height = self.core_rpc.submit_chain_lock(chain_lock)?; + Ok(if best_chain_locked_height >= given_chain_lock_height { + (true, Some(CoreIsSynced)) + } else if best_chain_locked_height - given_chain_lock_height + <= platform_version + .drive_abci + .methods + .core_chain_lock + .recent_block_count_amount + { + (true, Some(CoreAlmostSynced)) + } else { + (true, Some(CoreNotSynced)) + }) + } else { + Ok((self.core_rpc.verify_chain_lock(chain_lock)?, None)) + } + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/epoch/gather_epoch_info/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/epoch/gather_epoch_info/v0/mod.rs index a64fb5ac28f..ea3dd74b655 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/epoch/gather_epoch_info/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/epoch/gather_epoch_info/v0/mod.rs @@ -19,7 +19,7 @@ impl Platform { // Start by getting information from the state let state = self.state.read().unwrap(); - let last_block_time_ms = state.last_block_time_ms(); + let last_block_time_ms = state.last_committed_block_time_ms(); // Init block execution context let block_state_info = block_state_info::v0::BlockStateInfoV0::from_block_proposal( diff --git a/packages/rs-drive-abci/src/execution/platform_events/identity_credit_withdrawal/pool_withdrawals_into_transactions_queue/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/identity_credit_withdrawal/pool_withdrawals_into_transactions_queue/v0/mod.rs index 139820ec9ac..5e17d00ffcc 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/identity_credit_withdrawal/pool_withdrawals_into_transactions_queue/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/identity_credit_withdrawal/pool_withdrawals_into_transactions_queue/v0/mod.rs @@ -209,6 +209,8 @@ mod tests { current_validator_set_quorum_hash: QuorumHash::all_zeros(), next_validator_set_quorum_hash: None, validator_sets: Default::default(), + chain_lock_validating_quorums: Default::default(), + previous_height_chain_lock_validating_quorums: None, full_masternode_list: Default::default(), hpmn_masternode_list: Default::default(), genesis_block_info: None, diff --git a/packages/rs-drive-abci/src/execution/platform_events/identity_credit_withdrawal/update_broadcasted_withdrawal_transaction_statuses/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/identity_credit_withdrawal/update_broadcasted_withdrawal_transaction_statuses/v0/mod.rs index d0d503ada17..5a8c4e13e14 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/identity_credit_withdrawal/update_broadcasted_withdrawal_transaction_statuses/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/identity_credit_withdrawal/update_broadcasted_withdrawal_transaction_statuses/v0/mod.rs @@ -348,6 +348,8 @@ mod tests { current_validator_set_quorum_hash: QuorumHash::all_zeros(), next_validator_set_quorum_hash: None, validator_sets: Default::default(), + chain_lock_validating_quorums: Default::default(), + previous_height_chain_lock_validating_quorums: None, full_masternode_list: Default::default(), hpmn_masternode_list: Default::default(), genesis_block_info: None, diff --git a/packages/rs-drive-abci/src/execution/platform_events/initialization/initial_core_height/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/initialization/initial_core_height/v0/mod.rs index 3df1edb88d5..ab50a9e6de5 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/initialization/initial_core_height/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/initialization/initial_core_height/v0/mod.rs @@ -44,7 +44,7 @@ where let v20_fork = fork_info.height.unwrap(); if let Some(requested) = requested { - let best = self.core_rpc.get_best_chain_lock()?.core_block_height; + let best = self.core_rpc.get_best_chain_lock()?.block_height; tracing::trace!( requested, diff --git a/packages/rs-drive-abci/src/execution/platform_events/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/mod.rs index 51efcb08668..7e79189addd 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/mod.rs @@ -25,3 +25,6 @@ pub(in crate::execution) mod withdrawals; /// Events happening what starting to process a block pub(in crate::execution) mod block_start; + +/// Verify the chain lock +pub(in crate::execution) mod core_chain_lock; diff --git a/packages/rs-drive-abci/src/execution/platform_events/withdrawals/check_withdrawals/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/withdrawals/check_withdrawals/v0/mod.rs index 7c7594d1bb3..32a957cf4f0 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/withdrawals/check_withdrawals/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/withdrawals/check_withdrawals/v0/mod.rs @@ -53,7 +53,7 @@ where let quorum_hash = quorum_hash.expect("quorum hash is required to verify signature"); let validation_result = received_withdrawals.verify_signatures( &self.config.abci.chain_id, - self.config.quorum_type(), + self.config.validator_set_quorum_type(), quorum_hash, height, round, diff --git a/packages/rs-drive-abci/src/execution/types/block_execution_context/mod.rs b/packages/rs-drive-abci/src/execution/types/block_execution_context/mod.rs index 0ff0b617492..89e78136e97 100644 --- a/packages/rs-drive-abci/src/execution/types/block_execution_context/mod.rs +++ b/packages/rs-drive-abci/src/execution/types/block_execution_context/mod.rs @@ -15,7 +15,7 @@ use std::collections::BTreeMap; use tenderdash_abci::proto::abci::ResponsePrepareProposal; /// The versioned block execution context -#[derive(Debug, From)] +#[derive(Debug, From, Clone)] pub enum BlockExecutionContext { /// Version 0 V0(v0::BlockExecutionContextV0), diff --git a/packages/rs-drive-abci/src/execution/types/block_execution_context/v0/mod.rs b/packages/rs-drive-abci/src/execution/types/block_execution_context/v0/mod.rs index 33cd7fa2f19..587407bb47b 100644 --- a/packages/rs-drive-abci/src/execution/types/block_execution_context/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/types/block_execution_context/v0/mod.rs @@ -36,7 +36,7 @@ use std::collections::BTreeMap; use tenderdash_abci::proto::abci::ResponsePrepareProposal; /// V0 of the Block execution context -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct BlockExecutionContextV0 { /// Block info pub block_state_info: BlockStateInfo, diff --git a/packages/rs-drive-abci/src/execution/types/block_state_info/mod.rs b/packages/rs-drive-abci/src/execution/types/block_state_info/mod.rs index 86e794cc001..684bcaaa569 100644 --- a/packages/rs-drive-abci/src/execution/types/block_state_info/mod.rs +++ b/packages/rs-drive-abci/src/execution/types/block_state_info/mod.rs @@ -11,7 +11,7 @@ use dpp::block::block_info::BlockInfo; use dpp::block::epoch::Epoch; /// The versioned block state info -#[derive(Debug, From)] +#[derive(Debug, From, Clone, Eq, PartialEq)] pub enum BlockStateInfo { /// Version 0 V0(v0::BlockStateInfoV0), diff --git a/packages/rs-drive-abci/src/execution/types/block_state_info/v0/mod.rs b/packages/rs-drive-abci/src/execution/types/block_state_info/v0/mod.rs index 1b58804fdbb..8e3b405e651 100644 --- a/packages/rs-drive-abci/src/execution/types/block_state_info/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/types/block_state_info/v0/mod.rs @@ -34,7 +34,7 @@ use dpp::block::block_info::BlockInfo; use dpp::block::epoch::Epoch; /// Block info -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct BlockStateInfoV0 { /// Block height pub height: u64, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs index 20d35ea0b23..e3864c27c49 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs @@ -146,7 +146,7 @@ pub(super) fn state_transition_to_execution_event_for_check_tx_v0<'a, C: CoreRPC let execution_event = ExecutionEvent::create_from_state_transition_action( action, maybe_identity, - platform.state.epoch_ref(), + platform.state.last_committed_block_epoch_ref(), state_transition_execution_context, platform_version, )?; @@ -206,7 +206,7 @@ pub(super) fn state_transition_to_execution_event_for_check_tx_v0<'a, C: CoreRPC let execution_event = ExecutionEvent::create_from_state_transition_action( action, maybe_identity, - platform.state.epoch_ref(), + platform.state.last_committed_block_epoch_ref(), state_transition_execution_context, platform_version, )?; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs index ac909f52e09..f9d712bc9a0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs @@ -111,7 +111,7 @@ pub(in crate::execution) fn process_state_transition_v0<'a, C: CoreRPCLike>( ExecutionEvent::create_from_state_transition_action( action, maybe_identity, - platform.state.epoch_ref(), + platform.state.last_committed_block_epoch_ref(), state_transition_execution_context, platform_version, ) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs index 151eca048e8..cd571da9b82 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs @@ -147,10 +147,10 @@ mod tests { .data_contract_owned(); let config = PlatformConfig { - quorum_size: 10, + validator_set_quorum_size: 10, execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 300, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/structure_v0/mod.rs index 22409379a81..be05c9bd569 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/structure_v0/mod.rs @@ -78,7 +78,7 @@ impl DocumentCreateTransitionActionStructureValidationV0 for DocumentCreateTrans // Validate timestamps against block time // we do validation here but not in validate state because it's a cheap validation // and validate state implements expensive validation only - let latest_block_time_ms = platform.state.last_block_time_ms(); + let latest_block_time_ms = platform.state.last_committed_block_time_ms(); let average_block_spacing_ms = platform.config.block_spacing_ms; // We do not need to perform these checks on genesis diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/structure_v0/mod.rs index 1bf0ba9b8d3..8430b1a1fab 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/structure_v0/mod.rs @@ -58,7 +58,7 @@ impl DocumentReplaceTransitionActionStructureValidationV0 for DocumentReplaceTra // Validate timestamps against block time // we do validation here but not in validate state because it's a cheap validation // and validate state implements expensive validation only - let latest_block_time_ms = platform.state.last_block_time_ms(); + let latest_block_time_ms = platform.state.last_committed_block_time_ms(); let average_block_spacing_ms = platform.config.block_spacing_ms; if let Some(latest_block_time_ms) = latest_block_time_ms { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs index 42b07516598..61da179ca6f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs @@ -77,7 +77,7 @@ pub fn create_contact_request_data_trigger_v0( } if let Some(core_height_created_at) = maybe_core_height_created_at { - let core_chain_locked_height = context.platform.state.core_height(); + let core_chain_locked_height = context.platform.state.last_committed_core_height(); let height_window_start = core_chain_locked_height.saturating_sub(BLOCKS_SIZE_WINDOW); let height_window_end = core_chain_locked_height.saturating_add(BLOCKS_SIZE_WINDOW); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/v0/mod.rs index 2a307ea5dae..6300fdcc57a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/v0/mod.rs @@ -60,7 +60,7 @@ pub fn create_feature_flag_data_trigger_v0( ))) })?; - let latest_block_height = context.platform.state.height(); + let latest_block_height = context.platform.state.last_committed_height(); if enable_at_height < latest_block_height { let err = DataTriggerConditionError::new( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs index 1b55ac6a673..6ca0dc35441 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs @@ -82,7 +82,7 @@ pub(crate) fn fetch_documents_for_transitions_knowing_contract_id_and_document_t let add_to_cache_if_pulled = transaction.is_some(); let (_, contract_fetch_info) = drive.get_contract_with_fetch_info_and_fee( contract_id.to_buffer(), - Some(&platform.state.epoch()), + Some(&platform.state.last_committed_block_epoch()), add_to_cache_if_pulled, transaction, platform_version, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/state/v0/mod.rs index 335bec12a72..aef587218ef 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/state/v0/mod.rs @@ -91,11 +91,13 @@ impl IdentityCreditWithdrawalStateTransitionStateValidationV0 &self, platform: &PlatformRef, ) -> Result, Error> { - let last_block_time = platform.state.last_block_time_ms().ok_or(Error::Execution( - ExecutionError::StateNotInitialized( - "expected a last platform block during identity update validation", - ), - ))?; + let last_block_time = + platform + .state + .last_committed_block_time_ms() + .ok_or(Error::Execution(ExecutionError::StateNotInitialized( + "expected a last platform block during identity update validation", + )))?; Ok(ConsensusValidationResult::new_with_data( IdentityCreditWithdrawalTransitionAction::from_identity_credit_withdrawal( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs index 7619699f122..828635abb09 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs @@ -123,11 +123,13 @@ impl IdentityUpdateStateTransitionStateValidationV0 for IdentityUpdateTransition if let Some(disabled_at_ms) = self.public_keys_disabled_at() { // We need to verify the time the keys were disabled - let last_block_time = platform.state.last_block_time_ms().ok_or( - Error::Execution(ExecutionError::StateNotInitialized( - "expected a last platform block during identity update validation", - )), - )?; + let last_block_time = + platform + .state + .last_committed_block_time_ms() + .ok_or(Error::Execution(ExecutionError::StateNotInitialized( + "expected a last platform block during identity update validation", + )))?; let window_validation_result = validate_time_in_block_time_window( last_block_time, diff --git a/packages/rs-drive-abci/src/mimic/mod.rs b/packages/rs-drive-abci/src/mimic/mod.rs index 1c532fba21b..640a6baa1ad 100644 --- a/packages/rs-drive-abci/src/mimic/mod.rs +++ b/packages/rs-drive-abci/src/mimic/mod.rs @@ -29,6 +29,8 @@ use tenderdash_abci::proto::types::{ use tenderdash_abci::signatures::SignBytes; use tenderdash_abci::{signatures::SignDigest, proto::version::Consensus, Application}; use tenderdash_abci::proto::abci::tx_record::TxAction; +use crate::execution::types::block_execution_context::v0::BlockExecutionContextV0Getters; +use crate::execution::types::block_state_info::v0::BlockStateInfoV0Getters; use crate::mimic::test_quorum::TestQuorumInfo; /// Test quorum for mimic block execution @@ -65,6 +67,10 @@ pub struct MimicExecuteBlockOptions { pub dont_finalize_block: bool, /// rounds before finalization pub rounds_before_finalization: Option, + /// max tx bytes per block + pub max_tx_bytes_per_block: u64, + /// run process proposal independently + pub independent_process_proposal_verification: bool, } impl<'a, C: CoreRPCLike> AbciApplication<'a, C> { @@ -80,9 +86,30 @@ impl<'a, C: CoreRPCLike> AbciApplication<'a, C> { expect_validation_errors: &[u32], expect_vote_extension_errors: bool, state_transitions: Vec, - max_tx_bytes_per_block: i64, options: MimicExecuteBlockOptions, ) -> Result { + // This will be NONE, except on init chain + let original_block_execution_context = self + .platform + .block_execution_context + .read() + .unwrap() + .as_ref() + .cloned(); + + let transaction_guard = self.transaction.read().unwrap(); + + let init_chain_root_hash = transaction_guard.as_ref().map(|transaction| { + self.platform + .drive + .grove + .root_hash(Some(transaction)) + .unwrap() + .unwrap() + }); + + drop(transaction_guard); + const APP_VERSION: u64 = 0; let mut rng = StdRng::seed_from_u64(block_info.height); @@ -106,7 +133,7 @@ impl<'a, C: CoreRPCLike> AbciApplication<'a, C> { // PREPARE (also processes internally) let request_prepare_proposal = RequestPrepareProposal { - max_tx_bytes: max_tx_bytes_per_block, + max_tx_bytes: options.max_tx_bytes_per_block as i64, txs: serialized_state_transitions.clone(), local_last_commit: None, misbehavior: vec![], @@ -217,14 +244,112 @@ impl<'a, C: CoreRPCLike> AbciApplication<'a, C> { quorum_hash: current_quorum.quorum_hash.to_byte_array().to_vec(), }; - //we must call process proposal so the app hash is set - self.process_proposal(request_process_proposal) - .unwrap_or_else(|e| { - panic!( - "should skip processing (because we prepared it) block #{} at time #{} : {:?}", - block_info.height, block_info.time_ms, e - ) - }); + if !options.independent_process_proposal_verification { + //we just check as if we were the proposer + //we must call process proposal so the app hash is set + self.process_proposal(request_process_proposal) + .unwrap_or_else(|e| { + panic!( + "should skip processing (because we prepared it) block #{} at time #{} : {:?}", + block_info.height, block_info.time_ms, e + ) + }); + } else { + //we first call process proposal as the proposer + //we must call process proposal so the app hash is set + self.process_proposal(request_process_proposal.clone()) + .unwrap_or_else(|e| { + panic!( + "should skip processing (because we prepared it) block #{} at time #{} : {:?}", + block_info.height, block_info.time_ms, e + ) + }); + + let mut block_execution_context = + self.platform.block_execution_context.write().unwrap(); + + let application_hash = block_execution_context + .as_ref() + .expect("expected a block execution context") + .block_state_info() + .app_hash() + .expect("expected an application hash after process proposal"); + + *block_execution_context = original_block_execution_context.clone(); + drop(block_execution_context); + + if let Some(init_chain_root_hash) = init_chain_root_hash + //we are in init chain + { + // special logic on init chain + let transaction = self.transaction.write().unwrap(); + + let transaction = transaction.as_ref().ok_or(Error::Execution( + ExecutionError::NotInTransaction( + "trying to finalize block without a current transaction", + ), + ))?; + + transaction + .rollback_to_savepoint() + .expect("expected to rollback to savepoint"); + + let start_root_hash = self + .platform + .drive + .grove + .root_hash(Some(transaction)) + .unwrap() + .unwrap(); + assert_eq!(start_root_hash, init_chain_root_hash); + // this is just to verify that the rollback worked. + }; + + //we call process proposal as if we are a processor + self.process_proposal(request_process_proposal) + .unwrap_or_else(|e| { + panic!( + "should skip processing (because we prepared it) block #{} at time #{} : {:?}", + block_info.height, block_info.time_ms, e + ) + }); + + let block_execution_context = self.platform.block_execution_context.read().unwrap(); + + let process_proposal_application_hash = block_execution_context + .as_ref() + .expect("expected a block execution context") + .block_state_info() + .app_hash() + .expect("expected an application hash after process proposal"); + + assert_eq!( + application_hash, process_proposal_application_hash, + "the application hashed are not valid for height {}", + block_info.height + ); + + let transaction_guard = self.transaction.read().unwrap(); + + let transaction = transaction_guard.as_ref().ok_or(Error::Execution( + ExecutionError::NotInTransaction( + "trying to finalize block without a current transaction", + ), + ))?; + + let direct_root_hash = self + .platform + .drive + .grove + .root_hash(Some(transaction)) + .unwrap() + .unwrap(); + assert_eq!( + application_hash, direct_root_hash, + "the application hashed are not valid for height {}", + block_info.height + ); + } let request_extend_vote = RequestExtendVote { hash: block_header_hash.to_vec(), @@ -321,7 +446,7 @@ impl<'a, C: CoreRPCLike> AbciApplication<'a, C> { // We need to sign the block - let quorum_type = self.platform.config.quorum_type(); + let quorum_type = self.platform.config.validator_set_quorum_type(); let state_id_hash = state_id .sha256(CHAIN_ID, height as i64, round as i32) .expect("cannot calculate state id hash"); diff --git a/packages/rs-drive-abci/src/platform_types/block_proposal/v0.rs b/packages/rs-drive-abci/src/platform_types/block_proposal/v0.rs index 31486f97e05..7ed2273d95d 100644 --- a/packages/rs-drive-abci/src/platform_types/block_proposal/v0.rs +++ b/packages/rs-drive-abci/src/platform_types/block_proposal/v0.rs @@ -1,8 +1,13 @@ use crate::abci::AbciError; use crate::error::Error; +use dpp::dashcore::bls_sig_utils::BLSSignature; +use dpp::dashcore::hashes::Hash; +use dpp::dashcore::{BlockHash, ChainLock}; +use dpp::platform_value::Bytes32; use std::fmt; use tenderdash_abci::proto::abci::{RequestPrepareProposal, RequestProcessProposal}; use tenderdash_abci::proto::serializers::timestamp::ToMilis; +use tenderdash_abci::proto::types::CoreChainLock; use tenderdash_abci::proto::version::Consensus; /// The block proposal is the combination of information that a proposer will propose, @@ -20,6 +25,8 @@ pub struct BlockProposal<'a> { pub block_time_ms: u64, /// Block height of the core chain pub core_chain_locked_height: u32, + /// Potential update core chain lock + pub core_chain_lock_update: Option, /// The proposed app version pub proposed_app_version: u64, /// Block proposer's proTxHash @@ -133,6 +140,7 @@ impl<'a> TryFrom<&'a RequestPrepareProposal> for BlockProposal<'a> { height: *height as u64, round: *round as u32, core_chain_locked_height: *core_chain_locked_height, + core_chain_lock_update: None, //there is no need to verify a chain lock we are proposing proposed_app_version: *proposed_app_version, proposer_pro_tx_hash, validator_set_quorum_hash, @@ -157,7 +165,7 @@ impl<'a> TryFrom<&'a RequestProcessProposal> for BlockProposal<'a> { time, next_validators_hash: _, core_chain_locked_height, - core_chain_lock_update: _, + core_chain_lock_update, proposer_pro_tx_hash, proposed_app_version, version, @@ -207,12 +215,36 @@ impl<'a> TryFrom<&'a RequestProcessProposal> for BlockProposal<'a> { ) .into()); } + + let core_chain_lock_update = core_chain_lock_update + .as_ref() + .map(|core_chain_lock| { + let CoreChainLock { + core_block_height, + core_block_hash, + signature, + } = core_chain_lock; + + let block_hash: Bytes32 = Bytes32::from_vec(core_block_hash.clone())?; + + let signature: [u8; 96] = signature.clone().try_into().map_err(|_| { + AbciError::BadRequest("core chain lock signature not 96 bytes".to_string()) + })?; + + Ok::(ChainLock { + block_height: *core_block_height, + block_hash: BlockHash::from_byte_array(block_hash.0), + signature: BLSSignature::from(signature), + }) + }) + .transpose()?; Ok(Self { consensus_versions, block_hash: Some(block_hash), height: *height as u64, round: *round as u32, core_chain_locked_height: *core_chain_locked_height, + core_chain_lock_update, proposed_app_version: *proposed_app_version, proposer_pro_tx_hash, validator_set_quorum_hash, diff --git a/packages/rs-drive-abci/src/platform_types/epoch_info/mod.rs b/packages/rs-drive-abci/src/platform_types/epoch_info/mod.rs index 4d20118a553..78dac32a8c1 100644 --- a/packages/rs-drive-abci/src/platform_types/epoch_info/mod.rs +++ b/packages/rs-drive-abci/src/platform_types/epoch_info/mod.rs @@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize}; pub mod v0; /// Info pertinent to the current epoch. -#[derive(Clone, Serialize, Deserialize, Debug, From)] +#[derive(Clone, Serialize, Deserialize, Debug, From, Eq, PartialEq)] #[serde(rename_all = "camelCase")] pub enum EpochInfo { /// Version 0 diff --git a/packages/rs-drive-abci/src/platform_types/epoch_info/v0/mod.rs b/packages/rs-drive-abci/src/platform_types/epoch_info/v0/mod.rs index 81a1c62c3b9..b0891428c72 100644 --- a/packages/rs-drive-abci/src/platform_types/epoch_info/v0/mod.rs +++ b/packages/rs-drive-abci/src/platform_types/epoch_info/v0/mod.rs @@ -45,7 +45,7 @@ use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; /// Info pertinent to the current epoch. -#[derive(Clone, Serialize, Deserialize, Debug)] +#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq)] #[serde(rename_all = "camelCase")] pub struct EpochInfoV0 { /// Current epoch index diff --git a/packages/rs-drive-abci/src/platform_types/mod.rs b/packages/rs-drive-abci/src/platform_types/mod.rs index 3c9ea91fdee..7602529bab6 100644 --- a/packages/rs-drive-abci/src/platform_types/mod.rs +++ b/packages/rs-drive-abci/src/platform_types/mod.rs @@ -58,3 +58,6 @@ pub mod validator; pub mod validator_set; /// Withdrawal types pub mod withdrawal; + +/// Verify chain lock result +pub mod verify_chain_lock_result; diff --git a/packages/rs-drive-abci/src/platform_types/platform/mod.rs b/packages/rs-drive-abci/src/platform_types/platform/mod.rs index 619c02bd0ec..54c9f8cea4b 100644 --- a/packages/rs-drive-abci/src/platform_types/platform/mod.rs +++ b/packages/rs-drive-abci/src/platform_types/platform/mod.rs @@ -103,7 +103,7 @@ impl Platform { path: P, config: Option, ) -> Result, Error> { - let config = config.unwrap_or_default(); + let config = config.unwrap_or(PlatformConfig::default_testnet()); let core_rpc = DefaultCoreRPC::open( config.core.rpc.url().as_str(), config.core.rpc.username.clone(), @@ -174,7 +174,7 @@ impl Platform { where C: CoreRPCLike, { - let config = config.unwrap_or_default(); + let config = config.unwrap_or(PlatformConfig::default_testnet()); let drive = Drive::open(path, Some(config.drive.clone())).map_err(Error::Drive)?; diff --git a/packages/rs-drive-abci/src/platform_types/platform_state/mod.rs b/packages/rs-drive-abci/src/platform_types/platform_state/mod.rs index 9e03b3f2b26..8c7bf8ddc5f 100644 --- a/packages/rs-drive-abci/src/platform_types/platform_state/mod.rs +++ b/packages/rs-drive-abci/src/platform_types/platform_state/mod.rs @@ -24,6 +24,7 @@ use indexmap::IndexMap; use crate::error::execution::ExecutionError; use dpp::block::block_info::BlockInfo; +use dpp::bls_signatures::PublicKey as ThresholdBlsPublicKey; use dpp::util::hash::hash; use std::collections::BTreeMap; @@ -194,75 +195,69 @@ impl TryFromPlatformVersioned for PlatformState { } impl PlatformStateV0Methods for PlatformState { - fn height(&self) -> u64 { + fn last_committed_height(&self) -> u64 { match self { - PlatformState::V0(v0) => v0.height(), + PlatformState::V0(v0) => v0.last_committed_height(), } } - fn known_height_or(&self, default: u64) -> u64 { + fn last_committed_known_height_or(&self, default: u64) -> u64 { match self { - PlatformState::V0(v0) => v0.known_height_or(default), + PlatformState::V0(v0) => v0.last_committed_known_height_or(default), } } - fn core_height(&self) -> u32 { + fn last_committed_core_height(&self) -> u32 { match self { - PlatformState::V0(v0) => v0.core_height(), + PlatformState::V0(v0) => v0.last_committed_core_height(), } } - fn known_core_height_or(&self, default: u32) -> u32 { + fn last_committed_known_core_height_or(&self, default: u32) -> u32 { match self { - PlatformState::V0(v0) => v0.known_core_height_or(default), + PlatformState::V0(v0) => v0.last_committed_known_core_height_or(default), } } - fn last_block_time_ms(&self) -> Option { + fn last_committed_block_time_ms(&self) -> Option { match self { - PlatformState::V0(v0) => v0.last_block_time_ms(), + PlatformState::V0(v0) => v0.last_committed_block_time_ms(), } } - fn last_quorum_hash(&self) -> [u8; 32] { + fn last_committed_quorum_hash(&self) -> [u8; 32] { match self { - PlatformState::V0(v0) => v0.last_quorum_hash(), + PlatformState::V0(v0) => v0.last_committed_quorum_hash(), } } - fn last_block_signature(&self) -> [u8; 96] { + fn last_committed_block_signature(&self) -> [u8; 96] { match self { - PlatformState::V0(v0) => v0.last_block_signature(), + PlatformState::V0(v0) => v0.last_committed_block_signature(), } } - fn last_block_app_hash(&self) -> Option<[u8; 32]> { + fn last_committed_block_app_hash(&self) -> Option<[u8; 32]> { match self { - PlatformState::V0(v0) => v0.last_block_app_hash(), + PlatformState::V0(v0) => v0.last_committed_block_app_hash(), } } - fn last_block_height(&self) -> u64 { + fn last_committed_block_height(&self) -> u64 { match self { - PlatformState::V0(v0) => v0.last_block_height(), + PlatformState::V0(v0) => v0.last_committed_block_height(), } } - fn last_block_round(&self) -> u32 { + fn last_committed_block_round(&self) -> u32 { match self { - PlatformState::V0(v0) => v0.last_block_round(), + PlatformState::V0(v0) => v0.last_committed_block_round(), } } - fn epoch(&self) -> Epoch { + fn last_committed_block_epoch(&self) -> Epoch { match self { - PlatformState::V0(v0) => v0.epoch(), - } - } - - fn epoch_ref(&self) -> &Epoch { - match self { - PlatformState::V0(v0) => v0.epoch_ref(), + PlatformState::V0(v0) => v0.last_committed_block_epoch(), } } @@ -278,15 +273,15 @@ impl PlatformStateV0Methods for PlatformState { } } - fn current_protocol_version_in_consensus(&self) -> ProtocolVersion { + fn last_committed_block_info(&self) -> &Option { match self { - PlatformState::V0(v0) => v0.current_protocol_version_in_consensus(), + PlatformState::V0(v0) => &v0.last_committed_block_info, } } - fn last_committed_block_info(&self) -> &Option { + fn current_protocol_version_in_consensus(&self) -> ProtocolVersion { match self { - PlatformState::V0(v0) => &v0.last_committed_block_info, + PlatformState::V0(v0) => v0.current_protocol_version_in_consensus(), } } @@ -308,12 +303,24 @@ impl PlatformStateV0Methods for PlatformState { } } + fn take_next_validator_set_quorum_hash(&mut self) -> Option { + match self { + PlatformState::V0(v0) => v0.take_next_validator_set_quorum_hash(), + } + } + fn validator_sets(&self) -> &IndexMap { match self { PlatformState::V0(v0) => &v0.validator_sets, } } + fn chain_lock_validating_quorums(&self) -> &BTreeMap { + match self { + PlatformState::V0(v0) => &v0.chain_lock_validating_quorums, + } + } + fn full_masternode_list(&self) -> &BTreeMap { match self { PlatformState::V0(v0) => &v0.full_masternode_list, @@ -332,6 +339,12 @@ impl PlatformStateV0Methods for PlatformState { } } + fn any_block_info(&self) -> &BlockInfo { + match self { + PlatformState::V0(v0) => v0.any_block_info(), + } + } + fn set_last_committed_block_info(&mut self, info: Option) { match self { PlatformState::V0(v0) => v0.set_last_committed_block_info(info), @@ -368,6 +381,41 @@ impl PlatformStateV0Methods for PlatformState { } } + fn set_chain_lock_validating_quorums( + &mut self, + quorums: BTreeMap, + ) { + match self { + PlatformState::V0(v0) => v0.set_chain_lock_validating_quorums(quorums), + } + } + + fn replace_chain_lock_validating_quorums( + &mut self, + quorums: BTreeMap, + ) -> BTreeMap { + match self { + PlatformState::V0(v0) => v0.replace_chain_lock_validating_quorums(quorums), + } + } + + fn set_previous_chain_lock_validating_quorums( + &mut self, + previous_core_height: u32, + change_core_height: u32, + previous_quorums_change_height: Option, + quorums: BTreeMap, + ) { + match self { + PlatformState::V0(v0) => v0.set_previous_chain_lock_validating_quorums( + previous_core_height, + change_core_height, + previous_quorums_change_height, + quorums, + ), + } + } + fn set_full_masternode_list(&mut self, list: BTreeMap) { match self { PlatformState::V0(v0) => v0.set_full_masternode_list(list), @@ -422,33 +470,61 @@ impl PlatformStateV0Methods for PlatformState { } } - fn full_masternode_list_mut(&mut self) -> &mut BTreeMap { + fn chain_lock_validating_quorums_mut( + &mut self, + ) -> &mut BTreeMap { match self { - PlatformState::V0(v0) => v0.full_masternode_list_mut(), + PlatformState::V0(v0) => v0.chain_lock_validating_quorums_mut(), } } - fn hpmn_masternode_list_mut(&mut self) -> &mut BTreeMap { + fn previous_height_chain_lock_validating_quorums( + &self, + ) -> Option<&( + u32, + u32, + Option, + BTreeMap, + )> { match self { - PlatformState::V0(v0) => v0.hpmn_masternode_list_mut(), + PlatformState::V0(v0) => v0.previous_height_chain_lock_validating_quorums(), } } - fn take_next_validator_set_quorum_hash(&mut self) -> Option { + fn previous_height_chain_lock_validating_quorums_mut( + &mut self, + ) -> &mut Option<( + u32, + u32, + Option, + BTreeMap, + )> { match self { - PlatformState::V0(v0) => v0.take_next_validator_set_quorum_hash(), + PlatformState::V0(v0) => v0.previous_height_chain_lock_validating_quorums_mut(), } } - fn last_block_id_hash(&self) -> [u8; 32] { + fn full_masternode_list_mut(&mut self) -> &mut BTreeMap { match self { - PlatformState::V0(v0) => v0.last_block_id_hash(), + PlatformState::V0(v0) => v0.full_masternode_list_mut(), } } - fn any_block_info(&self) -> &BlockInfo { + fn hpmn_masternode_list_mut(&mut self) -> &mut BTreeMap { match self { - PlatformState::V0(v0) => v0.any_block_info(), + PlatformState::V0(v0) => v0.hpmn_masternode_list_mut(), + } + } + + fn last_committed_block_epoch_ref(&self) -> &Epoch { + match self { + PlatformState::V0(v0) => v0.last_committed_block_epoch_ref(), + } + } + + fn last_committed_block_id_hash(&self) -> [u8; 32] { + match self { + PlatformState::V0(v0) => v0.last_committed_block_id_hash(), } } } diff --git a/packages/rs-drive-abci/src/platform_types/platform_state/v0/mod.rs b/packages/rs-drive-abci/src/platform_types/platform_state/v0/mod.rs index af69a73643b..2cb112bdaf0 100644 --- a/packages/rs-drive-abci/src/platform_types/platform_state/v0/mod.rs +++ b/packages/rs-drive-abci/src/platform_types/platform_state/v0/mod.rs @@ -17,7 +17,9 @@ use crate::platform_types::masternode::Masternode; use crate::platform_types::validator_set::ValidatorSet; use dpp::block::block_info::{BlockInfo, DEFAULT_BLOCK_INFO}; use dpp::block::extended_block_info::v0::ExtendedBlockInfoV0Getters; +use dpp::bls_signatures::PublicKey as ThresholdBlsPublicKey; use dpp::version::{PlatformVersion, TryIntoPlatformVersioned}; +use drive::grovedb::batch::Op; use std::collections::BTreeMap; use std::fmt::{Debug, Formatter}; @@ -41,6 +43,25 @@ pub struct PlatformStateV0 { /// all members pub validator_sets: IndexMap, + /// The current quorums used for validating chain locks (400 60 for mainnet) + pub chain_lock_validating_quorums: BTreeMap, + + /// The slightly old quorums used for validating chain locks, it's important to keep + /// these because validation of signatures happens for the quorums that are 8 blocks before the + /// height written in the chain lock (400 60 for mainnet) + /// The first u32 is the core height at which these chain lock validating quorums were last active + /// The second u32 is the core height we are changing at. + /// The third u32 is the core height the previous chain lock validating quorums became active. + /// Keeping all three is important for verifying the chain locks, as we can detect edge cases where we + /// must check a chain lock with both the previous height chain lock validating quorums and the + /// current ones + pub previous_height_chain_lock_validating_quorums: Option<( + u32, + u32, + Option, + BTreeMap, + )>, + /// current full masternode list pub full_masternode_list: BTreeMap, @@ -112,6 +133,15 @@ pub(super) struct PlatformStateForSavingV0 { #[bincode(with_serde)] pub validator_sets: Vec<(Bytes32, ValidatorSet)>, + /// The 400 60 quorums used for validating chain locks + #[bincode(with_serde)] + pub chain_lock_validating_quorums: Vec<(Bytes32, ThresholdBlsPublicKey)>, + + /// The quorums used for validating chain locks from a slightly previous height. + #[bincode(with_serde)] + pub previous_height_chain_lock_validating_quorums: + Option<(u32, u32, Option, Vec<(Bytes32, ThresholdBlsPublicKey)>)>, + /// current full masternode list pub full_masternode_list: BTreeMap, @@ -141,6 +171,31 @@ impl TryFrom for PlatformStateForSavingV0 { .into_iter() .map(|(k, v)| (k.to_byte_array().into(), v)) .collect(), + chain_lock_validating_quorums: value + .chain_lock_validating_quorums + .into_iter() + .map(|(k, v)| (k.to_byte_array().into(), v)) + .collect(), + previous_height_chain_lock_validating_quorums: value + .previous_height_chain_lock_validating_quorums + .map( + |( + previous_height, + change_height, + previous_quorums_change_height, + inner_value, + )| { + ( + previous_height, + change_height, + previous_quorums_change_height, + inner_value + .into_iter() + .map(|(k, v)| (k.to_byte_array().into(), v)) + .collect(), + ) + }, + ), full_masternode_list: value .full_masternode_list .into_iter() @@ -183,6 +238,31 @@ impl From for PlatformStateV0 { .into_iter() .map(|(k, v)| (QuorumHash::from_byte_array(k.to_buffer()), v)) .collect(), + chain_lock_validating_quorums: value + .chain_lock_validating_quorums + .into_iter() + .map(|(k, v)| (QuorumHash::from_byte_array(k.to_buffer()), v)) + .collect(), + previous_height_chain_lock_validating_quorums: value + .previous_height_chain_lock_validating_quorums + .map( + |( + previous_height, + change_height, + previous_quorums_change_height, + inner_value, + )| { + ( + previous_height, + change_height, + previous_quorums_change_height, + inner_value + .into_iter() + .map(|(k, v)| (QuorumHash::from_byte_array(k.to_buffer()), v)) + .collect(), + ) + }, + ), full_masternode_list: value .full_masternode_list .into_iter() @@ -210,6 +290,8 @@ impl PlatformStateV0 { current_validator_set_quorum_hash: QuorumHash::all_zeros(), next_validator_set_quorum_hash: None, validator_sets: Default::default(), + chain_lock_validating_quorums: Default::default(), + previous_height_chain_lock_validating_quorums: None, full_masternode_list: Default::default(), hpmn_masternode_list: Default::default(), genesis_block_info: None, @@ -220,27 +302,27 @@ impl PlatformStateV0 { /// Platform state methods introduced in version 0 of Platform State Struct pub trait PlatformStateV0Methods { /// The height of the platform, only committed blocks increase height - fn height(&self) -> u64; + fn last_committed_height(&self) -> u64; /// The height of the platform, only committed blocks increase height - fn known_height_or(&self, default: u64) -> u64; + fn last_committed_known_height_or(&self, default: u64) -> u64; /// The height of the core blockchain that Platform knows about through chain locks - fn core_height(&self) -> u32; + fn last_committed_core_height(&self) -> u32; /// The height of the core blockchain that Platform knows about through chain locks - fn known_core_height_or(&self, default: u32) -> u32; + fn last_committed_known_core_height_or(&self, default: u32) -> u32; /// The last block time in milliseconds - fn last_block_time_ms(&self) -> Option; + fn last_committed_block_time_ms(&self) -> Option; /// The last quorum hash - fn last_quorum_hash(&self) -> [u8; 32]; + fn last_committed_quorum_hash(&self) -> [u8; 32]; /// The last block signature - fn last_block_signature(&self) -> [u8; 96]; + fn last_committed_block_signature(&self) -> [u8; 96]; /// The last block app hash - fn last_block_app_hash(&self) -> Option<[u8; 32]>; + fn last_committed_block_app_hash(&self) -> Option<[u8; 32]>; /// The last block height or 0 for genesis - fn last_block_height(&self) -> u64; + fn last_committed_block_height(&self) -> u64; /// The last block round - fn last_block_round(&self) -> u32; + fn last_committed_block_round(&self) -> u32; /// The current epoch - fn epoch(&self) -> Epoch; + fn last_committed_block_epoch(&self) -> Epoch; /// HPMN list len fn hpmn_list_len(&self) -> usize; /// Get the current quorum @@ -265,6 +347,9 @@ pub trait PlatformStateV0Methods { /// Returns the current validator sets. fn validator_sets(&self) -> &IndexMap; + /// Returns the current 400 60 quorums used to validate chain locks. + fn chain_lock_validating_quorums(&self) -> &BTreeMap; + /// Returns the full list of masternodes. fn full_masternode_list(&self) -> &BTreeMap; @@ -295,6 +380,27 @@ pub trait PlatformStateV0Methods { /// Sets the current validator sets. fn set_validator_sets(&mut self, sets: IndexMap); + /// Sets the current chain lock validating quorums. + fn set_chain_lock_validating_quorums( + &mut self, + quorums: BTreeMap, + ); + + /// Sets the current chain lock validating quorums and returns the old value. + fn replace_chain_lock_validating_quorums( + &mut self, + quorums: BTreeMap, + ) -> BTreeMap; + + /// Sets the previous chain lock validating quorums. + fn set_previous_chain_lock_validating_quorums( + &mut self, + previous_core_height: u32, + change_core_height: u32, + previous_quorums_change_height: Option, + quorums: BTreeMap, + ); + /// Sets the full masternode list. fn set_full_masternode_list(&mut self, list: BTreeMap); @@ -321,6 +427,21 @@ pub trait PlatformStateV0Methods { /// Returns a mutable reference to the current validator sets. fn validator_sets_mut(&mut self) -> &mut IndexMap; + /// Returns a mutable reference to the current chain lock validating quorums. + fn chain_lock_validating_quorums_mut( + &mut self, + ) -> &mut BTreeMap; + + /// Returns a mutable reference to the previous chain lock validating quorums. + fn previous_height_chain_lock_validating_quorums_mut( + &mut self, + ) -> &mut Option<( + u32, + u32, + Option, + BTreeMap, + )>; + /// Returns a mutable reference to the full masternode list. fn full_masternode_list_mut(&mut self) -> &mut BTreeMap; @@ -328,14 +449,24 @@ pub trait PlatformStateV0Methods { fn hpmn_masternode_list_mut(&mut self) -> &mut BTreeMap; /// The epoch ref - fn epoch_ref(&self) -> &Epoch; + fn last_committed_block_epoch_ref(&self) -> &Epoch; /// The last block id hash - fn last_block_id_hash(&self) -> [u8; 32]; + fn last_committed_block_id_hash(&self) -> [u8; 32]; + + /// The previous height chain lock validating quorums + fn previous_height_chain_lock_validating_quorums( + &self, + ) -> Option<&( + u32, + u32, + Option, + BTreeMap, + )>; } impl PlatformStateV0Methods for PlatformStateV0 { /// The height of the platform, only committed blocks increase height - fn height(&self) -> u64 { + fn last_committed_height(&self) -> u64 { self.last_committed_block_info .as_ref() .map(|block_info| block_info.basic_info().height) @@ -343,7 +474,7 @@ impl PlatformStateV0Methods for PlatformStateV0 { } /// The height of the platform, only committed blocks increase height - fn known_height_or(&self, default: u64) -> u64 { + fn last_committed_known_height_or(&self, default: u64) -> u64 { self.last_committed_block_info .as_ref() .map(|block_info| block_info.basic_info().height) @@ -351,7 +482,7 @@ impl PlatformStateV0Methods for PlatformStateV0 { } /// The height of the core blockchain that Platform knows about through chain locks - fn core_height(&self) -> u32 { + fn last_committed_core_height(&self) -> u32 { self.last_committed_block_info .as_ref() .map(|block_info| block_info.basic_info().core_height) @@ -364,7 +495,7 @@ impl PlatformStateV0Methods for PlatformStateV0 { } /// The height of the core blockchain that Platform knows about through chain locks - fn known_core_height_or(&self, default: u32) -> u32 { + fn last_committed_known_core_height_or(&self, default: u32) -> u32 { self.last_committed_block_info .as_ref() .map(|block_info| block_info.basic_info().core_height) @@ -377,14 +508,14 @@ impl PlatformStateV0Methods for PlatformStateV0 { } /// The last block time in milliseconds - fn last_block_time_ms(&self) -> Option { + fn last_committed_block_time_ms(&self) -> Option { self.last_committed_block_info .as_ref() .map(|block_info| block_info.basic_info().time_ms) } /// The last quorum hash - fn last_quorum_hash(&self) -> [u8; 32] { + fn last_committed_quorum_hash(&self) -> [u8; 32] { self.last_committed_block_info .as_ref() .map(|block_info| *block_info.quorum_hash()) @@ -392,7 +523,7 @@ impl PlatformStateV0Methods for PlatformStateV0 { } /// The last block id hash - fn last_block_id_hash(&self) -> [u8; 32] { + fn last_committed_block_id_hash(&self) -> [u8; 32] { self.last_committed_block_info .as_ref() .map(|block_info| *block_info.block_id_hash()) @@ -400,7 +531,7 @@ impl PlatformStateV0Methods for PlatformStateV0 { } /// The last block signature - fn last_block_signature(&self) -> [u8; 96] { + fn last_committed_block_signature(&self) -> [u8; 96] { self.last_committed_block_info .as_ref() .map(|block_info| *block_info.signature()) @@ -408,14 +539,14 @@ impl PlatformStateV0Methods for PlatformStateV0 { } /// The last block app hash - fn last_block_app_hash(&self) -> Option<[u8; 32]> { + fn last_committed_block_app_hash(&self) -> Option<[u8; 32]> { self.last_committed_block_info .as_ref() .map(|block_info| *block_info.app_hash()) } /// The last block height or 0 for genesis - fn last_block_height(&self) -> u64 { + fn last_committed_block_height(&self) -> u64 { self.last_committed_block_info .as_ref() .map(|block_info| block_info.basic_info().height) @@ -423,7 +554,7 @@ impl PlatformStateV0Methods for PlatformStateV0 { } /// The last block round - fn last_block_round(&self) -> u32 { + fn last_committed_block_round(&self) -> u32 { self.last_committed_block_info .as_ref() .map(|block_info| block_info.round()) @@ -431,14 +562,14 @@ impl PlatformStateV0Methods for PlatformStateV0 { } /// The current epoch - fn epoch(&self) -> Epoch { + fn last_committed_block_epoch(&self) -> Epoch { self.last_committed_block_info .as_ref() .map(|block_info| block_info.basic_info().epoch) .unwrap_or_default() } - fn epoch_ref(&self) -> &Epoch { + fn last_committed_block_epoch_ref(&self) -> &Epoch { self.last_committed_block_info .as_ref() .map(|block_info| &block_info.basic_info().epoch) @@ -489,6 +620,11 @@ impl PlatformStateV0Methods for PlatformStateV0 { &self.validator_sets } + /// Returns the current 400 60 quorums used to validate chain locks. + fn chain_lock_validating_quorums(&self) -> &BTreeMap { + &self.chain_lock_validating_quorums + } + /// Returns the full list of masternodes. fn full_masternode_list(&self) -> &BTreeMap { &self.full_masternode_list @@ -539,6 +675,38 @@ impl PlatformStateV0Methods for PlatformStateV0 { self.validator_sets = sets; } + /// Sets the current chain lock validating quorums. + fn set_chain_lock_validating_quorums( + &mut self, + quorums: BTreeMap, + ) { + self.chain_lock_validating_quorums = quorums; + } + + /// Swaps the current chain lock validating quorums and returns the old one + fn replace_chain_lock_validating_quorums( + &mut self, + quorums: BTreeMap, + ) -> BTreeMap { + std::mem::replace(&mut self.chain_lock_validating_quorums, quorums) + } + + /// Sets the previous chain lock validating quorums. + fn set_previous_chain_lock_validating_quorums( + &mut self, + previous_core_height: u32, + change_core_height: u32, + previous_quorums_change_height: Option, + quorums: BTreeMap, + ) { + self.previous_height_chain_lock_validating_quorums = Some(( + previous_core_height, + change_core_height, + previous_quorums_change_height, + quorums, + )); + } + /// Sets the full masternode list. fn set_full_masternode_list(&mut self, list: BTreeMap) { self.full_masternode_list = list; @@ -578,6 +746,34 @@ impl PlatformStateV0Methods for PlatformStateV0 { &mut self.validator_sets } + fn chain_lock_validating_quorums_mut( + &mut self, + ) -> &mut BTreeMap { + &mut self.chain_lock_validating_quorums + } + + fn previous_height_chain_lock_validating_quorums( + &self, + ) -> Option<&( + u32, + u32, + Option, + BTreeMap, + )> { + self.previous_height_chain_lock_validating_quorums.as_ref() + } + + fn previous_height_chain_lock_validating_quorums_mut( + &mut self, + ) -> &mut Option<( + u32, + u32, + Option, + BTreeMap, + )> { + &mut self.previous_height_chain_lock_validating_quorums + } + fn full_masternode_list_mut(&mut self) -> &mut BTreeMap { &mut self.full_masternode_list } diff --git a/packages/rs-drive-abci/src/platform_types/verify_chain_lock_result/mod.rs b/packages/rs-drive-abci/src/platform_types/verify_chain_lock_result/mod.rs new file mode 100644 index 00000000000..d09310b584f --- /dev/null +++ b/packages/rs-drive-abci/src/platform_types/verify_chain_lock_result/mod.rs @@ -0,0 +1,2 @@ +/// V0 +pub mod v0; diff --git a/packages/rs-drive-abci/src/platform_types/verify_chain_lock_result/v0/mod.rs b/packages/rs-drive-abci/src/platform_types/verify_chain_lock_result/v0/mod.rs new file mode 100644 index 00000000000..57d0293ba8b --- /dev/null +++ b/packages/rs-drive-abci/src/platform_types/verify_chain_lock_result/v0/mod.rs @@ -0,0 +1,12 @@ +/// A structure for returning the result of verification of a chain lock +pub struct VerifyChainLockResult { + /// If the chain lock signature represents a valid G2 BLS Element + pub(crate) chain_lock_signature_is_deserializable: bool, + /// If the chain lock was found to be valid based on platform state + pub(crate) found_valid_locally: Option, + /// If we were not able to validate based on platform state - ie the chain lock is too far in + /// the future + pub(crate) found_valid_by_core: Option, + /// Core is synced + pub(crate) core_is_synced: Option, +} diff --git a/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contract/v0/mod.rs b/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contract/v0/mod.rs index ab9cb627f2d..39da61433cd 100644 --- a/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contract/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contract/v0/mod.rs @@ -22,7 +22,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetDataContractRequestV0 { id, prove } = request; let contract_id: Identifier = check_validation_result_with_data!(id.try_into().map_err(|_| { @@ -39,11 +39,11 @@ impl Platform { version: Some(get_data_contract_response::Version::V0(GetDataContractResponseV0 { result: Some(get_data_contract_response::get_data_contract_response_v0::Result::Proof(Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), })), metadata: Some(metadata), })), diff --git a/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contract_history/v0/mod.rs b/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contract_history/v0/mod.rs index fad0100be91..ad58118f603 100644 --- a/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contract_history/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contract_history/v0/mod.rs @@ -25,7 +25,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetDataContractHistoryRequestV0 { id, limit, @@ -66,11 +66,11 @@ impl Platform { version: Some(get_data_contract_history_response::Version::V0(GetDataContractHistoryResponseV0 { result: Some(get_data_contract_history_response::get_data_contract_history_response_v0::Result::Proof(Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), })), metadata: Some(metadata), })), diff --git a/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contracts/v0/mod.rs b/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contracts/v0/mod.rs index b5f3e7f78ef..c3a2da2dc2d 100644 --- a/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contracts/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/data_contract_based_queries/data_contracts/v0/mod.rs @@ -23,7 +23,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetDataContractsRequestV0 { ids, prove } = request; let contract_ids = check_validation_result_with_data!(ids .into_iter() @@ -45,11 +45,11 @@ impl Platform { version: Some(get_data_contracts_response::Version::V0(GetDataContractsResponseV0 { result: Some(get_data_contracts_response::get_data_contracts_response_v0::Result::Proof(Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), })), metadata: Some(metadata), })), diff --git a/packages/rs-drive-abci/src/query/document_query/v0/mod.rs b/packages/rs-drive-abci/src/query/document_query/v0/mod.rs index e635c7d744c..0f52f904e15 100644 --- a/packages/rs-drive-abci/src/query/document_query/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/document_query/v0/mod.rs @@ -26,7 +26,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetDocumentsRequestV0 { data_contract_id, document_type: document_type_name, @@ -147,11 +147,11 @@ impl Platform { get_documents_response::get_documents_response_v0::Result::Proof( Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), }, ), ), diff --git a/packages/rs-drive-abci/src/query/identity_based_queries/balance/v0/mod.rs b/packages/rs-drive-abci/src/query/identity_based_queries/balance/v0/mod.rs index 8865f6c46a8..e271ce29c54 100644 --- a/packages/rs-drive-abci/src/query/identity_based_queries/balance/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/identity_based_queries/balance/v0/mod.rs @@ -21,7 +21,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetIdentityRequestV0 { id, prove } = get_identity_request; let identity_id: Identifier = check_validation_result_with_data!(id.try_into().map_err(|_| { @@ -40,11 +40,11 @@ impl Platform { version: Some(get_identity_balance_response::Version::V0(GetIdentityBalanceResponseV0 { result: Some(get_identity_balance_response::get_identity_balance_response_v0::Result::Proof(Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), })), metadata: Some(metadata), })), diff --git a/packages/rs-drive-abci/src/query/identity_based_queries/balance_and_revision/v0/mod.rs b/packages/rs-drive-abci/src/query/identity_based_queries/balance_and_revision/v0/mod.rs index 20b851ed4d6..2488a82fc23 100644 --- a/packages/rs-drive-abci/src/query/identity_based_queries/balance_and_revision/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/identity_based_queries/balance_and_revision/v0/mod.rs @@ -25,7 +25,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetIdentityRequestV0 { id, prove } = get_identity_request; let identity_id: Identifier = check_validation_result_with_data!(id.try_into().map_err(|_| { @@ -44,11 +44,11 @@ impl Platform { version: Some(get_identity_balance_and_revision_response::Version::V0(GetIdentityBalanceAndRevisionResponseV0 { result: Some(get_identity_balance_and_revision_response::get_identity_balance_and_revision_response_v0::Result::Proof(Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), })), metadata: Some(metadata), })), diff --git a/packages/rs-drive-abci/src/query/identity_based_queries/identities/v0/mod.rs b/packages/rs-drive-abci/src/query/identity_based_queries/identities/v0/mod.rs index d585053f717..4ea7ad8fead 100644 --- a/packages/rs-drive-abci/src/query/identity_based_queries/identities/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/identity_based_queries/identities/v0/mod.rs @@ -22,7 +22,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetIdentitiesRequestV0 { ids, prove } = get_identities_request; let identity_ids = check_validation_result_with_data!(ids .into_iter() @@ -50,11 +50,11 @@ impl Platform { get_identities_response::get_identities_response_v0::Result::Proof( Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), }, ), ), diff --git a/packages/rs-drive-abci/src/query/identity_based_queries/identities_by_public_key_hashes/v0/mod.rs b/packages/rs-drive-abci/src/query/identity_based_queries/identities_by_public_key_hashes/v0/mod.rs index 7235e4adbe6..d6ed8f5b99d 100644 --- a/packages/rs-drive-abci/src/query/identity_based_queries/identities_by_public_key_hashes/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/identity_based_queries/identities_by_public_key_hashes/v0/mod.rs @@ -26,7 +26,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetIdentitiesByPublicKeyHashesRequestV0 { public_key_hashes, prove, @@ -56,11 +56,11 @@ impl Platform { version: Some(get_identities_by_public_key_hashes_response::Version::V0(GetIdentitiesByPublicKeyHashesResponseV0 { result: Some(get_identities_by_public_key_hashes_response::get_identities_by_public_key_hashes_response_v0::Result::Proof(Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), })), metadata: Some(metadata), })), diff --git a/packages/rs-drive-abci/src/query/identity_based_queries/identity/v0/mod.rs b/packages/rs-drive-abci/src/query/identity_based_queries/identity/v0/mod.rs index 358ebd142bc..1fdc04da053 100644 --- a/packages/rs-drive-abci/src/query/identity_based_queries/identity/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/identity_based_queries/identity/v0/mod.rs @@ -22,7 +22,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetIdentityRequestV0 { id, prove } = get_identity_request; let identity_id: Identifier = check_validation_result_with_data!(id.try_into().map_err(|_| { @@ -42,11 +42,11 @@ impl Platform { result: Some( get_identity_response::get_identity_response_v0::Result::Proof(Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), }), ), metadata: Some(metadata), diff --git a/packages/rs-drive-abci/src/query/identity_based_queries/identity_by_public_key_hash/v0/mod.rs b/packages/rs-drive-abci/src/query/identity_based_queries/identity_by_public_key_hash/v0/mod.rs index 988a3e5d855..f25c0a85f2b 100644 --- a/packages/rs-drive-abci/src/query/identity_based_queries/identity_by_public_key_hash/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/identity_based_queries/identity_by_public_key_hash/v0/mod.rs @@ -24,7 +24,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetIdentityByPublicKeyHashRequestV0 { public_key_hash, prove, @@ -46,11 +46,11 @@ impl Platform { version: Some(get_identity_by_public_key_hash_response::Version::V0(GetIdentityByPublicKeyHashResponseV0 { result: Some(get_identity_by_public_key_hash_response::get_identity_by_public_key_hash_response_v0::Result::Proof(Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), })), metadata: Some(metadata), })), diff --git a/packages/rs-drive-abci/src/query/identity_based_queries/keys/v0/mod.rs b/packages/rs-drive-abci/src/query/identity_based_queries/keys/v0/mod.rs index 80b3bbb6088..374057d1e35 100644 --- a/packages/rs-drive-abci/src/query/identity_based_queries/keys/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/identity_based_queries/keys/v0/mod.rs @@ -79,7 +79,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetIdentityKeysRequestV0 { identity_id, request_type, @@ -142,11 +142,11 @@ impl Platform { version: Some(get_identity_keys_response::Version::V0(GetIdentityKeysResponseV0 { result: Some(get_identity_keys_response::get_identity_keys_response_v0::Result::Proof(Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), })), metadata: Some(metadata), })), diff --git a/packages/rs-drive-abci/src/query/proofs/v0/mod.rs b/packages/rs-drive-abci/src/query/proofs/v0/mod.rs index 7969042161f..584eac412e6 100644 --- a/packages/rs-drive-abci/src/query/proofs/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/proofs/v0/mod.rs @@ -24,7 +24,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetProofsRequestV0 { identities, contracts, @@ -109,11 +109,11 @@ impl Platform { result: Some(get_proofs_response::get_proofs_response_v0::Result::Proof( Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), }, )), metadata: Some(metadata), diff --git a/packages/rs-drive-abci/src/query/response_metadata/v0/mod.rs b/packages/rs-drive-abci/src/query/response_metadata/v0/mod.rs index a13e0878c53..492db68f4cf 100644 --- a/packages/rs-drive-abci/src/query/response_metadata/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/response_metadata/v0/mod.rs @@ -6,10 +6,10 @@ use dapi_grpc::platform::v0::ResponseMetadata; impl Platform { pub(in crate::query) fn response_metadata_v0(&self, state: &PlatformState) -> ResponseMetadata { ResponseMetadata { - height: state.height(), - core_chain_locked_height: state.core_height(), - epoch: state.epoch().index as u32, - time_ms: state.last_block_time_ms().unwrap_or_default(), + height: state.last_committed_height(), + core_chain_locked_height: state.last_committed_core_height(), + epoch: state.last_committed_block_epoch().index as u32, + time_ms: state.last_committed_block_time_ms().unwrap_or_default(), chain_id: self.config.abci.chain_id.clone(), protocol_version: state.current_protocol_version_in_consensus(), } diff --git a/packages/rs-drive-abci/src/query/system/epoch_infos/v0/mod.rs b/packages/rs-drive-abci/src/query/system/epoch_infos/v0/mod.rs index 9bc9448df81..a4961af007b 100644 --- a/packages/rs-drive-abci/src/query/system/epoch_infos/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/system/epoch_infos/v0/mod.rs @@ -23,7 +23,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetEpochsInfoRequestV0 { start_epoch, count, @@ -35,7 +35,7 @@ impl Platform { if ascending { 0 } else { - state.epoch_ref().index as u32 + state.last_committed_block_epoch_ref().index as u32 } }); @@ -70,11 +70,11 @@ impl Platform { get_epochs_info_response::get_epochs_info_response_v0::Result::Proof( Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), }, ), ), diff --git a/packages/rs-drive-abci/src/query/system/version_upgrade_state/v0/mod.rs b/packages/rs-drive-abci/src/query/system/version_upgrade_state/v0/mod.rs index c891b479069..44a2cbc283e 100644 --- a/packages/rs-drive-abci/src/query/system/version_upgrade_state/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/system/version_upgrade_state/v0/mod.rs @@ -23,7 +23,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetProtocolVersionUpgradeStateRequestV0 { prove } = request; let response_data = if prove { @@ -38,11 +38,11 @@ impl Platform { get_protocol_version_upgrade_state_response::get_protocol_version_upgrade_state_response_v0::Result::Proof( Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), }, ), ), diff --git a/packages/rs-drive-abci/src/query/system/version_upgrade_vote_status/v0/mod.rs b/packages/rs-drive-abci/src/query/system/version_upgrade_vote_status/v0/mod.rs index 1948a1f718e..661a2660114 100644 --- a/packages/rs-drive-abci/src/query/system/version_upgrade_vote_status/v0/mod.rs +++ b/packages/rs-drive-abci/src/query/system/version_upgrade_vote_status/v0/mod.rs @@ -25,7 +25,7 @@ impl Platform { platform_version: &PlatformVersion, ) -> Result>, Error> { let metadata = self.response_metadata_v0(state); - let quorum_type = self.config.quorum_type() as u32; + let quorum_type = self.config.validator_set_quorum_type() as u32; let GetProtocolVersionUpgradeVoteStatusRequestV0 { start_pro_tx_hash, count, @@ -71,11 +71,11 @@ impl Platform { get_protocol_version_upgrade_vote_status_response::get_protocol_version_upgrade_vote_status_response_v0::Result::Proof( Proof { grovedb_proof: proof, - quorum_hash: state.last_quorum_hash().to_vec(), + quorum_hash: state.last_committed_quorum_hash().to_vec(), quorum_type, - block_id_hash: state.last_block_id_hash().to_vec(), - signature: state.last_block_signature().to_vec(), - round: state.last_block_round(), + block_id_hash: state.last_committed_block_id_hash().to_vec(), + signature: state.last_committed_block_signature().to_vec(), + round: state.last_committed_block_round(), }, ), ), diff --git a/packages/rs-drive-abci/src/rpc/core.rs b/packages/rs-drive-abci/src/rpc/core.rs index ab0c9b59a5f..941459325f5 100644 --- a/packages/rs-drive-abci/src/rpc/core.rs +++ b/packages/rs-drive-abci/src/rpc/core.rs @@ -24,8 +24,11 @@ pub trait CoreRPCLike { /// Get block hash by height fn get_block_hash(&self, height: CoreHeight) -> Result; - /// Get block hash by height - fn get_best_chain_lock(&self) -> Result; + /// Get the best chain lock + fn get_best_chain_lock(&self) -> Result; + + /// Submit a chain lock + fn submit_chain_lock(&self, chain_lock: &ChainLock) -> Result; /// Get transaction fn get_transaction(&self, tx_id: &Txid) -> Result; @@ -109,13 +112,7 @@ pub trait CoreRPCLike { ) -> Result; /// Verify a chain lock signature - /// If `max_height` is provided the chain lock will be verified - /// against quorums available at this height - fn verify_chain_lock( - &self, - chain_lock: &ChainLock, - max_height: Option, - ) -> Result; + fn verify_chain_lock(&self, chain_lock: &ChainLock) -> Result; /// Returns masternode sync status fn masternode_sync_status(&self) -> Result; @@ -202,19 +199,12 @@ impl CoreRPCLike for DefaultCoreRPC { retry!(self.inner.get_block_hash(height)) } - fn get_best_chain_lock(&self) -> Result { - //no need to retry on this one - let GetBestChainLockResult { - blockhash, - height, - signature, - known_block: _, - } = self.inner.get_best_chain_lock()?; - Ok(CoreChainLock { - core_block_height: height, - core_block_hash: blockhash.to_byte_array().to_vec(), - signature, - }) + fn get_best_chain_lock(&self) -> Result { + retry!(self.inner.get_best_chain_lock()) + } + + fn submit_chain_lock(&self, chain_lock: &ChainLock) -> Result { + retry!(self.inner.submit_chain_lock(chain_lock)) } fn get_transaction(&self, tx_id: &Txid) -> Result { @@ -300,19 +290,15 @@ impl CoreRPCLike for DefaultCoreRPC { } /// Verify a chain lock signature - /// If `max_height` is provided the chain lock will be verified - /// against quorums available at this height - fn verify_chain_lock( - &self, - chain_lock: &ChainLock, - max_height: Option, - ) -> Result { + fn verify_chain_lock(&self, chain_lock: &ChainLock) -> Result { let block_hash = chain_lock.block_hash.to_string(); let signature = hex::encode(chain_lock.signature); - retry!(self - .inner - .get_verifychainlock(block_hash.as_str(), &signature, max_height)) + retry!(self.inner.get_verifychainlock( + block_hash.as_str(), + &signature, + Some(chain_lock.block_height) + )) } /// Returns masternode sync status diff --git a/packages/rs-drive-abci/tests/strategy_tests/chain_lock_update.rs b/packages/rs-drive-abci/tests/strategy_tests/chain_lock_update.rs new file mode 100644 index 00000000000..a6a3e57e894 --- /dev/null +++ b/packages/rs-drive-abci/tests/strategy_tests/chain_lock_update.rs @@ -0,0 +1,87 @@ +#[cfg(test)] +mod tests { + use dpp::dashcore::hashes::Hash; + use dpp::dashcore::{BlockHash, ChainLock}; + use tenderdash_abci::proto::types::CoreChainLock; + + use crate::execution::run_chain_for_strategy; + use crate::strategy::CoreHeightIncrease::RandomCoreHeightIncrease; + use crate::strategy::{MasternodeListChangesStrategy, NetworkStrategy}; + use drive_abci::config::{ExecutionConfig, PlatformConfig, PlatformTestConfig}; + use drive_abci::platform_types::platform_state::v0::PlatformStateV0Methods; + use drive_abci::platform_types::validator_set::v0::ValidatorSetV0Getters; + use drive_abci::test::helpers::setup::TestPlatformBuilder; + use strategy_tests::frequency::Frequency; + use strategy_tests::Strategy; + + #[test] + fn run_chain_lock_update_quorums_not_changing() { + // The point of this test is to check that chain locks can be validated in the + // simple case where quorums do not change + let strategy = NetworkStrategy { + strategy: Strategy { + contracts_with_updates: vec![], + operations: vec![], + start_identities: vec![], + identities_inserts: Frequency { + times_per_block_range: Default::default(), + chance_per_block: None, + }, + signer: None, + }, + total_hpmns: 100, + extra_normal_mns: 400, + validator_quorum_count: 24, + chain_lock_quorum_count: 4, + upgrading_info: None, + core_height_increase: RandomCoreHeightIncrease(Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }), + proposer_strategy: MasternodeListChangesStrategy { + new_hpmns: Default::default(), + removed_hpmns: Default::default(), + updated_hpmns: Default::default(), + banned_hpmns: Default::default(), + unbanned_hpmns: Default::default(), + changed_ip_hpmns: Default::default(), + changed_p2p_port_hpmns: Default::default(), + changed_http_port_hpmns: Default::default(), + new_masternodes: Default::default(), + removed_masternodes: Default::default(), + updated_masternodes: Default::default(), + banned_masternodes: Default::default(), + unbanned_masternodes: Default::default(), + changed_ip_masternodes: Default::default(), + }, + rotate_quorums: true, + failure_testing: None, + query_testing: None, + verify_state_transition_results: false, + independent_process_proposal_verification: true, + sign_chain_locks: true, + ..Default::default() + }; + + let quorum_size = 100; + + let config = PlatformConfig { + validator_set_quorum_size: quorum_size, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_400_60".to_string(), + execution: ExecutionConfig { + verify_sum_trees: true, + validator_set_rotation_block_count: 25, + ..Default::default() + }, + block_spacing_ms: 3000, + testing_configs: PlatformTestConfig::default_with_no_block_signing(), + ..Default::default() + }; + let mut platform = TestPlatformBuilder::new() + .with_config(config.clone()) + .build_with_mock_rpc(); + + run_chain_for_strategy(&mut platform, 50, strategy, config, 13); + } +} diff --git a/packages/rs-drive-abci/tests/strategy_tests/core_update_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/core_update_tests.rs index 223f9ee0f2b..9c097506251 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/core_update_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/core_update_tests.rs @@ -1,8 +1,11 @@ #[cfg(test)] mod tests { + use dpp::dashcore::hashes::Hash; + use dpp::dashcore::{BlockHash, ChainLock}; use tenderdash_abci::proto::types::CoreChainLock; use crate::execution::run_chain_for_strategy; + use crate::strategy::CoreHeightIncrease::RandomCoreHeightIncrease; use crate::strategy::{MasternodeListChangesStrategy, NetworkStrategy}; use drive_abci::config::{ExecutionConfig, PlatformConfig, PlatformTestConfig}; use drive_abci::platform_types::platform_state::v0::PlatformStateV0Methods; @@ -26,12 +29,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..2, chance_per_block: None, - }, + }), proposer_strategy: MasternodeListChangesStrategy { new_hpmns: Default::default(), removed_hpmns: Default::default(), @@ -61,10 +65,12 @@ mod tests { let quorum_size = 100; let config = PlatformConfig { - quorum_size, + validator_set_quorum_size: quorum_size, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -75,16 +81,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 1, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); let outcome = run_chain_for_strategy(&mut platform, 50, strategy, config, 13); // we expect to see quorums with banned members @@ -132,12 +128,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..2, chance_per_block: None, - }, + }), proposer_strategy: MasternodeListChangesStrategy { new_hpmns: Default::default(), removed_hpmns: Frequency { @@ -167,10 +164,12 @@ mod tests { let quorum_size = 100; let config = PlatformConfig { - quorum_size, + validator_set_quorum_size: quorum_size, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -181,16 +180,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 1, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); let outcome = run_chain_for_strategy(&mut platform, 50, strategy, config, 13); // we expect to see quorums with banned members @@ -224,12 +213,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..2, chance_per_block: None, - }, + }), proposer_strategy: MasternodeListChangesStrategy { new_hpmns: Default::default(), removed_hpmns: Default::default(), @@ -262,10 +252,12 @@ mod tests { let quorum_size = 100; let config = PlatformConfig { - quorum_size, + validator_set_quorum_size: quorum_size, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -276,16 +268,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 1, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); let outcome = run_chain_for_strategy(&mut platform, 26, strategy, config, 13); // We should also see validator sets with less than the quorum size diff --git a/packages/rs-drive-abci/tests/strategy_tests/execution.rs b/packages/rs-drive-abci/tests/strategy_tests/execution.rs index c51a376673f..57f809f922e 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/execution.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/execution.rs @@ -2,8 +2,8 @@ use crate::masternodes; use crate::masternodes::{GenerateTestMasternodeUpdates, MasternodeListItemWithUpdates}; use crate::query::ProofVerification; use crate::strategy::{ - ChainExecutionOutcome, ChainExecutionParameters, NetworkStrategy, StrategyRandomness, - ValidatorVersionMigration, + ChainExecutionOutcome, ChainExecutionParameters, CoreHeightIncrease, NetworkStrategy, + StrategyRandomness, ValidatorVersionMigration, }; use crate::verify_state_transitions::verify_state_transitions_were_or_were_not_executed; use dashcore_rpc::dashcore::hashes::Hash; @@ -20,6 +20,10 @@ use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV use strategy_tests::operations::FinalizeBlockOperation::IdentityAddKeys; use dashcore_rpc::json::{ExtendedQuorumListResult, SoftforkInfo}; +use dpp::bls_signatures::PrivateKey; +use dpp::dashcore::consensus::Encodable; +use dpp::dashcore::hashes::{sha256d, HashEngine}; +use dpp::dashcore::{ChainLock, QuorumSigningRequestId, VarInt}; use drive_abci::abci::AbciApplication; use drive_abci::config::PlatformConfig; use drive_abci::mimic::test_quorum::TestQuorumInfo; @@ -27,10 +31,11 @@ use drive_abci::mimic::{MimicExecuteBlockOptions, MimicExecuteBlockOutcome}; use drive_abci::platform_types::epoch_info::v0::EpochInfoV0; use drive_abci::platform_types::platform::Platform; use drive_abci::platform_types::platform_state::v0::PlatformStateV0Methods; -use drive_abci::rpc::core::MockCoreRPCLike; +use drive_abci::rpc::core::{CoreRPCLike, MockCoreRPCLike}; use drive_abci::test::fixture::abci::static_init_chain_request; +use platform_version::version::PlatformVersion; use rand::prelude::{SliceRandom, StdRng}; -use rand::SeedableRng; +use rand::{Rng, SeedableRng}; use std::collections::{BTreeMap, HashMap}; use tenderdash_abci::proto::abci::{ResponseInitChain, ValidatorSetUpdate}; use tenderdash_abci::proto::crypto::public_key::Sum::Bls12381; @@ -45,23 +50,42 @@ pub(crate) fn run_chain_for_strategy( config: PlatformConfig, seed: u64, ) -> ChainExecutionOutcome { - let quorum_count = strategy.quorum_count; // We assume 24 quorums - let quorum_size = config.quorum_size; + let validator_quorum_count = strategy.validator_quorum_count; // In most tests 24 quorums + let chain_lock_quorum_count = strategy.chain_lock_quorum_count; // In most tests 4 quorums when not the same as validator + let validator_set_quorum_size = config.validator_set_quorum_size; + let chain_lock_quorum_size = config.chain_lock_quorum_size; let mut rng = StdRng::seed_from_u64(seed); let any_changes_in_strategy = strategy.proposer_strategy.any_is_set(); let updated_proposers_in_strategy = strategy.proposer_strategy.any_kind_of_update_is_set(); + let core_height_increase = strategy.core_height_increase.clone(); + + let max_core_height = + core_height_increase.max_core_height(block_count, strategy.initial_core_height); + + let chain_lock_quorum_type = config.chain_lock_quorum_type(); + + let sign_chain_locks = strategy.sign_chain_locks; + + let mut core_blocks = BTreeMap::new(); + let mut block_rng = StdRng::seed_from_u64(rng.gen()); // so we don't need to regenerate tests + + for x in strategy.initial_core_height..max_core_height + 1 { + let block_hash: [u8; 32] = block_rng.gen(); + core_blocks.insert(x, block_hash); + } + let ( initial_masternodes_with_updates, initial_hpmns_with_updates, with_extra_masternodes_with_updates, with_extra_hpmns_with_updates, ) = if any_changes_in_strategy { - let approximate_end_core_height = - ((block_count as f64) * strategy.core_height_increase.average_event_count()) as u32; - let end_core_height = approximate_end_core_height * 2; //let's be safe + let end_core_height = strategy + .core_height_increase + .max_core_height(block_count, strategy.initial_core_height); let generate_updates = if updated_proposers_in_strategy { Some(GenerateTestMasternodeUpdates { start_core_height: config.abci.genesis_core_height, @@ -189,28 +213,33 @@ pub(crate) fn run_chain_for_strategy( ) }; + let initial_all_masternodes: Vec<_> = initial_masternodes_with_updates + .into_iter() + .chain(initial_hpmns_with_updates.clone()) + .collect(); + let all_hpmns_with_updates = with_extra_hpmns_with_updates .iter() .max_by_key(|(key, _)| *key) .map(|(_, v)| v.clone()) .unwrap_or(initial_hpmns_with_updates.clone()); - let total_quorums = if strategy.rotate_quorums { - quorum_count * 10 + let total_validator_quorums = if strategy.rotate_quorums { + validator_quorum_count * 10 } else { - quorum_count + validator_quorum_count }; - let quorums = masternodes::generate_test_quorums( - total_quorums as usize, + let validator_quorums = masternodes::generate_test_quorums( + total_validator_quorums as usize, initial_hpmns_with_updates .iter() .map(|hpmn| &hpmn.masternode), - quorum_size as usize, + validator_set_quorum_size as usize, &mut rng, ); - let mut quorums_details: Vec<(QuorumHash, ExtendedQuorumDetails)> = quorums + let mut quorums_details: Vec<(QuorumHash, ExtendedQuorumDetails)> = validator_quorums .keys() .map(|quorum_hash| { ( @@ -228,6 +257,47 @@ pub(crate) fn run_chain_for_strategy( quorums_details.shuffle(&mut rng); + let (chain_lock_quorums, chain_lock_quorums_details) = + if config.validator_set_quorum_type != config.chain_lock_quorum_type { + let total_chain_lock_quorums = if strategy.rotate_quorums { + chain_lock_quorum_count * 10 + } else { + chain_lock_quorum_count + }; + + let chain_lock_quorums = masternodes::generate_test_quorums( + total_chain_lock_quorums as usize, + initial_all_masternodes + .iter() + .map(|masternode| &masternode.masternode), + chain_lock_quorum_size as usize, + &mut rng, + ); + + let mut chain_lock_quorums_details: Vec<(QuorumHash, ExtendedQuorumDetails)> = + chain_lock_quorums + .keys() + .map(|quorum_hash| { + ( + *quorum_hash, + ExtendedQuorumDetails { + creation_height: 0, + quorum_index: None, + mined_block_hash: BlockHash::all_zeros(), + num_valid_members: 0, + health_ratio: 0.0, + }, + ) + }) + .collect(); + + chain_lock_quorums_details.shuffle(&mut rng); + + (chain_lock_quorums, chain_lock_quorums_details) + } else { + (BTreeMap::new(), vec![]) + }; + let start_core_height = platform.config.abci.genesis_core_height; platform @@ -266,15 +336,15 @@ pub(crate) fn run_chain_for_strategy( .core_rpc .expect_get_quorum_listextended() .returning(move |core_height: Option| { - let extended_info = if !strategy.rotate_quorums { + let validator_set_extended_info = if !strategy.rotate_quorums { quorums_details.clone().into_iter().collect() } else { let core_height = core_height.expect("expected a core height"); // if we rotate quorums we shouldn't give back the same ones every time let start_range = core_height / 24; - let end_range = start_range + quorum_count as u32; - let start_range = start_range % total_quorums as u32; - let end_range = end_range % total_quorums as u32; + let end_range = start_range + validator_quorum_count as u32; + let start_range = start_range % total_validator_quorums as u32; + let end_range = end_range % total_validator_quorums as u32; if end_range > start_range { quorums_details @@ -287,7 +357,7 @@ pub(crate) fn run_chain_for_strategy( let first_range = quorums_details .iter() .skip(start_range as usize) - .take((total_quorums as u32 - start_range) as usize); + .take((total_validator_quorums as u32 - start_range) as usize); let second_range = quorums_details.iter().take(end_range as usize); first_range .chain(second_range) @@ -296,15 +366,24 @@ pub(crate) fn run_chain_for_strategy( } }; - let result = ExtendedQuorumListResult { - quorums_by_type: HashMap::from([(QuorumType::Llmq100_67, extended_info)]), - }; + let mut quorums_by_type = + HashMap::from([(QuorumType::Llmq100_67, validator_set_extended_info)]); + + if !chain_lock_quorums_details.is_empty() { + quorums_by_type.insert( + QuorumType::Llmq400_60, + chain_lock_quorums_details.clone().into_iter().collect(), + ); + } + + let result = ExtendedQuorumListResult { quorums_by_type }; Ok(result) }); - let quorums_info: HashMap = quorums + let all_quorums_info: HashMap = validator_quorums .iter() + .chain(chain_lock_quorums.iter()) .map(|(quorum_hash, test_quorum_info)| (*quorum_hash, test_quorum_info.into())) .collect(); @@ -312,17 +391,12 @@ pub(crate) fn run_chain_for_strategy( .core_rpc .expect_get_quorum_info() .returning(move |_, quorum_hash: &QuorumHash, _| { - Ok(quorums_info + Ok(all_quorums_info .get::(quorum_hash) .unwrap_or_else(|| panic!("expected to get quorum {}", hex::encode(quorum_hash))) .clone()) }); - let initial_all_masternodes: Vec<_> = initial_masternodes_with_updates - .into_iter() - .chain(initial_hpmns_with_updates.clone()) - .collect(); - platform .core_rpc .expect_get_protx_diff_with_masternodes() @@ -467,11 +541,123 @@ pub(crate) fn run_chain_for_strategy( Ok(diff) }); + let mut core_height = strategy.initial_core_height; + + let mut core_height_increase = strategy.core_height_increase.clone(); + let mut core_height_rng = rng.clone(); + + let chain_lock_quorums_private_keys: BTreeMap = chain_lock_quorums + .iter() + .map(|(quorum_hash, info)| { + let bytes = info.private_key.to_bytes(); + let fixed_bytes: [u8; 32] = bytes + .as_slice() + .try_into() + .expect("Expected a byte array of length 32"); + (quorum_hash.clone(), fixed_bytes) + }) + .collect(); + + platform + .core_rpc + .expect_get_best_chain_lock() + .returning(move || { + let block_height = match &mut core_height_increase { + CoreHeightIncrease::NoCoreHeightIncrease + | CoreHeightIncrease::RandomCoreHeightIncrease(_) => core_height, + CoreHeightIncrease::KnownCoreHeightIncreases(core_block_heights) => { + if core_block_heights.len() == 1 { + *core_block_heights.first().unwrap() + } else { + core_block_heights.remove(0) + } + } + }; + + let block_hash = *core_blocks + .get(&block_height) + .expect(format!("expected a block hash to be known for {}", core_height).as_str()); + + let chain_lock = if sign_chain_locks { + // From DIP 8: https://github.com/dashpay/dips/blob/master/dip-0008.md#finalization-of-signed-blocks + // The request id is SHA256("clsig", blockHeight) and the message hash is the block hash of the previously successful attempt. + + let mut engine = QuorumSigningRequestId::engine(); + + // Prefix + let prefix_len = VarInt("clsig".len() as u64); + prefix_len + .consensus_encode(&mut engine) + .expect("expected to encode the prefix"); + + engine.input("clsig".as_bytes()); + engine.input(core_height.to_le_bytes().as_slice()); + + let request_id = QuorumSigningRequestId::from_engine(engine); + + // Based on the deterministic masternode list at the given height, a quorum must be selected that was active at the time this block was mined + + let quorum = Platform::::choose_quorum_thread_safe( + chain_lock_quorum_type, + &chain_lock_quorums_private_keys, + request_id.as_ref(), + PlatformVersion::latest(), //it should be okay to use latest here + ) + .expect("expected a quorum"); + + let (quorum_hash, quorum_private_key) = quorum.expect("expected to find a quorum"); + + // The signature must verify against the quorum public key and SHA256(llmqType, quorumHash, SHA256(height), blockHash). llmqType and quorumHash must be taken from the quorum selected in 1. + + let mut engine = sha256d::Hash::engine(); + + engine.input(&[chain_lock_quorum_type as u8]); + engine.input(quorum_hash.as_slice()); + engine.input(request_id.as_byte_array()); + engine.input(&block_hash); + + let message_digest = sha256d::Hash::from_engine(engine); + + let quorum_private_key = + PrivateKey::from_bytes(quorum_private_key.as_slice(), false) + .expect("expected to have a valid private key"); + let signature = quorum_private_key.sign(message_digest.as_byte_array()); + let chain_lock = ChainLock { + block_height: core_height, + block_hash: BlockHash::from_byte_array(block_hash), + signature: (*signature.to_bytes()).into(), + }; + + Ok(chain_lock) + } else { + let chain_lock = ChainLock { + block_height: core_height, + block_hash: BlockHash::from_byte_array(block_hash), + signature: [2; 96].into(), + }; + + Ok(chain_lock) + }; + + if let CoreHeightIncrease::RandomCoreHeightIncrease(core_height_increase) = + &core_height_increase + { + core_height += core_height_increase.events_if_hit(&mut core_height_rng) as u32; + }; + + chain_lock + }); + + platform + .core_rpc + .expect_submit_chain_lock() + .returning(move |chain_lock: &ChainLock| return Ok(chain_lock.block_height)); + create_chain_for_strategy( platform, block_count, all_hpmns_with_updates, - quorums, + validator_quorums, strategy, config, rng, @@ -613,7 +799,7 @@ pub(crate) fn continue_chain_for_strategy( StrategyRandomness::SeedEntropy(seed) => StdRng::seed_from_u64(seed), StrategyRandomness::RNGEntropy(rng) => rng, }; - let quorum_size = config.quorum_size; + let quorum_size = config.validator_set_quorum_size; let first_block_time = start_time_ms; let mut current_identities = vec![]; let mut signer = strategy.strategy.signer.clone().unwrap_or_default(); @@ -647,13 +833,11 @@ pub(crate) fn continue_chain_for_strategy( let mut state_transition_results_per_block = BTreeMap::new(); for block_height in block_start..(block_start + block_count) { + let state = platform.state.read().expect("lock is poisoned"); let epoch_info = EpochInfoV0::calculate( first_block_time, current_time_ms, - platform - .state - .read() - .expect("lock is poisoned") + state .last_committed_block_info() .as_ref() .map(|block_info| block_info.basic_info().time_ms), @@ -661,7 +845,9 @@ pub(crate) fn continue_chain_for_strategy( ) .expect("should calculate epoch info"); - current_core_height += strategy.core_height_increase.events_if_hit(&mut rng) as u32; + current_core_height = state.last_committed_core_height(); + + drop(state); let block_info = BlockInfo { time_ms: current_time_ms, @@ -747,12 +933,14 @@ pub(crate) fn continue_chain_for_strategy( expected_validation_errors.as_slice(), false, state_transitions.clone(), - strategy.max_tx_bytes_per_block, MimicExecuteBlockOptions { dont_finalize_block: strategy.dont_finalize_block(), rounds_before_finalization: strategy.failure_testing.as_ref().and_then( |failure_testing| failure_testing.rounds_before_successful_block, ), + max_tx_bytes_per_block: strategy.max_tx_bytes_per_block, + independent_process_proposal_verification: strategy + .independent_process_proposal_verification, }, ) .expect("expected to execute a block"), @@ -820,7 +1008,7 @@ pub(crate) fn continue_chain_for_strategy( query_strategy.query_chain_for_strategy( &ProofVerification { quorum_hash: ¤t_quorum_with_test_info.quorum_hash.into(), - quorum_type: config.quorum_type(), + quorum_type: config.validator_set_quorum_type(), app_version, chain_id: drive_abci::mimic::CHAIN_ID.to_string(), core_chain_locked_height: state_id.core_chain_locked_height, diff --git a/packages/rs-drive-abci/tests/strategy_tests/failures.rs b/packages/rs-drive-abci/tests/strategy_tests/failures.rs index 6f55d48d657..52fd3d1ef64 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/failures.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/failures.rs @@ -11,6 +11,9 @@ mod tests { use drive_abci::config::{ExecutionConfig, PlatformConfig, PlatformTestConfig}; + use crate::strategy::CoreHeightIncrease::{KnownCoreHeightIncreases, NoCoreHeightIncrease}; + use dpp::dashcore::hashes::Hash; + use dpp::dashcore::{BlockHash, ChainLock}; use dpp::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use dpp::data_contract::document_type::random_document::{ DocumentFieldFillSize, DocumentFieldFillType, @@ -61,12 +64,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: Some(FailureStrategy { @@ -81,10 +82,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -94,16 +97,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 10, strategy, config, 15); outcome @@ -146,12 +140,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: Some(FailureStrategy { @@ -166,10 +158,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -186,15 +180,15 @@ mod tests { .core_rpc .expect_get_best_chain_lock() .returning(move || { - let core_block_height = if core_block_heights.len() == 1 { + let block_height = if core_block_heights.len() == 1 { *core_block_heights.first().unwrap() } else { core_block_heights.remove(0) }; - Ok(CoreChainLock { - core_block_height, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); run_chain_for_strategy(&mut platform, 1, strategy.clone(), config.clone(), 15); @@ -212,11 +206,13 @@ mod tests { // We use the dpns contract and we insert two documents both with the same "name" // This is a common scenario we should see quite often let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { //we disable document triggers because we are using dpns and dpns needs a preorder use_document_triggers: false, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -346,13 +342,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, - + core_height_increase: KnownCoreHeightIncreases(vec![10, 11]), proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: Some(FailureStrategy { @@ -367,23 +360,6 @@ mod tests { ..Default::default() }; - let mut core_block_heights = vec![10, 11]; - - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - let core_block_height = if core_block_heights.len() == 1 { - *core_block_heights.first().unwrap() - } else { - core_block_heights.remove(0) - }; - Ok(CoreChainLock { - core_block_height, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); // On the first block we only have identities and contracts let outcome = run_chain_for_strategy(&mut platform, 2, strategy.clone(), config.clone(), 15); diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 3e4070df124..6a528ee5ad8 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -47,6 +47,7 @@ use strategy::{ }; use strategy_tests::Strategy; +mod chain_lock_update; mod core_update_tests; mod execution; mod failures; @@ -74,6 +75,8 @@ mod tests { DocumentAction, DocumentOp, IdentityUpdateOp, Operation, OperationType, }; + use crate::strategy::CoreHeightIncrease::RandomCoreHeightIncrease; + use dpp::dashcore::ChainLock; use dpp::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use dpp::data_contract::document_type::random_document::{ DocumentFieldFillSize, DocumentFieldFillType, @@ -131,12 +134,9 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -145,10 +145,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..ExecutionConfig::default() }, block_spacing_ms: 3000, @@ -159,16 +161,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); run_chain_for_strategy(&mut platform, 100, strategy, config, 15); } @@ -187,12 +179,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -201,10 +191,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..ExecutionConfig::default() }, block_spacing_ms: 3000, @@ -215,16 +207,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); run_chain_for_strategy(&mut platform, 50, strategy, config, 13); } @@ -243,12 +225,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -257,10 +237,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..ExecutionConfig::default() }, block_spacing_ms: 3000, @@ -274,17 +256,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); - let ChainExecutionOutcome { abci_app, proposers, @@ -379,12 +350,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: Some(FailureStrategy { @@ -399,10 +368,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..ExecutionConfig::default() }, block_spacing_ms: 3000, @@ -416,17 +387,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); - let ChainExecutionOutcome { abci_app, proposers, @@ -522,12 +482,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -536,10 +494,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -549,16 +509,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 100, strategy, config, 15); let balance = outcome @@ -573,7 +524,7 @@ mod tests { .expect("expected to fetch balances") .expect("expected to have an identity to get balance from"); - assert_eq!(balance, 99869044820) + assert_eq!(balance, 99868861500) } #[test] @@ -591,12 +542,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..3, chance_per_block: Some(0.01), - }, + }), proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -605,10 +557,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -619,16 +573,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); run_chain_for_strategy(&mut platform, 1000, strategy, config, 15); } @@ -647,12 +591,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..3, chance_per_block: Some(0.5), - }, + }), proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -662,10 +607,12 @@ mod tests { }; let hour_in_ms = 1000 * 60 * 60; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, ..Default::default() }, block_spacing_ms: hour_in_ms, @@ -676,16 +623,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 1000, strategy, config, 15); assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome @@ -710,12 +648,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..3, chance_per_block: Some(0.5), - }, + }), proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -726,10 +665,12 @@ mod tests { let hour_in_s = 60 * 60; let three_mins_in_ms = 1000 * 60 * 3; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, epoch_time_length_s: hour_in_s, ..Default::default() }, @@ -741,16 +682,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 1000, strategy, config, 15); assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome @@ -778,12 +710,13 @@ mod tests { }, total_hpmns: 500, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 5..6, chance_per_block: Some(0.5), - }, + }), proposer_strategy: Default::default(), rotate_quorums: true, failure_testing: None, @@ -792,10 +725,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 10, + validator_set_quorum_size: 10, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 300, @@ -806,16 +741,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); let ChainExecutionOutcome { abci_app, .. } = run_chain_for_strategy(&mut platform, 2000, strategy, config, 40); @@ -862,12 +787,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..2, chance_per_block: Some(0.2), - }, + }), proposer_strategy: MasternodeListChangesStrategy { new_hpmns: Frequency { times_per_block_range: 1..3, @@ -882,10 +808,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 10, + validator_set_quorum_size: 10, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 300, @@ -896,16 +824,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); let ChainExecutionOutcome { abci_app, .. } = run_chain_for_strategy(&mut platform, 300, strategy, config, 43); @@ -933,12 +851,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..2, chance_per_block: Some(0.2), - }, + }), proposer_strategy: MasternodeListChangesStrategy { new_hpmns: Frequency { times_per_block_range: 1..3, @@ -957,10 +876,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 10, + validator_set_quorum_size: 10, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 300, @@ -971,16 +892,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); let ChainExecutionOutcome { abci_app, .. } = run_chain_for_strategy(&mut platform, 300, strategy, config, 43); @@ -1007,12 +918,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..2, chance_per_block: Some(0.2), - }, + }), proposer_strategy: MasternodeListChangesStrategy { updated_hpmns: Frequency { times_per_block_range: 1..3, @@ -1027,10 +939,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 10, + validator_set_quorum_size: 10, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 300, @@ -1041,16 +955,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); let ChainExecutionOutcome { abci_app, proposers, @@ -1108,12 +1012,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1127,10 +1029,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -1140,16 +1044,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 100, strategy, config, 15); assert_eq!(outcome.identities.len(), 100); @@ -1170,12 +1065,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1185,10 +1078,12 @@ mod tests { }; let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, ..Default::default() }, block_spacing_ms: day_in_ms, @@ -1199,16 +1094,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 150, strategy, config, 15); assert_eq!(outcome.identities.len(), 150); assert_eq!(outcome.masternode_identity_balances.len(), 100); @@ -1228,7 +1114,7 @@ mod tests { .unwrap() .unwrap() ), - "31479dd805715e196773106ae8f00e1f28f8e5d4f8e3cbf21e6dd59f94643207".to_string() + "b1717304d3ce607569ca53d7f801df874578f510b352f23d8e4c087cdfed5697".to_string() ) } @@ -1255,12 +1141,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1269,10 +1153,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -1282,16 +1168,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 1, strategy, config, 15); outcome @@ -1367,12 +1244,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1381,10 +1256,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -1394,16 +1271,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 10, strategy, config, 15); outcome @@ -1474,12 +1342,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1488,10 +1354,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -1501,16 +1369,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + run_chain_for_strategy(&mut platform, 100, strategy, config, 15); } @@ -1557,12 +1416,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1572,10 +1429,12 @@ mod tests { }; let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, ..Default::default() }, block_spacing_ms: day_in_ms, @@ -1586,16 +1445,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15); assert_eq!(outcome.identities.len() as u64, block_count); assert_eq!(outcome.masternode_identity_balances.len(), 100); @@ -1668,12 +1518,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1683,10 +1531,12 @@ mod tests { }; let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, ..Default::default() }, block_spacing_ms: day_in_ms, @@ -1697,16 +1547,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15); assert_eq!(outcome.identities.len() as u64, block_count); assert_eq!(outcome.masternode_identity_balances.len(), 100); @@ -1779,12 +1620,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1794,10 +1633,12 @@ mod tests { }; let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, ..Default::default() }, block_spacing_ms: day_in_ms, @@ -1809,16 +1650,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15); assert_eq!(outcome.identities.len() as u64, block_count); assert_eq!(outcome.masternode_identity_balances.len(), 100); @@ -1838,7 +1670,7 @@ mod tests { .unwrap() .unwrap() ), - "1a1b119866b5cdff20d2fa04f3d2ff8e8d7349aa4b83e7ea05adeae0cfc9cb2c".to_string() + "40b51654a73ab89e98076819498a746dc179d54c53f599fa5ceeec57cec3576e".to_string() ) } @@ -1904,12 +1736,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1921,10 +1751,12 @@ mod tests { let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, epoch_time_length_s: 1576800, ..Default::default() }, @@ -1936,16 +1768,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15); assert_eq!(outcome.identities.len() as u64, 421); assert_eq!(outcome.masternode_identity_balances.len(), 100); @@ -2035,12 +1858,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -2052,10 +1873,12 @@ mod tests { let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, epoch_time_length_s: 1576800, ..Default::default() }, @@ -2067,16 +1890,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15); assert_eq!(outcome.identities.len() as u64, 86); assert_eq!(outcome.masternode_identity_balances.len(), 100); @@ -2111,12 +1925,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -2125,10 +1937,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -2138,16 +1952,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 10, strategy, config, 15); let max_initial_balance = 100000000000u64; // TODO: some centralized way for random test data (`arbitrary` maybe?) @@ -2193,12 +1998,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -2209,10 +2012,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -2222,16 +2027,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 10, strategy, config, 15); let state = outcome.abci_app.platform.state.read().unwrap(); let protocol_version = state.current_protocol_version_in_consensus(); @@ -2282,12 +2078,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -2298,10 +2092,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -2311,16 +2107,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 10, strategy, config, 15); let identities = outcome @@ -2378,12 +2165,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -2394,10 +2179,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -2407,16 +2194,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 10, strategy, config, 15); assert_eq!(outcome.identities.len(), 10); @@ -2439,12 +2217,12 @@ mod tests { }, total_hpmns: 50, extra_normal_mns: 0, - quorum_count: 10, + validator_quorum_count: 10, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..2, chance_per_block: None, - }, + }), proposer_strategy: Default::default(), rotate_quorums: true, failure_testing: None, @@ -2454,10 +2232,12 @@ mod tests { }; let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 3, + validator_set_quorum_size: 3, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 1, + validator_set_rotation_block_count: 1, ..Default::default() }, block_spacing_ms: day_in_ms, @@ -2480,10 +2260,10 @@ mod tests { .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); @@ -2596,12 +2376,12 @@ mod tests { }, total_hpmns: 500, extra_normal_mns: 0, - quorum_count: 100, + validator_quorum_count: 100, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..2, chance_per_block: None, - }, + }), proposer_strategy: Default::default(), rotate_quorums: true, failure_testing: None, @@ -2611,10 +2391,12 @@ mod tests { }; let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 3, + validator_set_quorum_size: 3, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 1, + validator_set_rotation_block_count: 1, epoch_time_length_s: 1576800, ..Default::default() }, @@ -2632,20 +2414,20 @@ mod tests { .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); platform_b .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); @@ -2665,7 +2447,7 @@ mod tests { ); assert_eq!( masternodes_fingerprint_a, - "3f13e499c5c49b04ab1edf2bbddca733fd9cf6f92875ccf51e827a6f4bf044e8".to_string() + "0154fd29f0062819ee6b8063ea02c9f3296ed9af33a4538ae98087edb1a75029".to_string() ); let masternodes_fingerprint_b = hash_to_hex_string( outcome_b @@ -2676,7 +2458,7 @@ mod tests { ); assert_eq!( masternodes_fingerprint_b, - "3f13e499c5c49b04ab1edf2bbddca733fd9cf6f92875ccf51e827a6f4bf044e8".to_string() + "0154fd29f0062819ee6b8063ea02c9f3296ed9af33a4538ae98087edb1a75029".to_string() ); let last_app_hash_a = outcome_a @@ -2724,12 +2506,12 @@ mod tests { }, total_hpmns: 500, extra_normal_mns: 0, - quorum_count: 100, + validator_quorum_count: 100, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..2, chance_per_block: None, - }, + }), proposer_strategy: Default::default(), rotate_quorums: true, failure_testing: None, @@ -2739,10 +2521,12 @@ mod tests { }; let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 3, + validator_set_quorum_size: 3, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 1, + validator_set_rotation_block_count: 1, ..Default::default() }, block_spacing_ms: day_in_ms, @@ -2759,20 +2543,20 @@ mod tests { .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); platform_b .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); @@ -2792,7 +2576,7 @@ mod tests { ); assert_eq!( masternodes_fingerprint_a, - "3f13e499c5c49b04ab1edf2bbddca733fd9cf6f92875ccf51e827a6f4bf044e8".to_string() + "0154fd29f0062819ee6b8063ea02c9f3296ed9af33a4538ae98087edb1a75029".to_string() ); let masternodes_fingerprint_b = hash_to_hex_string( outcome_b @@ -2803,7 +2587,7 @@ mod tests { ); assert_eq!( masternodes_fingerprint_b, - "3f13e499c5c49b04ab1edf2bbddca733fd9cf6f92875ccf51e827a6f4bf044e8".to_string() + "0154fd29f0062819ee6b8063ea02c9f3296ed9af33a4538ae98087edb1a75029".to_string() ); let last_app_hash_a = outcome_a @@ -2831,8 +2615,8 @@ mod tests { .into_iter() .filter(|(_, balance)| *balance != 0) .count(); - // we have a maximum 90 quorums, that could have been used, 4 were used twice - assert_eq!(balance_count, 86); + // we have a maximum 90 quorums, that could have been used, 6 were used twice + assert_eq!(balance_count, 84); } #[test] @@ -2852,12 +2636,9 @@ mod tests { }, total_hpmns: 500, extra_normal_mns: 0, - quorum_count: 100, + validator_quorum_count: 100, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -2867,10 +2648,12 @@ mod tests { }; let day_in_ms = 1000 * 60 * 60 * 24; let config = PlatformConfig { - quorum_size: 3, + validator_set_quorum_size: 3, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 1, + validator_set_rotation_block_count: 1, epoch_time_length_s: 1576800, ..Default::default() }, @@ -2885,17 +2668,6 @@ mod tests { .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); - let ChainExecutionOutcome { abci_app, proposers, @@ -2994,12 +2766,10 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -3009,10 +2779,12 @@ mod tests { }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -3023,16 +2795,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 15, strategy, config, 15); let balances = &outcome @@ -3067,10 +2830,12 @@ mod tests { ..Default::default() }; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 25, + validator_set_rotation_block_count: 25, ..Default::default() }, block_spacing_ms: 3000, @@ -3080,16 +2845,6 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); let outcome = run_chain_for_strategy(&mut platform, 1, strategy, config, 15); let state_transitions = outcome diff --git a/packages/rs-drive-abci/tests/strategy_tests/query.rs b/packages/rs-drive-abci/tests/strategy_tests/query.rs index 0da1dc98d93..17ae1ce383a 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/query.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/query.rs @@ -349,6 +349,9 @@ mod tests { use strategy_tests::Strategy; + use crate::strategy::CoreHeightIncrease::RandomCoreHeightIncrease; + use dpp::dashcore::hashes::Hash; + use dpp::dashcore::{BlockHash, ChainLock}; use tenderdash_abci::proto::types::CoreChainLock; use tenderdash_abci::Application; @@ -391,12 +394,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..3, chance_per_block: Some(0.5), - }, + }), proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -406,10 +410,12 @@ mod tests { }; let hour_in_ms = 1000 * 60 * 60; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, ..Default::default() }, block_spacing_ms: hour_in_ms, @@ -420,16 +426,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 1000, strategy, config, 15); assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome @@ -502,12 +499,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..3, chance_per_block: Some(0.5), - }, + }), proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -517,10 +515,12 @@ mod tests { }; let hour_in_ms = 1000 * 60 * 60; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, ..Default::default() }, block_spacing_ms: hour_in_ms, @@ -531,16 +531,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 1000, strategy, config, 15); assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome @@ -614,12 +605,13 @@ mod tests { }, total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: None, - core_height_increase: Frequency { + core_height_increase: RandomCoreHeightIncrease(Frequency { times_per_block_range: 1..3, chance_per_block: Some(0.5), - }, + }), proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -629,10 +621,12 @@ mod tests { }; let hour_in_ms = 1000 * 60 * 60; let config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 100, + validator_set_rotation_block_count: 100, ..Default::default() }, block_spacing_ms: hour_in_ms, @@ -643,16 +637,7 @@ mod tests { let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); - platform - .core_rpc - .expect_get_best_chain_lock() - .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), - }) - }); + let outcome = run_chain_for_strategy(&mut platform, 1000, strategy, config, 15); assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome @@ -678,7 +663,7 @@ mod tests { .read() .expect("expected to read state"); let protocol_version = platform_state.current_protocol_version_in_consensus(); - let current_epoch = platform_state.epoch_ref().index; + let current_epoch = platform_state.last_committed_block_epoch_ref().index; drop(platform_state); let platform_version = PlatformVersion::get(protocol_version) .expect("expected to get current platform version"); diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index 9bb4013dadf..1cae313520e 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -51,6 +51,7 @@ use dpp::state_transition::documents_batch_transition::document_transition::{Doc use drive::drive::document::query::QueryDocumentsOutcomeV0Methods; use dpp::state_transition::data_contract_create_transition::methods::v0::DataContractCreateTransitionMethodsV0; +use crate::strategy::CoreHeightIncrease::NoCoreHeightIncrease; use simple_signer::signer::SimpleSigner; #[derive(Clone, Debug, Default)] @@ -154,20 +155,74 @@ pub struct MasternodeChanges { pub masternode_change_port_chance: Frequency, } +#[derive(Clone, Debug, Default)] +pub enum CoreHeightIncrease { + #[default] + NoCoreHeightIncrease, + RandomCoreHeightIncrease(Frequency), + KnownCoreHeightIncreases(Vec), +} + +impl CoreHeightIncrease { + pub fn max_core_height(&self, block_count: u64, initial_core_height: u32) -> u32 { + match self { + NoCoreHeightIncrease => initial_core_height, + CoreHeightIncrease::RandomCoreHeightIncrease(frequency) => { + initial_core_height + frequency.max_event_count() as u32 * block_count as u32 + } + CoreHeightIncrease::KnownCoreHeightIncreases(values) => { + values.last().copied().unwrap_or(initial_core_height) + } + } + } + pub fn average_core_height(&self, block_count: u64, initial_core_height: u32) -> u32 { + match self { + NoCoreHeightIncrease => initial_core_height, + CoreHeightIncrease::RandomCoreHeightIncrease(frequency) => { + initial_core_height + frequency.average_event_count() as u32 * block_count as u32 + } + CoreHeightIncrease::KnownCoreHeightIncreases(values) => values + .get(values.len() / 2) + .copied() + .unwrap_or(initial_core_height), + } + } + + pub fn add_events_if_hit(&mut self, core_height: u32, rng: &mut StdRng) -> u32 { + match self { + NoCoreHeightIncrease => 0, + CoreHeightIncrease::RandomCoreHeightIncrease(frequency) => { + core_height + frequency.events_if_hit(rng) as u32 + } + CoreHeightIncrease::KnownCoreHeightIncreases(values) => { + if values.len() == 1 { + *values.get(0).unwrap() + } else { + values.pop().unwrap() + } + } + } + } +} + #[derive(Clone, Debug)] pub struct NetworkStrategy { pub strategy: Strategy, pub total_hpmns: u16, pub extra_normal_mns: u16, - pub quorum_count: u16, + pub validator_quorum_count: u16, + pub chain_lock_quorum_count: u16, + pub initial_core_height: u32, pub upgrading_info: Option, - pub core_height_increase: Frequency, + pub core_height_increase: CoreHeightIncrease, pub proposer_strategy: MasternodeListChangesStrategy, pub rotate_quorums: bool, pub failure_testing: Option, pub query_testing: Option, pub verify_state_transition_results: bool, - pub max_tx_bytes_per_block: i64, + pub max_tx_bytes_per_block: u64, + pub independent_process_proposal_verification: bool, + pub sign_chain_locks: bool, } impl Default for NetworkStrategy { @@ -176,18 +231,19 @@ impl Default for NetworkStrategy { strategy: Default::default(), total_hpmns: 100, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, + initial_core_height: 1, upgrading_info: None, - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + core_height_increase: NoCoreHeightIncrease, proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, query_testing: None, verify_state_transition_results: false, max_tx_bytes_per_block: 44800, + independent_process_proposal_verification: false, + sign_chain_locks: false, } } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/upgrade_fork_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/upgrade_fork_tests.rs index 8fe6259375f..e3954dfd102 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/upgrade_fork_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/upgrade_fork_tests.rs @@ -1,6 +1,8 @@ #[cfg(test)] mod tests { use dpp::block::extended_block_info::v0::ExtendedBlockInfoV0Getters; + use dpp::dashcore::hashes::Hash; + use dpp::dashcore::{BlockHash, ChainLock}; use dpp::version::PlatformVersion; use drive::drive::config::DriveConfig; use tenderdash_abci::proto::types::CoreChainLock; @@ -43,16 +45,14 @@ mod tests { }, total_hpmns: 460, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: Some(UpgradingInfo { current_protocol_version: 1, proposed_protocol_versions_with_weight: vec![(TEST_PROTOCOL_VERSION_2, 1)], upgrade_three_quarters_life: 0.1, }), - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -62,10 +62,12 @@ mod tests { }; let twenty_minutes_in_ms = 1000 * 60 * 20; let mut config = PlatformConfig { - quorum_size: 100, + validator_set_quorum_size: 100, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 125, + validator_set_rotation_block_count: 125, epoch_time_length_s: 1576800, ..Default::default() }, @@ -85,10 +87,10 @@ mod tests { .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); let ChainExecutionOutcome { @@ -138,7 +140,7 @@ mod tests { ); assert_eq!( (counter.get(&1), counter.get(&TEST_PROTOCOL_VERSION_2)), - (Some(&16), Some(&416)) + (Some(&17), Some(&414)) ); //most nodes were hit (63 were not) } @@ -216,7 +218,7 @@ mod tests { TEST_PROTOCOL_VERSION_2 ); assert_eq!(counter.get(&1), None); //no one has proposed 1 yet - assert_eq!(counter.get(&TEST_PROTOCOL_VERSION_2), Some(&157)); + assert_eq!(counter.get(&TEST_PROTOCOL_VERSION_2), Some(&154)); } // we locked in @@ -278,7 +280,7 @@ mod tests { TEST_PROTOCOL_VERSION_2 ); assert_eq!(counter.get(&1), None); //no one has proposed 1 yet - assert_eq!(counter.get(&TEST_PROTOCOL_VERSION_2), Some(&120)); + assert_eq!(counter.get(&TEST_PROTOCOL_VERSION_2), Some(&122)); } }) .expect("Failed to create thread with custom stack size"); @@ -312,16 +314,14 @@ mod tests { }, total_hpmns: 50, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: Some(UpgradingInfo { current_protocol_version: 1, proposed_protocol_versions_with_weight: vec![(TEST_PROTOCOL_VERSION_2, 1)], upgrade_three_quarters_life: 0.2, }), - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -332,10 +332,12 @@ mod tests { let one_hour_in_s = 60 * 60; let thirty_seconds_in_ms = 1000 * 30; let config = PlatformConfig { - quorum_size: 30, + validator_set_quorum_size: 30, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 30, + validator_set_rotation_block_count: 30, epoch_time_length_s: one_hour_in_s, ..Default::default() }, @@ -351,10 +353,10 @@ mod tests { .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); let ChainExecutionOutcome { @@ -574,16 +576,13 @@ mod tests { }, total_hpmns: 120, extra_normal_mns: 0, - quorum_count: 200, + validator_quorum_count: 200, upgrading_info: Some(UpgradingInfo { current_protocol_version: 1, proposed_protocol_versions_with_weight: vec![(TEST_PROTOCOL_VERSION_2, 1)], upgrade_three_quarters_life: 5.0, //it will take many epochs before we get enough nodes }), - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -593,10 +592,12 @@ mod tests { }; let hour_in_ms = 1000 * 60 * 60; let config = PlatformConfig { - quorum_size: 40, + validator_set_quorum_size: 40, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 80, + validator_set_rotation_block_count: 80, epoch_time_length_s: 1576800, ..Default::default() }, @@ -616,10 +617,10 @@ mod tests { .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); @@ -835,16 +836,13 @@ mod tests { }, total_hpmns: 200, extra_normal_mns: 0, - quorum_count: 100, + validator_quorum_count: 100, upgrading_info: Some(UpgradingInfo { current_protocol_version: 1, proposed_protocol_versions_with_weight: vec![(TEST_PROTOCOL_VERSION_2, 1)], upgrade_three_quarters_life: 5.0, }), - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -854,10 +852,12 @@ mod tests { }; let hour_in_ms = 1000 * 60 * 60; let mut config = PlatformConfig { - quorum_size: 50, + validator_set_quorum_size: 50, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 50, + validator_set_rotation_block_count: 50, epoch_time_length_s: 1576800, ..Default::default() }, @@ -877,10 +877,10 @@ mod tests { .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); let ChainExecutionOutcome { @@ -1013,7 +1013,7 @@ mod tests { }, total_hpmns: 200, extra_normal_mns: 0, - quorum_count: 100, + validator_quorum_count: 100, upgrading_info: Some(UpgradingInfo { current_protocol_version: 2, proposed_protocol_versions_with_weight: vec![ @@ -1022,10 +1022,7 @@ mod tests { ], upgrade_three_quarters_life: 0.1, }), - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1075,7 +1072,7 @@ mod tests { let counter = &drive_cache.protocol_versions_counter; assert_eq!( (counter.get(&1), counter.get(&TEST_PROTOCOL_VERSION_2)), - (Some(&170), Some(&24)) + (Some(&172), Some(&24)) ); //a lot nodes reverted to previous version, however this won't impact things assert_eq!( @@ -1138,7 +1135,7 @@ mod tests { let counter = &drive_cache.protocol_versions_counter; assert_eq!( (counter.get(&1), counter.get(&TEST_PROTOCOL_VERSION_2)), - (Some(&22), Some(&3)) + (Some(&23), Some(&2)) ); assert_eq!( platform @@ -1197,7 +1194,7 @@ mod tests { }, total_hpmns: 200, extra_normal_mns: 0, - quorum_count: 100, + validator_quorum_count: 100, upgrading_info: Some(UpgradingInfo { current_protocol_version: 1, proposed_protocol_versions_with_weight: vec![ @@ -1207,10 +1204,7 @@ mod tests { ], upgrade_three_quarters_life: 0.75, }), - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1220,10 +1214,12 @@ mod tests { }; let hour_in_ms = 1000 * 60 * 60; let config = PlatformConfig { - quorum_size: 50, + validator_set_quorum_size: 50, + validator_set_quorum_type: "llmq_100_67".to_string(), + chain_lock_quorum_type: "llmq_100_67".to_string(), execution: ExecutionConfig { verify_sum_trees: true, - validator_set_quorum_rotation_block_count: 30, + validator_set_rotation_block_count: 30, epoch_time_length_s: 1576800, ..Default::default() }, @@ -1243,10 +1239,10 @@ mod tests { .core_rpc .expect_get_best_chain_lock() .returning(move || { - Ok(CoreChainLock { - core_block_height: 10, - core_block_hash: [1; 32].to_vec(), - signature: [2; 96].to_vec(), + Ok(ChainLock { + block_height: 10, + block_hash: BlockHash::from_byte_array([1; 32]), + signature: [2; 96].into(), }) }); let ChainExecutionOutcome { @@ -1293,7 +1289,7 @@ mod tests { counter.get(&TEST_PROTOCOL_VERSION_2), counter.get(&TEST_PROTOCOL_VERSION_3) ), - (Some(&2), Some(&69), Some(&3)) + (Some(&2), Some(&68), Some(&3)) ); //some nodes reverted to previous version } @@ -1310,7 +1306,8 @@ mod tests { }, total_hpmns: 200, extra_normal_mns: 0, - quorum_count: 24, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, upgrading_info: Some(UpgradingInfo { current_protocol_version: 1, proposed_protocol_versions_with_weight: vec![ @@ -1319,10 +1316,7 @@ mod tests { ], upgrade_three_quarters_life: 0.5, }), - core_height_increase: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + proposer_strategy: Default::default(), rotate_quorums: false, failure_testing: None, @@ -1349,7 +1343,7 @@ mod tests { ChainExecutionParameters { block_start, core_height_start: 1, - block_count: 700, + block_count: 1100, proposers, quorums, current_quorum_hash, @@ -1375,7 +1369,7 @@ mod tests { .basic_info() .epoch .index, - 4 + 5 ); assert_eq!( platform @@ -1395,7 +1389,7 @@ mod tests { counter.get(&TEST_PROTOCOL_VERSION_2), counter.get(&TEST_PROTOCOL_VERSION_3) ), - (None, Some(&3), Some(&155)) + (None, Some(&3), Some(&143)) ); } }) diff --git a/packages/rs-drive-proof-verifier/Cargo.toml b/packages/rs-drive-proof-verifier/Cargo.toml index ec67564352e..3b42107d9e7 100644 --- a/packages/rs-drive-proof-verifier/Cargo.toml +++ b/packages/rs-drive-proof-verifier/Cargo.toml @@ -20,7 +20,7 @@ drive = { path = "../rs-drive", default-features = false, features = [ "verify", ] } dpp = { path = "../rs-dpp" } -tenderdash-abci = { git = "https://github.com/dashpay/rs-tenderdash-abci" } +tenderdash-abci = { git = "https://github.com/dashpay/rs-tenderdash-abci", tag = "v0.14.0-dev.5" } # tenderdash-abci = { path = "../../../rs-tenderdash-abci/abci" } tracing = { version = "0.1.37" } serde = { version = "1.0.171", default-features = false, optional = true } diff --git a/packages/rs-platform-version/src/version/drive_abci_versions.rs b/packages/rs-platform-version/src/version/drive_abci_versions.rs index e39f192cf83..62fa30ba2c9 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions.rs @@ -61,6 +61,7 @@ pub struct DriveAbciMethodVersions { pub protocol_upgrade: DriveAbciProtocolUpgradeMethodVersions, pub block_fee_processing: DriveAbciBlockFeeProcessingMethodVersions, pub core_subsidy: DriveAbciCoreSubsidyMethodVersions, + pub core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants, pub fee_pool_inwards_distribution: DriveAbciFeePoolInwardsDistributionMethodVersions, pub fee_pool_outwards_distribution: DriveAbciFeePoolOutwardsDistributionMethodVersions, pub identity_credit_withdrawal: DriveAbciIdentityCreditWithdrawalMethodVersions, @@ -203,6 +204,16 @@ pub struct DriveAbciCoreSubsidyMethodVersions { pub epoch_core_reward_credits_for_distribution: FeatureVersion, } +#[derive(Clone, Debug, Default)] +pub struct DriveAbciCoreChainLockMethodVersionsAndConstants { + pub choose_quorum: FeatureVersion, + pub verify_chain_lock: FeatureVersion, + pub verify_chain_lock_locally: FeatureVersion, + pub verify_chain_lock_through_core: FeatureVersion, + pub make_sure_core_is_synced_to_chain_lock: FeatureVersion, + pub recent_block_count_amount: u32, //what constitutes a recent block, for v0 it's 2. +} + #[derive(Clone, Debug, Default)] pub struct DriveAbciFeePoolInwardsDistributionMethodVersions { pub add_distribute_block_fees_into_pools_operations: FeatureVersion, diff --git a/packages/rs-platform-version/src/version/mocks/v2_test.rs b/packages/rs-platform-version/src/version/mocks/v2_test.rs index 98050279775..bef04b0d407 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -12,9 +12,10 @@ use crate::version::dpp_versions::{ use crate::version::drive_abci_versions::{ DriveAbciAssetLockValidationVersions, DriveAbciBlockEndMethodVersions, DriveAbciBlockFeeProcessingMethodVersions, DriveAbciBlockStartMethodVersions, - DriveAbciCoreBasedUpdatesMethodVersions, DriveAbciCoreSubsidyMethodVersions, - DriveAbciDocumentsStateTransitionValidationVersions, DriveAbciEngineMethodVersions, - DriveAbciEpochMethodVersions, DriveAbciFeePoolInwardsDistributionMethodVersions, + DriveAbciCoreBasedUpdatesMethodVersions, DriveAbciCoreChainLockMethodVersionsAndConstants, + DriveAbciCoreSubsidyMethodVersions, DriveAbciDocumentsStateTransitionValidationVersions, + DriveAbciEngineMethodVersions, DriveAbciEpochMethodVersions, + DriveAbciFeePoolInwardsDistributionMethodVersions, DriveAbciFeePoolOutwardsDistributionMethodVersions, DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, @@ -501,6 +502,14 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { core_subsidy: DriveAbciCoreSubsidyMethodVersions { epoch_core_reward_credits_for_distribution: 0, }, + core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { + choose_quorum: 0, + verify_chain_lock: 0, + verify_chain_lock_locally: 0, + verify_chain_lock_through_core: 0, + make_sure_core_is_synced_to_chain_lock: 0, + recent_block_count_amount: 2, + }, fee_pool_inwards_distribution: DriveAbciFeePoolInwardsDistributionMethodVersions { add_distribute_block_fees_into_pools_operations: 0, add_distribute_storage_fee_to_epochs_operations: 0, diff --git a/packages/rs-platform-version/src/version/mocks/v3_test.rs b/packages/rs-platform-version/src/version/mocks/v3_test.rs index 2825786c603..19ed1497bbf 100644 --- a/packages/rs-platform-version/src/version/mocks/v3_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v3_test.rs @@ -12,9 +12,10 @@ use crate::version::dpp_versions::{ use crate::version::drive_abci_versions::{ DriveAbciAssetLockValidationVersions, DriveAbciBlockEndMethodVersions, DriveAbciBlockFeeProcessingMethodVersions, DriveAbciBlockStartMethodVersions, - DriveAbciCoreBasedUpdatesMethodVersions, DriveAbciCoreSubsidyMethodVersions, - DriveAbciDocumentsStateTransitionValidationVersions, DriveAbciEngineMethodVersions, - DriveAbciEpochMethodVersions, DriveAbciFeePoolInwardsDistributionMethodVersions, + DriveAbciCoreBasedUpdatesMethodVersions, DriveAbciCoreChainLockMethodVersionsAndConstants, + DriveAbciCoreSubsidyMethodVersions, DriveAbciDocumentsStateTransitionValidationVersions, + DriveAbciEngineMethodVersions, DriveAbciEpochMethodVersions, + DriveAbciFeePoolInwardsDistributionMethodVersions, DriveAbciFeePoolOutwardsDistributionMethodVersions, DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, @@ -501,6 +502,14 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { core_subsidy: DriveAbciCoreSubsidyMethodVersions { epoch_core_reward_credits_for_distribution: 0, }, + core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { + choose_quorum: 0, + verify_chain_lock: 0, + verify_chain_lock_locally: 0, + verify_chain_lock_through_core: 0, + make_sure_core_is_synced_to_chain_lock: 0, + recent_block_count_amount: 2, + }, fee_pool_inwards_distribution: DriveAbciFeePoolInwardsDistributionMethodVersions { add_distribute_block_fees_into_pools_operations: 0, add_distribute_storage_fee_to_epochs_operations: 0, diff --git a/packages/rs-platform-version/src/version/v1.rs b/packages/rs-platform-version/src/version/v1.rs index 057e9eb0413..e7122638dca 100644 --- a/packages/rs-platform-version/src/version/v1.rs +++ b/packages/rs-platform-version/src/version/v1.rs @@ -12,9 +12,10 @@ use crate::version::dpp_versions::{ use crate::version::drive_abci_versions::{ DriveAbciAssetLockValidationVersions, DriveAbciBlockEndMethodVersions, DriveAbciBlockFeeProcessingMethodVersions, DriveAbciBlockStartMethodVersions, - DriveAbciCoreBasedUpdatesMethodVersions, DriveAbciCoreSubsidyMethodVersions, - DriveAbciDocumentsStateTransitionValidationVersions, DriveAbciEngineMethodVersions, - DriveAbciEpochMethodVersions, DriveAbciFeePoolInwardsDistributionMethodVersions, + DriveAbciCoreBasedUpdatesMethodVersions, DriveAbciCoreChainLockMethodVersionsAndConstants, + DriveAbciCoreSubsidyMethodVersions, DriveAbciDocumentsStateTransitionValidationVersions, + DriveAbciEngineMethodVersions, DriveAbciEpochMethodVersions, + DriveAbciFeePoolInwardsDistributionMethodVersions, DriveAbciFeePoolOutwardsDistributionMethodVersions, DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, @@ -498,6 +499,14 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { core_subsidy: DriveAbciCoreSubsidyMethodVersions { epoch_core_reward_credits_for_distribution: 0, }, + core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { + choose_quorum: 0, + verify_chain_lock: 0, + verify_chain_lock_locally: 0, + verify_chain_lock_through_core: 0, + make_sure_core_is_synced_to_chain_lock: 0, + recent_block_count_amount: 2, + }, fee_pool_inwards_distribution: DriveAbciFeePoolInwardsDistributionMethodVersions { add_distribute_block_fees_into_pools_operations: 0, add_distribute_storage_fee_to_epochs_operations: 0, diff --git a/packages/strategy-tests/src/frequency.rs b/packages/strategy-tests/src/frequency.rs index a846a27f316..8b46d8ec7f2 100644 --- a/packages/strategy-tests/src/frequency.rs +++ b/packages/strategy-tests/src/frequency.rs @@ -64,6 +64,10 @@ impl Frequency { } } + pub fn max_event_count(&self) -> u16 { + self.times_per_block_range.end + } + pub fn pick_in_range(&self, rng: &mut impl Rng, range: Range) -> Vec { if !self.is_set() || range.is_empty() { return vec![]; diff --git a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs index b2e514a2947..4dde4941064 100644 --- a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs @@ -3,7 +3,6 @@ use crate::errors::consensus::basic::{ UnsupportedProtocolVersionErrorWasm, UnsupportedVersionErrorWasm, }; use dpp::consensus::ConsensusError as DPPConsensusError; -use std::ops::Deref; use crate::errors::consensus::basic::identity::{ DuplicatedIdentityPublicKeyErrorWasm, DuplicatedIdentityPublicKeyIdErrorWasm, diff --git a/scripts/configure_dotenv.sh b/scripts/configure_dotenv.sh index 2074b73ca3b..f5f6fa4636b 100755 --- a/scripts/configure_dotenv.sh +++ b/scripts/configure_dotenv.sh @@ -50,7 +50,7 @@ NETWORK=regtest" >>"${SDK_ENV_FILE_PATH}" #EOF # DRIVE: -cp "${DRIVE_PATH}"/.env.example "${DRIVE_PATH}"/.env +cp "${DRIVE_PATH}"/.env.local "${DRIVE_PATH}"/.env # WALLET-LIB: WALLET_LIB_ENV_FILE_PATH=${WALLET_LIB_PATH}/.env