diff --git a/Cargo.lock b/Cargo.lock index f8c9ab0..ea61176 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,6 +75,44 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "alloy-primitives" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6a0fb18dd5fb43ec5f0f6a20be1ce0287c79825827de5744afaa6c957737c33" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if 1.0.4", + "const-hex", + "derive_more 2.1.1", + "foldhash 0.2.0", + "hashbrown 0.16.1", + "indexmap", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand 0.9.2", + "rapidhash", + "ruint", + "rustc-hash", + "serde", + "sha3", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f70d83b765fdc080dbcd4f4db70d8d23fe4761f2f02ebfa9146b833900634b4" +dependencies = [ + "arrayvec", + "bytes", +] + [[package]] name = "anstream" version = "0.6.21" @@ -138,8 +176,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" dependencies = [ "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", ] [[package]] @@ -149,10 +187,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" dependencies = [ "ahash", - "ark-ff", + "ark-ff 0.5.0", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "educe", "fnv", "hashbrown 0.15.5", @@ -163,18 +201,56 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] + [[package]] name = "ark-ff" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "arrayvec", - "digest", + "digest 0.10.7", "educe", "itertools 0.13.0", "num-bigint 0.4.6", @@ -183,6 +259,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-ff-asm" version = "0.5.0" @@ -193,6 +289,31 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-ff-macros" version = "0.5.0" @@ -213,14 +334,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" dependencies = [ "ahash", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "educe", "fnv", "hashbrown 0.15.5", ] +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint 0.4.6", +] + [[package]] name = "ark-serialize" version = "0.5.0" @@ -228,9 +370,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" dependencies = [ "ark-serialize-derive", - "ark-std", + "ark-std 0.5.0", "arrayvec", - "digest", + "digest 0.10.7", "num-bigint 0.4.6", ] @@ -245,6 +387,26 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "ark-std" version = "0.5.0" @@ -384,6 +546,17 @@ dependencies = [ "url", ] +[[package]] +name = "auto_impl" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -500,7 +673,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -530,7 +703,7 @@ name = "bls12_381" version = "0.8.0" source = "git+https://github.com/lambdaclass/bls12_381?branch=expose-fp-struct#219174187bd78154cec35b0809799fc2c991a579" dependencies = [ - "digest", + "digest 0.10.7", "ff", "group", "pairing", @@ -760,7 +933,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d72c1252426a83be2092dd5884a5f6e3b8e7180f6891b6263d2c21b92ec8816" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -772,6 +945,18 @@ dependencies = [ "crossbeam-utils 0.8.21", ] +[[package]] +name = "const-hex" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bb320cac8a0750d7f25280aa97b09c26edfe161164238ecbbb31092b079e735" +dependencies = [ + "cfg-if 1.0.4", + "cpufeatures", + "proptest", + "serde_core", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -819,6 +1004,15 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1054,9 +1248,9 @@ dependencies = [ "cfg-if 1.0.4", "cpufeatures", "curve25519-dalek-derive", - "digest", + "digest 0.10.7", "fiat-crypto", - "rustc_version", + "rustc_version 0.4.1", "subtle", "zeroize", ] @@ -1072,6 +1266,76 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.111", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.111", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", + "quote", + "syn 2.0.111", +] + [[package]] name = "data-encoding" version = "2.9.0" @@ -1144,13 +1408,33 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" dependencies = [ - "derive_more-impl", + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl 2.1.1", ] [[package]] @@ -1159,13 +1443,36 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ - "convert_case", + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 2.0.111", + "unicode-xid", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "convert_case 0.10.0", "proc-macro2", "quote", + "rustc_version 0.4.1", "syn 2.0.111", "unicode-xid", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" @@ -1208,7 +1515,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", - "digest", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", @@ -1265,7 +1572,7 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "digest", + "digest 0.10.7", "ff", "generic-array", "group", @@ -1354,8 +1661,59 @@ dependencies = [ "fixed-hash", "impl-rlp", "impl-serde", - "primitive-types", - "uint", + "primitive-types 0.13.1", + "uint 0.10.0", +] + +[[package]] +name = "ethereum_hashing" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa93f58bb1eb3d1e556e4f408ef1dac130bad01ac37db4e7ade45de40d1c86a" +dependencies = [ + "cpufeatures", + "ring", + "sha2", +] + +[[package]] +name = "ethereum_serde_utils" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dc1355dbb41fbbd34ec28d4fb2a57d9a70c67ac3c19f6a5ca4d4a176b9e997a" +dependencies = [ + "alloy-primitives", + "hex", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "ethereum_ssz" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8cd8c4f47dfb947dbfe3cdf2945ae1da808dbedc592668658e827a12659ba1" +dependencies = [ + "alloy-primitives", + "ethereum_serde_utils", + "itertools 0.13.0", + "serde", + "serde_derive", + "smallvec", + "typenum", +] + +[[package]] +name = "ethereum_ssz_derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d247bc40823c365a62e572441a8f8b12df03f171713f06bc76180fcd56ab71" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.111", ] [[package]] @@ -1386,6 +1744,8 @@ name = "ethlambda-p2p" version = "0.1.0" dependencies = [ "async-trait", + "ethereum_ssz", + "ethereum_ssz_derive", "ethlambda-types", "ethrex-common", "ethrex-p2p", @@ -1393,7 +1753,10 @@ dependencies = [ "hex", "libp2p", "snap", + "ssz_types", "tracing", + "tree_hash", + "tree_hash_derive", ] [[package]] @@ -1413,8 +1776,13 @@ name = "ethlambda-types" version = "0.1.0" dependencies = [ "ethereum-types", + "ethereum_ssz", + "ethereum_ssz_derive", "serde", + "ssz_types", "thiserror 2.0.17", + "tree_hash", + "tree_hash_derive", ] [[package]] @@ -1488,12 +1856,12 @@ source = "git+https://github.com/lambdaclass/ethrex?rev=1af63a4de7c93eb7413b9b00 dependencies = [ "ark-bn254", "ark-ec", - "ark-ff", + "ark-ff 0.5.0", "bitvec", "bls12_381", "bytes", "datatest-stable", - "derive_more", + "derive_more 1.0.0", "ethrex-common", "ethrex-crypto", "ethrex-rlp", @@ -1622,7 +1990,7 @@ dependencies = [ "anyhow", "bytes", "crossbeam 0.8.4", - "digest", + "digest 0.10.7", "ethereum-types", "ethrex-crypto", "ethrex-rlp", @@ -1645,7 +2013,7 @@ source = "git+https://github.com/lambdaclass/ethrex?rev=1af63a4de7c93eb7413b9b00 dependencies = [ "bincode", "bytes", - "derive_more", + "derive_more 1.0.0", "dyn-clone", "ethereum-types", "ethrex-common", @@ -1692,6 +2060,34 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + [[package]] name = "ff" version = "0.13.1" @@ -2050,6 +2446,8 @@ dependencies = [ "allocator-api2", "equivalent", "foldhash 0.2.0", + "serde", + "serde_core", ] [[package]] @@ -2162,7 +2560,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -2328,6 +2726,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.1.0" @@ -2403,6 +2807,15 @@ dependencies = [ "xmltree", ] +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + [[package]] name = "impl-codec" version = "0.7.1" @@ -2418,7 +2831,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54ed8ad1f3877f7e775b8cbf30ed1bd3209a95401817f19a0eb4402d13f8cf90" dependencies = [ - "rlp", + "rlp 0.6.1", ] [[package]] @@ -2449,6 +2862,8 @@ checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] @@ -2484,6 +2899,15 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -2550,6 +2974,16 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + [[package]] name = "kzg-rs" version = "0.2.7" @@ -2878,7 +3312,7 @@ dependencies = [ "smallvec", "thiserror 2.0.17", "tracing", - "uint", + "uint 0.10.0", "web-time", ] @@ -3730,6 +4164,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -3994,6 +4429,16 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pest" +version = "2.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" +dependencies = [ + "memchr", + "ucd-trie", +] + [[package]] name = "pin-project" version = "1.1.10" @@ -4112,6 +4557,17 @@ dependencies = [ "elliptic-curve", ] +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec 0.6.0", + "uint 0.9.5", +] + [[package]] name = "primitive-types" version = "0.13.1" @@ -4119,10 +4575,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5" dependencies = [ "fixed-hash", - "impl-codec", + "impl-codec 0.7.1", "impl-rlp", "impl-serde", - "uint", + "uint 0.10.0", ] [[package]] @@ -4181,6 +4637,25 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "proptest" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.10.0", + "num-traits", + "rand 0.9.2", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + [[package]] name = "protobuf" version = "3.7.2" @@ -4230,6 +4705,12 @@ dependencies = [ "xxhash-rust", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quick-protobuf" version = "0.8.1" @@ -4370,6 +4851,7 @@ checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", + "serde", ] [[package]] @@ -4427,6 +4909,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom 0.3.4", + "serde", ] [[package]] @@ -4438,6 +4921,24 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + +[[package]] +name = "rapidhash" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2988730ee014541157f48ce4dcc603940e00915edc3c7f9a8d78092256bb2493" +dependencies = [ + "rustversion", +] + [[package]] name = "rayon" version = "1.11.0" @@ -4554,7 +5055,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -4587,6 +5088,16 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + [[package]] name = "rlp" version = "0.6.1" @@ -4615,6 +5126,40 @@ dependencies = [ "tokio", ] +[[package]] +name = "ruint" +version = "1.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint 0.4.6", + "num-integer", + "num-traits", + "parity-scale-codec", + "primitive-types 0.12.2", + "proptest", + "rand 0.8.5", + "rand 0.9.2", + "rlp 0.5.2", + "ruint-macro", + "serde_core", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rustc-hash" version = "2.1.1" @@ -4627,13 +5172,22 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver", + "semver 1.0.27", ] [[package]] @@ -4699,6 +5253,18 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "rw-stream-sink" version = "0.4.0" @@ -4783,12 +5349,30 @@ dependencies = [ "cc", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + [[package]] name = "send_wrapper" version = "0.4.0" @@ -4864,7 +5448,7 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if 1.0.4", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] @@ -4875,7 +5459,7 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if 1.0.4", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] @@ -4884,10 +5468,20 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest", + "digest 0.10.7", "keccak", ] +[[package]] +name = "sha3-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" +dependencies = [ + "cc", + "cfg-if 1.0.4", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -4919,7 +5513,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -4959,7 +5553,7 @@ dependencies = [ "curve25519-dalek", "rand_core 0.6.4", "ring", - "rustc_version", + "rustc_version 0.4.1", "sha2", "subtle", ] @@ -5088,6 +5682,22 @@ dependencies = [ "der", ] +[[package]] +name = "ssz_types" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc20a89bab2dabeee65e9c9eb96892dc222c23254b401e1319b85efd852fa31" +dependencies = [ + "ethereum_serde_utils", + "ethereum_ssz", + "itertools 0.14.0", + "serde", + "serde_derive", + "smallvec", + "tree_hash", + "typenum", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -5213,6 +5823,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +dependencies = [ + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -5498,6 +6121,31 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "tree_hash" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db21caa355767db4fd6129876e5ae278a8699f4a6959b1e3e7aff610b532d52" +dependencies = [ + "alloy-primitives", + "ethereum_hashing", + "ethereum_ssz", + "smallvec", + "typenum", +] + +[[package]] +name = "tree_hash_derive" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711cc655fcbb48384a87dc2bf641b991a15c5ad9afc3caa0b1ab1df3b436f70f" +dependencies = [ + "darling 0.21.3", + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -5510,6 +6158,24 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "uint" version = "0.10.0" @@ -5522,6 +6188,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-ident" version = "1.0.22" @@ -5615,6 +6287,15 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.5.0" diff --git a/crates/common/types/Cargo.toml b/crates/common/types/Cargo.toml index cc70a6f..8391b0c 100644 --- a/crates/common/types/Cargo.toml +++ b/crates/common/types/Cargo.toml @@ -13,3 +13,9 @@ version.workspace = true thiserror.workspace = true serde.workspace = true ethereum-types.workspace = true + +ethereum_ssz_derive = "0.10.0" +ethereum_ssz = "0.10.0" +ssz_types = "0.14.0" +tree_hash = "0.12.0" +tree_hash_derive = "0.12.0" diff --git a/crates/common/types/src/block.rs b/crates/common/types/src/block.rs index d6ec0e8..bd29c67 100644 --- a/crates/common/types/src/block.rs +++ b/crates/common/types/src/block.rs @@ -1,4 +1,4 @@ -use ethereum_types::H256; +use crate::primitives::H256; use crate::state::Slot; diff --git a/crates/common/types/src/lib.rs b/crates/common/types/src/lib.rs index f7647b7..c7c712e 100644 --- a/crates/common/types/src/lib.rs +++ b/crates/common/types/src/lib.rs @@ -1,3 +1,4 @@ pub mod block; pub mod genesis; +pub mod primitives; pub mod state; diff --git a/crates/common/types/src/primitives.rs b/crates/common/types/src/primitives.rs new file mode 100644 index 0000000..632826b --- /dev/null +++ b/crates/common/types/src/primitives.rs @@ -0,0 +1,3 @@ +use tree_hash::Hash256; + +pub type H256 = Hash256; diff --git a/crates/common/types/src/state.rs b/crates/common/types/src/state.rs index 147b560..1e8869f 100644 --- a/crates/common/types/src/state.rs +++ b/crates/common/types/src/state.rs @@ -1,7 +1,8 @@ -use ethereum_types::{H256, U256}; use serde::{Deserialize, Serialize}; +use ssz_derive::{Decode, Encode}; +use tree_hash_derive::TreeHash; -use crate::{block::BlockHeader, genesis::Genesis}; +use crate::{block::BlockHeader, genesis::Genesis, primitives::H256}; #[derive(Debug)] pub struct Slot(u64); @@ -39,10 +40,10 @@ impl State { latest_block_header: BlockHeader { slot: Slot(0), proposer_index: 0, - parent_root: H256::zero(), - state_root: H256::zero(), + parent_root: H256::ZERO, + state_root: H256::ZERO, // TODO: this should be the hash_tree_root of an empty block body - body_root: H256::zero(), + body_root: H256::ZERO, }, latest_justified: genesis.latest_justified.clone(), latest_finalized: genesis.latest_finalized.clone(), @@ -50,12 +51,25 @@ impl State { } } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct Checkpoint { pub root: H256, // Used U256 due to it being serialized as string - // TODO: use u64 and implement custom serialization - pub slot: U256, + #[serde(deserialize_with = "deser_dec_str")] + pub slot: u64, +} + +// Taken from ethrex-common +pub fn deser_dec_str<'de, D>(d: D) -> Result +where + D: serde::Deserializer<'de>, +{ + use serde::de::Error; + + let value = String::deserialize(d)?; + value + .parse() + .map_err(|_| D::Error::custom("Failed to deserialize u64 value")) } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/crates/net/p2p/Cargo.toml b/crates/net/p2p/Cargo.toml index ac174ef..369147e 100644 --- a/crates/net/p2p/Cargo.toml +++ b/crates/net/p2p/Cargo.toml @@ -25,5 +25,12 @@ ethrex-p2p = { git = "https://github.com/lambdaclass/ethrex", rev = "1af63a4de7c ethrex-rlp = { git = "https://github.com/lambdaclass/ethrex", rev = "1af63a4de7c93eb7413b9b003df1be82e1484c69" } ethrex-common = { git = "https://github.com/lambdaclass/ethrex", rev = "1af63a4de7c93eb7413b9b003df1be82e1484c69" } +# SSZ +ethereum_ssz_derive = "0.10.0" +ethereum_ssz = "0.10.0" +ssz_types = "0.14.0" +tree_hash = "0.12.0" +tree_hash_derive = "0.12.0" + [dev-dependencies] hex = "0.4" diff --git a/crates/net/p2p/src/lib.rs b/crates/net/p2p/src/lib.rs index 1b99e70..bde9c56 100644 --- a/crates/net/p2p/src/lib.rs +++ b/crates/net/p2p/src/lib.rs @@ -14,7 +14,7 @@ use libp2p::{ }; use tracing::{info, trace}; -use crate::messages::status::STATUS_PROTOCOL_V1; +use crate::messages::status::{STATUS_PROTOCOL_V1, Status}; mod messages; @@ -110,18 +110,21 @@ struct Behaviour { async fn event_loop(mut swarm: libp2p::Swarm) { while let Some(event) = swarm.next().await { match event { - SwarmEvent::Behaviour(BehaviourEvent::ReqResp(Event::Message { - peer, - connection_id, - message: - Message::Request { - request_id, - request, - channel, - }, - })) => { - info!(finalized_slot=%request.finalized.slot, head_slot=%request.head.slot, "Received status request from peer {peer}"); + SwarmEvent::Behaviour(BehaviourEvent::ReqResp(message @ Event::Message { .. })) => { + handle_req_resp_message(&mut swarm, message).await; } + // SwarmEvent::Behaviour(BehaviourEvent::ReqResp(Event::Message { + // peer, + // connection_id, + // message: + // Message::Request { + // request_id, + // request, + // channel, + // }, + // })) => { + // info!(finalized_slot=%request.finalized.slot, head_slot=%request.head.slot, "Received status request from peer {peer}"); + // } _ => { trace!(?event, "Ignored swarm event"); } @@ -129,6 +132,41 @@ async fn event_loop(mut swarm: libp2p::Swarm) { } } +async fn handle_req_resp_message( + swarm: &mut libp2p::Swarm, + event: Event, +) { + let Event::Message { + peer, + connection_id: _, + message, + } = event + else { + unreachable!("we already matched on event_loop"); + }; + match message { + Message::Request { + request_id: _, + request, + channel, + } => { + info!(finalized_slot=%request.finalized.slot, head_slot=%request.head.slot, "Received status request from peer {peer}"); + swarm + .behaviour_mut() + .req_resp + .send_response(channel, request.clone()) + .unwrap(); + swarm.behaviour_mut().req_resp.send_request(&peer, request); + } + Message::Response { + request_id: _, + response, + } => { + info!(finalized_slot=%response.finalized.slot, head_slot=%response.head.slot, "Received status response from peer {peer}"); + } + } +} + pub struct Bootnode { ip: IpAddr, quic_port: u16, diff --git a/crates/net/p2p/src/messages/mod.rs b/crates/net/p2p/src/messages/mod.rs index 822c729..d7148cc 100644 --- a/crates/net/p2p/src/messages/mod.rs +++ b/crates/net/p2p/src/messages/mod.rs @@ -1 +1,6 @@ pub mod status; + +const MAX_PAYLOAD_SIZE: usize = 10 * 1024 * 1024; // 10 MB + +// https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/p2p-interface.md#max_message_size +const MAX_COMPRESSED_PAYLOAD_SIZE: usize = 32 + MAX_PAYLOAD_SIZE + MAX_PAYLOAD_SIZE / 6 + 1024; // ~12 MB diff --git a/crates/net/p2p/src/messages/status.rs b/crates/net/p2p/src/messages/status.rs index 7fcd2c4..9788dbb 100644 --- a/crates/net/p2p/src/messages/status.rs +++ b/crates/net/p2p/src/messages/status.rs @@ -1,8 +1,13 @@ use std::io; use ethlambda_types::state::Checkpoint; -use ethrex_common::{H256, U256}; -use libp2p::futures::{AsyncRead, AsyncReadExt, AsyncWrite}; +use libp2p::futures::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; +use snap::read::FrameEncoder; +use ssz::{Decode, Encode}; +use ssz_derive::{Decode, Encode}; +use tracing::trace; + +use crate::messages::MAX_COMPRESSED_PAYLOAD_SIZE; pub const STATUS_PROTOCOL_V1: &str = "/leanconsensus/req/status/1/ssz_snappy"; @@ -32,6 +37,17 @@ impl libp2p::request_response::Codec for StatusCodec { where T: AsyncRead + Unpin + Send, { + let mut result = 0_u8; + io.read_exact(std::slice::from_mut(&mut result)).await?; + + // TODO: send errors to event loop? + if result != 0 { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "non-zero result in response", + )); + } + let payload = decode_payload(io).await?; let status = deserialize_payload(payload)?; Ok(status) @@ -46,7 +62,18 @@ impl libp2p::request_response::Codec for StatusCodec { where T: AsyncWrite + Unpin + Send, { - todo!(); + trace!(?req, "Writing status request"); + + let encoded = req.as_ssz_bytes(); + let mut compressor = FrameEncoder::new(&encoded[..]); + + let mut buf = Vec::new(); + io::Read::read_to_end(&mut compressor, &mut buf)?; + + let mut size_buf = [0; 5]; + let varint_buf = encode_varint(buf.len() as u32, &mut size_buf); + io.write(varint_buf).await?; + io.write(&buf).await?; Ok(()) } @@ -60,7 +87,19 @@ impl libp2p::request_response::Codec for StatusCodec { where T: AsyncWrite + Unpin + Send, { - todo!(); + // Send result byte + io.write(&[0]).await?; + + let encoded = resp.as_ssz_bytes(); + let mut compressor = FrameEncoder::new(&encoded[..]); + + let mut buf = Vec::new(); + io::Read::read_to_end(&mut compressor, &mut buf)?; + + let mut size_buf = [0; 5]; + let varint_buf = encode_varint(buf.len() as u32, &mut size_buf); + io.write(varint_buf).await?; + io.write(&buf).await?; Ok(()) } @@ -70,12 +109,21 @@ async fn decode_payload(io: &mut T) -> io::Result> where T: AsyncRead + Unpin + Send, { - let mut varint_buf = [0; std::mem::size_of::()]; + // TODO: limit bytes received + let mut varint_buf = [0; 5]; - io.take(varint_buf.len() as u64) + let read = io + .take(varint_buf.len() as u64) .read(&mut varint_buf) .await?; - let (size, rest) = decode_varint(&varint_buf); + let (size, rest) = decode_varint(&varint_buf[..read])?; + + if (size as usize) < rest.len() || size as usize > MAX_COMPRESSED_PAYLOAD_SIZE { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "invalid message size", + )); + } let mut message = vec![0; size as usize]; if rest.is_empty() { @@ -93,49 +141,30 @@ where } fn deserialize_payload(payload: Vec) -> io::Result { - if payload.len() != 80 { - return Err(io::Error::new( - io::ErrorKind::InvalidData, - "Invalid status message length", - )); - } - - let finalized_root = H256( - payload[..32] - .try_into() - .expect("slice with incorrect length"), - ); - let finalized_slot = u64::from_be_bytes( - payload[32..40] - .try_into() - .expect("slice with incorrect length"), - ); - - let head_root = H256( - payload[40..72] - .try_into() - .expect("slice with incorrect length"), - ); - let head_slot = u64::from_be_bytes( - payload[72..] - .try_into() - .expect("slice with incorrect length"), - ); - - let status = Status { - finalized: Checkpoint { - root: finalized_root, - slot: U256::from(finalized_slot), - }, - head: Checkpoint { - root: head_root, - slot: U256::from(head_slot), - }, - }; + let status = Status::from_ssz_bytes(&payload) + // We turn to string since DecodeError does not implement std::error::Error + .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, format!("{err:?}")))?; Ok(status) } -fn decode_varint(buf: &[u8]) -> (u32, &[u8]) { +/// Encodes a u32 as a varint into the provided buffer, returning a slice of the buffer +/// containing the encoded bytes. +fn encode_varint(mut value: u32, dst: &mut [u8; 5]) -> &[u8] { + for i in 0..5 { + let mut byte = (value & 0x7F) as u8; + value >>= 7; + if value != 0 { + byte |= 0x80; + } + dst[i] = byte; + if value == 0 { + return &dst[..=i]; + } + } + &dst[..] +} + +fn decode_varint(buf: &[u8]) -> io::Result<(u32, &[u8])> { let mut result = 0_u32; let mut read_size = 0; @@ -147,10 +176,16 @@ fn decode_varint(buf: &[u8]) -> (u32, &[u8]) { break; } } - (result, &buf[read_size..]) + if read_size == 0 { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "message size is bigger than 28 bits", + )); + } + Ok((result, &buf[read_size..])) } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Encode, Decode)] pub struct Status { pub finalized: Checkpoint, pub head: Checkpoint, @@ -164,7 +199,7 @@ mod tests { fn test_decode_varint() { // Example from https://protobuf.dev/programming-guides/encoding/ let buf = [0b10010110, 0b00000001]; - let (value, rest) = decode_varint(&buf); + let (value, rest) = decode_varint(&buf).unwrap(); assert_eq!(value, 150); let expected: &[u8] = &[];