diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b6f5c4..77334fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to `ant-protocol` will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/). +## [2.3.0] + +### Changed +- **ADR-0004 (commitment-bound quote pricing):** verify the new signed + commitment fields (`committed_key_count`, `commitment_pin`) on single-node and + merkle quote types; centralise `StorageCommitment`, `commitment_hash`, sidecar + handling, and the shared `calculate_price`. Requires `evmlib` 0.9.0. Breaking + wire change — part of the coordinated ADR-0004 cutover (evmlib → ant-protocol → + ant-node/ant-client). + ## [2.0.0] — Unreleased First release of the `2.x` series. Not wire-compatible with previous diff --git a/Cargo.lock b/Cargo.lock index b5df0c9..1252458 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,13 +79,13 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e0378e959aa6a885897522080a990e80eb317f1e9a222a604492ea50e13096" +checksum = "3b5cc30538e90795a57647bef8d8864aad6e8d86190617009b4ef8d8b647b49a" dependencies = [ "alloy-primitives", "num_enum", - "strum", + "phf", ] [[package]] @@ -383,7 +383,7 @@ dependencies = [ "cfg-if", "const-hex", "derive_more", - "foldhash 0.2.0", + "foldhash", "hashbrown 0.17.1", "indexmap 2.14.0", "itoa", @@ -443,9 +443,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc90b1e703d3c03f4ff7f48e82dd0bc1c8211ab7d079cd836a06fcfeb06651cb" +checksum = "24671b1f62edcf0f9b62994c7bf72cd621a04a4b99f5020ece1a647b40e2f103" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -454,13 +454,13 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36834a5c0a2fa56e171bf256c34d70fca07d0c0031583edea1c4946b7889c9e" +checksum = "9d4311c03125e8a18296504560b9de3d75ecbd0dcda7f71e6cf2a196d57e6fba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -595,7 +595,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -613,7 +613,7 @@ dependencies = [ "proc-macro2", "quote", "sha3 0.11.0", - "syn 2.0.117", + "syn 2.0.118", "syn-solidity", ] @@ -631,7 +631,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.117", + "syn 2.0.118", "syn-solidity", ] @@ -721,7 +721,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -794,7 +794,7 @@ dependencies = [ [[package]] name = "ant-protocol" -version = "2.2.2" +version = "2.3.0" dependencies = [ "alloy", "blake3", @@ -816,9 +816,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "ark-ff" @@ -878,6 +878,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7a806ac6c8307b929df4645776290a50ee2aac754ad09d8bdf73391309e43af" +dependencies = [ + "ark-ff-asm 0.6.0", + "ark-ff-macros 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", + "digest 0.10.7", + "educe", + "num-bigint", + "num-traits", + "zeroize", +] + [[package]] name = "ark-ff-asm" version = "0.3.0" @@ -905,7 +922,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.118", +] + +[[package]] +name = "ark-ff-asm" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1479009684adc073dff49a1025d3a7065b317a9ead25aaaca38cdc70058ba8a2" +dependencies = [ + "quote", + "syn 2.0.118", ] [[package]] @@ -943,7 +970,20 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", +] + +[[package]] +name = "ark-ff-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0691ed21ef00ef89c1e9bda832eba493dda3ec2f8d892fb25b705f73f06bb8" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.118", ] [[package]] @@ -979,6 +1019,30 @@ dependencies = [ "num-bigint", ] +[[package]] +name = "ark-serialize" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a74dd304fd536fb95d0a328e72be759209cc496a9da094c5bc56e5fea4f9e86b" +dependencies = [ + "ark-serialize-derive", + "ark-std 0.6.0", + "digest 0.10.7", + "num-bigint", + "serde_with", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f153690697a2b91e5e1251ff98411ee5371500a111a0fd317a70e588eb300f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "ark-std" version = "0.3.0" @@ -1009,6 +1073,16 @@ dependencies = [ "rand 0.8.6", ] +[[package]] +name = "ark-std" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "367c9c827ed431bff6868b7aa926e05b16eb46603cc8b6e768e4a5553fa1d155" +dependencies = [ + "num-traits", + "rand 0.8.6", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -1017,9 +1091,9 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "asn1-rs" @@ -1045,7 +1119,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "synstructure", ] @@ -1057,7 +1131,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1079,7 +1153,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1090,7 +1164,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1128,7 +1202,7 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1139,9 +1213,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +checksum = "4342d8937fc7e5dd9b1c60292261c0670c882a2cd1719cfc11b1af41731e32ad" dependencies = [ "aws-lc-sys", "zeroize", @@ -1149,14 +1223,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.41.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +checksum = "6d9ceb1da931507a12f4fccea479dccd00da1943e1b4ae72d8e502d707361444" dependencies = [ "cc", "cmake", "dunce", "fs_extra", + "pkg-config", ] [[package]] @@ -1201,33 +1276,54 @@ dependencies = [ "serde", ] +[[package]] +name = "bitcoin-consensus-encoding" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2d6094e2a1ba3c93b5a596fe5a10d1a10c3c6e06785cde89f693a044c01aa40" +dependencies = [ + "bitcoin-internals", +] + +[[package]] +name = "bitcoin-internals" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a30a22d1f112dde8e16be7b45c63645dc165cef254f835b3e1e9553e485cfa64" +dependencies = [ + "hex-conservative 0.3.2", +] + [[package]] name = "bitcoin-io" -version = "0.1.100" +version = "0.1.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11301df0b06f22dea7bb1916403fdd88a371031e495c49b8f96931b28189e175" +checksum = "bb5de036369d1ac59d3c1819ebc4d850f89466f5401c571a285b6ed564a4cb78" +dependencies = [ + "bitcoin-consensus-encoding", +] [[package]] name = "bitcoin_hashes" -version = "0.14.100" +version = "0.14.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9901a56e133a1fc86eeb1113e2591f45f4682451ca893bff494d2f88918e3f" +checksum = "bca4c7abb40c8817d77403c880988cfd484f23ab2365726afb2f798363e2c4a2" dependencies = [ "bitcoin-io", - "hex-conservative", + "hex-conservative 0.2.2", ] [[package]] name = "bitflags" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -1260,9 +1356,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ "hybrid-array", ] @@ -1281,9 +1377,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" +checksum = "2f3f6da4992df95bbcd9af42a6c7dcb994498fc9048230405f3b36ff7cd3f145" dependencies = [ "borsh-derive", "bytes", @@ -1292,15 +1388,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" +checksum = "3ae8fb4fb5740e4b2c4884ff95f5f32f5e8479db1e8fd8eb49ddbe09eb09bb7c" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1338,9 +1434,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" dependencies = [ "serde", ] @@ -1362,9 +1458,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.63" +version = "1.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" +checksum = "f5d6cac793997bd970000024b2934968efe83b382de4fdcf4fcb46b6ee4ad996" dependencies = [ "find-msvc-tools", "jobserver", @@ -1403,9 +1499,9 @@ dependencies = [ [[package]] name = "chacha20" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cpufeatures 0.3.0", @@ -1481,7 +1577,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1645,9 +1741,9 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -1655,18 +1751,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crunchy" @@ -1739,7 +1835,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1763,7 +1859,7 @@ dependencies = [ "quote", "serde", "strsim", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1774,7 +1870,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1827,7 +1923,6 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ - "powerfmt", "serde_core", ] @@ -1861,7 +1956,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.117", + "syn 2.0.118", "unicode-xid", ] @@ -1892,7 +1987,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer 0.12.0", + "block-buffer 0.12.1", "crypto-common 0.2.2", ] @@ -1946,7 +2041,7 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2010,7 +2105,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2057,22 +2152,22 @@ checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" [[package]] name = "enum-ordinalize" -version = "4.3.2" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +checksum = "07f808d588c10e464ea6f7d3eaed500049eff30aaac103460f61828c2d65b3eb" dependencies = [ "enum-ordinalize-derive", ] [[package]] name = "enum-ordinalize-derive" -version = "4.3.2" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" +checksum = "42e528e2d34ba8a67a1a650b86beae8ef69fc5fdb638016f386b973226590432" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2084,7 +2179,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2105,9 +2200,9 @@ dependencies = [ [[package]] name = "evmlib" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd96cf24017cd31cd422c80de3078a821b7884a5b1feb00087e98209326c676" +checksum = "8da0d9ad5b5cab92cc92ddac9afb884f86b226340caf17f6e5c41d51175dcaa1" dependencies = [ "alloy", "ant-merkle", @@ -2237,12 +2332,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "foldhash" version = "0.2.0" @@ -2326,7 +2415,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2395,25 +2484,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi 5.3.0", "wasip2", - "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", - "wasip2", - "wasip3", + "wasm-bindgen", ] [[package]] @@ -2445,9 +2532,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" dependencies = [ "atomic-waker", "bytes", @@ -2483,15 +2570,6 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash 0.1.5", -] - [[package]] name = "hashbrown" version = "0.16.1" @@ -2500,7 +2578,7 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", - "foldhash 0.2.0", + "foldhash", ] [[package]] @@ -2509,7 +2587,7 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" dependencies = [ - "foldhash 0.2.0", + "foldhash", "serde", "serde_core", ] @@ -2555,6 +2633,15 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "hex-conservative" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830e599c2904b08f0834ee6337d8fe8f0ed4a63b5d9e7a7f49c0ffa06d08d360" +dependencies = [ + "arrayvec", +] + [[package]] name = "hkdf" version = "0.12.4" @@ -2596,9 +2683,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -2635,9 +2722,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hybrid-array" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" dependencies = [ "typenum", ] @@ -2807,12 +2894,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "ident_case" version = "1.0.1" @@ -2854,7 +2935,7 @@ dependencies = [ "hyper", "hyper-util", "log", - "rand 0.10.1", + "rand 0.10.2", "tokio", "url", "xmltree", @@ -2877,7 +2958,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3000,7 +3081,7 @@ dependencies = [ "quote", "rustc_version 0.4.1", "simd_cesu8", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3028,28 +3109,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.99" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -3088,9 +3168,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1766b89733097006f3a1388a02849865d6bc98c89273cb622e29fdd209922183" +checksum = "dd5dc2c0d691cbf7595cde551ced329cca99c2387c2cbc97754c5d0cd045d3ee" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -3127,12 +3207,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" version = "0.2.186" @@ -3147,9 +3221,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" +checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" dependencies = [ "libc", ] @@ -3177,9 +3251,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "lru" @@ -3204,7 +3278,7 @@ checksum = "59a9dbbfc75d2688ed057456ce8a3ee3f48d12eec09229f560f3643b9f275653" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3218,9 +3292,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "memoffset" @@ -3282,9 +3356,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", @@ -3343,7 +3417,7 @@ checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3443,7 +3517,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3516,14 +3590,32 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.6" +version = "2.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +checksum = "47627dd7305c6a2d6c8c6bcd24c5a4c17dbbf425f4f9c5313e724b38fc9782e9" dependencies = [ "memchr", "ucd-trie", ] +[[package]] +name = "phf" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "010378780309880b08997fae13be7834dba947d36393bd372f2b1556deb2a2f6" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fd9027e2d9319be6349febd1db4e8d02aa544921200c9b777720ac34a3aa89" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.1.13" @@ -3541,7 +3633,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3566,6 +3658,12 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + [[package]] name = "poly1305" version = "0.8.0" @@ -3626,16 +3724,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.117", -] - [[package]] name = "primeorder" version = "0.13.6" @@ -3684,7 +3772,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3723,15 +3811,15 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", "cfg_aliases", "pin-project-lite", "quinn-proto", - "quinn-udp 0.5.14", + "quinn-udp 0.5.15", "rustc-hash", "rustls", "socket2 0.6.4", @@ -3743,15 +3831,16 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" dependencies = [ "aws-lc-rs", "bytes", - "getrandom 0.3.4", + "getrandom 0.4.3", "lru-slab", - "rand 0.9.4", + "rand 0.10.2", + "rand_pcg", "ring", "rustc-hash", "rustls", @@ -3765,16 +3854,16 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" dependencies = [ "cfg_aliases", "libc", "once_cell", "socket2 0.6.4", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3792,9 +3881,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -3842,12 +3931,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ - "chacha20 0.10.0", - "getrandom 0.4.2", + "chacha20 0.10.1", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -3896,6 +3985,15 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "rand_xorshift" version = "0.4.0" @@ -3907,9 +4005,9 @@ dependencies = [ [[package]] name = "rapidhash" -version = "4.4.1" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59" +checksum = "5da7e78a036ce858e8d55b7e7dc8ba3a88b78350fd2155d3591bbd966b58589e" dependencies = [ "rustversion", ] @@ -3996,14 +4094,14 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -4024,9 +4122,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "reqwest" @@ -4120,14 +4218,15 @@ dependencies = [ [[package]] name = "ruint" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0298da754d1395046b0afdc2f20ee76d29a8ae310cd30ffa84ed42acba9cb12a" +checksum = "45caf26f647c19115bf9c453c70ffe4a4a3a6390dceebd942610584f99b8ddce" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", "ark-ff 0.4.2", "ark-ff 0.5.0", + "ark-ff 0.6.0", "bytes", "fastrlp 0.3.1", "fastrlp 0.4.0", @@ -4154,9 +4253,9 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc-hex" @@ -4206,9 +4305,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ "aws-lc-rs", "log", @@ -4242,9 +4341,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ "web-time", "zeroize", @@ -4323,9 +4422,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "rusty-fork" @@ -4707,7 +4806,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4734,9 +4833,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" +checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" dependencies = [ "base64", "bs58", @@ -4754,14 +4853,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" +checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4809,7 +4908,7 @@ checksum = "94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4845,9 +4944,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3f15d4e239ebe08413eed880e0f9b5af4b40ee0472543320efa91d488e96a7" +checksum = "a6287fd675f713484342a89cbf0a386abef5f15919cfad607e5e1f19e1e15331" dependencies = [ "cc", "cfg-if", @@ -4904,6 +5003,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + [[package]] name = "slab" version = "0.4.12" @@ -4912,9 +5017,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" dependencies = [ "serde", ] @@ -4976,27 +5081,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "subtle" version = "2.6.1" @@ -5016,9 +5100,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -5034,7 +5118,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5054,7 +5138,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5091,7 +5175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", @@ -5123,7 +5207,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5134,7 +5218,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5157,12 +5241,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" dependencies = [ "deranged", - "itoa", "libc", "num-conv", "num_threads", @@ -5174,15 +5257,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" dependencies = [ "num-conv", "time-core", @@ -5247,7 +5330,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5381,7 +5464,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5533,11 +5616,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.2" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "serde_core", "wasm-bindgen", @@ -5591,27 +5674,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.122" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -5622,9 +5696,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.72" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ "js-sys", "wasm-bindgen", @@ -5632,9 +5706,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.122" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5642,60 +5716,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.122" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.122" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap 2.14.0", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap 2.14.0", - "semver 1.0.28", -] - [[package]] name = "wasmtimer" version = "0.4.3" @@ -5712,9 +5752,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.99" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -5732,9 +5772,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" dependencies = [ "rustls-pki-types", ] @@ -5802,7 +5842,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5813,7 +5853,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5824,7 +5864,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5835,7 +5875,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5908,15 +5948,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - [[package]] name = "windows-sys" version = "0.61.2" @@ -5965,30 +5996,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -6007,12 +6021,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -6031,12 +6039,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -6055,24 +6057,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -6091,12 +6081,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -6115,12 +6099,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -6139,12 +6117,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -6163,12 +6135,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" version = "1.0.3" @@ -6178,100 +6144,12 @@ dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap 2.14.0", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap 2.14.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap 2.14.0", - "log", - "semver 1.0.28", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "writeable" version = "0.6.3" @@ -6375,28 +6253,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.50" +version = "0.8.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" +checksum = "75726053136156d419e285b9b7eddaaea9e3fea6ce32eed44a89901f0bd98de1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.50" +version = "0.8.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" +checksum = "4714fd92cf900833d49538023a9b3915155210801d1c1169eba513b2addefd71" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6416,28 +6294,28 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6470,7 +6348,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 82a9d58..a7e265f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ant-protocol" -version = "2.2.2" +version = "2.3.0" edition = "2021" authors = ["MaidSafe Developers "] description = "Wire protocol for the Autonomi decentralized network (WithAutonomi fork)" @@ -23,7 +23,7 @@ path = "src/lib.rs" # breaking change for both downstream crates. saorsa-core = "0.26.2" saorsa-pqc = "0.5" -evmlib = "0.8.1" +evmlib = "0.9.0" # Content addressing (BLAKE3) blake3 = "1" diff --git a/src/chunk.rs b/src/chunk.rs index 351b574..82db826 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -264,6 +264,24 @@ pub enum ChunkQuoteResponse { quote: Vec, /// `true` when the chunk already exists on this node (skip payment). already_stored: bool, + /// ADR-0004: the serialized signed storage commitment the quote's price + /// was derived from, so the client can verify the binding before paying + /// ("the commitment arrived with the quote") and forward it as a sidecar + /// in the PUT bundle. `None` for a baseline quote (no commitment to + /// pin), or from a node that has not yet rotated a commitment. Opaque + /// bytes: `ant-protocol` stays agnostic of `ant-node`'s commitment type; + /// the client resolves it only to match the quote's `commitment_pin`. + /// + /// NOTE: this enum is encoded with **postcard** (see [`ChunkMessage::encode`]), + /// which is non-self-describing — `#[serde(default)]` does NOT make an + /// old-format `Success` (without this field) decode against new code, and + /// vice versa. ADR-0004 is a HARD CUTOVER: the whole fleet and clients + /// upgrade together, so old/new `ChunkQuoteResponse` never interoperate. + /// The attribute only keeps `Default`-based construction ergonomic; it is + /// not a wire-compat guarantee. (Contrast `PaymentQuote`/`PaymentProof`, + /// which ARE rmp-encoded, where tail `serde(default)` is decode-compatible.) + #[serde(default)] + commitment: Option>, }, /// Quote generation failed. Error(ProtocolError), @@ -298,6 +316,19 @@ pub enum MerkleCandidateQuoteResponse { Success { /// Serialized `MerklePaymentCandidateNode`. candidate_node: Vec, + /// ADR-0004: the serialized signed storage commitment the candidate's + /// price was derived from, so the client can fully resolve the binding + /// BEFORE paying (resolve-before-pay). `None` for a baseline candidate. + /// Unlike the single-node path, this commitment is NOT forwarded in the + /// merkle PUT bundle — sixteen per-candidate sidecars exceeded the + /// storer's payment-proof size budget, so current clients omit them and + /// storers resolve merkle pins from gossip or a `GetCommitmentByPin` + /// fetch (`MerklePaymentProof.commitment_sidecars` stays for legacy + /// bundles). Same semantics as + /// [`ChunkQuoteResponse::Success::commitment`]; postcard-encoded, so + /// this is a hard-cutover field, not an interop guarantee. + #[serde(default)] + commitment: Option>, }, /// Quote generation failed. Error(ProtocolError), @@ -598,6 +629,7 @@ mod tests { let candidate_node_bytes = vec![0xAA, 0xBB, 0xCC, 0xDD]; let response = MerkleCandidateQuoteResponse::Success { candidate_node: candidate_node_bytes.clone(), + commitment: Some(vec![0x11, 0x22]), }; let msg = ChunkMessage { request_id: 501, @@ -609,10 +641,14 @@ mod tests { assert_eq!(decoded.request_id, 501); if let ChunkMessageBody::MerkleCandidateQuoteResponse( - MerkleCandidateQuoteResponse::Success { candidate_node }, + MerkleCandidateQuoteResponse::Success { + candidate_node, + commitment, + }, ) = decoded.body { assert_eq!(candidate_node, candidate_node_bytes); + assert_eq!(commitment, Some(vec![0x11, 0x22])); } else { panic!("expected MerkleCandidateQuoteResponse::Success"); } diff --git a/src/lib.rs b/src/lib.rs index ca9c29a..cd47dbc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -154,6 +154,8 @@ pub mod pqc { /// Higher-level `api::sig::*` API (used for release signatures). pub mod api { - pub use saorsa_pqc::api::sig::{ml_dsa_65, MlDsaPublicKey, MlDsaSignature, MlDsaVariant}; + pub use saorsa_pqc::api::sig::{ + ml_dsa_65, MlDsaPublicKey, MlDsaSecretKey, MlDsaSignature, MlDsaVariant, + }; } } diff --git a/src/payment/commitment.rs b/src/payment/commitment.rs new file mode 100644 index 0000000..959e5fc --- /dev/null +++ b/src/payment/commitment.rs @@ -0,0 +1,256 @@ +//! The signed storage commitment — shared between node and client (ADR-0004). +//! +//! ADR-0004 makes a quote's price a function of the node's audited storage +//! commitment, and requires the **client** to fully verify that commitment +//! before paying ("the client pays nothing it cannot resolve" — the ceiling's +//! load-bearing wall). To do that the client needs the commitment type, its +//! pin (hash), and its signature/peer-binding check — exactly the pieces here. +//! +//! This is the **single source of truth** for the commitment wire type and its +//! verification: `ant-node` re-exports [`StorageCommitment`], [`commitment_hash`], +//! [`verify_commitment_signature`], and [`MAX_COMMITMENT_KEY_COUNT`] from this +//! module so the node (gossip/audit) and the client (resolve-before-pay) can +//! never disagree on what a valid commitment is or what pin it hashes to. +//! +//! Only the *verification* surface lives here. The Merkle tree, inclusion +//! paths, and signing live in `ant-node` (the responder/auditor own those); +//! the client never builds or signs a commitment, it only verifies one. + +use blake3::Hasher; +use saorsa_pqc::api::sig::{ml_dsa_65, MlDsaPublicKey, MlDsaSignature, MlDsaVariant}; +use serde::{Deserialize, Serialize}; + +/// Domain-separation tag for the commitment signature. +/// +/// Signed payload is verified under this context tag. +pub const DOMAIN_COMMITMENT: &[u8] = b"autonomi.ant.replication.storage_commitment.v1"; + +/// Domain-separation tag for the auditor's pin: BLAKE3 over (this tag || +/// canonical commitment blob). +pub const DOMAIN_COMMITMENT_HASH: &[u8] = b"autonomi.ant.replication.commitment_hash.v1"; + +/// Maximum number of keys a single commitment may cover. +/// +/// Bounds the Merkle path depth and responder-side tree memory. A node storing +/// more keys than this would need to split its claim. The client rejects any +/// quote whose `committed_key_count` exceeds this before paying, exactly as the +/// node does. +pub const MAX_COMMITMENT_KEY_COUNT: u32 = 1_000_000; + +/// Maximum serialized size of a single commitment sidecar blob (ADR-0004). +/// +/// A well-formed `StorageCommitment` is ~5.3 KiB (root 32 + `key_count` 4 + +/// `peer_id` 32 + pubkey 1952 + signature 3293 + serde framing). 8 KiB leaves +/// generous headroom while bounding the deserialize/verify work a malicious +/// quote responder or client can force on the hot verification path. A sidecar +/// larger than this is rejected before any parse attempt. +pub const MAX_COMMITMENT_SIDECAR_BYTES: usize = 8 * 1024; + +/// Signed storage commitment. +/// +/// Piggybacked on neighbour-sync gossip and shipped alongside a quote (ADR-0004). +/// The signature commits to the Merkle root, key count, sender peer ID, **and +/// the sender's ML-DSA-65 public key** under [`DOMAIN_COMMITMENT`]. +/// +/// Embedding the public key lets any receiver (including the paying client) +/// verify the signature without an external `PeerId → MlDsaPublicKey` lookup. +/// Binding the public key in the signed payload prevents a key-swap attack. +/// +/// Wire size ≈ 5.3 KiB (root 32 B + `key_count` 4 B + `peer_id` 32 B + pubkey +/// 1952 B + signature 3293 B). +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct StorageCommitment { + /// Merkle root over the responder's claimed keys. + pub root: [u8; 32], + /// Number of leaves committed over. + pub key_count: u32, + /// Sender peer ID, bound to the signature. + pub sender_peer_id: [u8; 32], + /// Sender's ML-DSA-65 public key bytes (1952 bytes). Embedded so receivers + /// can verify the signature without a separate pubkey directory. Bound by + /// the signature. + pub sender_public_key: Vec, + /// ML-DSA-65 signature over canonical commitment fields. 3293 bytes. + pub signature: Vec, +} + +/// The pin: `BLAKE3(DOMAIN_COMMITMENT_HASH || postcard(commitment))`. +/// +/// Equal commitments produce equal hashes; any change to `root`, `key_count`, +/// peer ID, pubkey, or signature changes the hash. A quote pins a commitment by +/// this value; resolving the quote means finding a commitment that hashes to +/// the pin. +/// +/// # Errors +/// +/// Returns `None` only if postcard fails to serialize the commitment — not +/// reachable for a well-formed ML-DSA-65 commitment. Callers treat `None` as a +/// malformed commitment and drop it. +#[must_use] +pub fn commitment_hash(c: &StorageCommitment) -> Option<[u8; 32]> { + let serialized = postcard::to_allocvec(c).ok()?; + let mut h = Hasher::new(); + h.update(DOMAIN_COMMITMENT_HASH); + h.update(&serialized); + Some(*h.finalize().as_bytes()) +} + +/// Canonical bytes the ML-DSA signature covers: the commitment fields minus the +/// signature itself. +/// +/// `sender_public_key` is length-prefixed and included so an adversary cannot +/// keep the body and re-sign under a different key. +fn commitment_signed_payload( + root: &[u8; 32], + key_count: u32, + sender_peer_id: &[u8; 32], + sender_public_key: &[u8], +) -> Vec { + let mut v = Vec::with_capacity(32 + 4 + 32 + 4 + sender_public_key.len()); + v.extend_from_slice(root); + v.extend_from_slice(&key_count.to_le_bytes()); + v.extend_from_slice(sender_peer_id); + let pk_len = u32::try_from(sender_public_key.len()).unwrap_or(u32::MAX); + v.extend_from_slice(&pk_len.to_le_bytes()); + v.extend_from_slice(sender_public_key); + v +} + +/// Verify a commitment's ML-DSA-65 signature against its **embedded** public +/// key. Does NOT check the peer binding (`BLAKE3(pubkey) == sender_peer_id`) — +/// callers that need it (the client, the node) check it separately so the same +/// function serves both the "trust the embedded key" and "bind to a peer" uses. +#[must_use] +pub fn verify_commitment_signature(c: &StorageCommitment) -> bool { + let Ok(public_key) = MlDsaPublicKey::from_bytes(MlDsaVariant::MlDsa65, &c.sender_public_key) + else { + return false; + }; + let payload = commitment_signed_payload( + &c.root, + c.key_count, + &c.sender_peer_id, + &c.sender_public_key, + ); + let Ok(sig) = MlDsaSignature::from_bytes(MlDsaVariant::MlDsa65, &c.signature) else { + return false; + }; + ml_dsa_65() + .verify_with_context(&public_key, &payload, &sig, DOMAIN_COMMITMENT) + .unwrap_or(false) +} + +#[cfg(test)] +#[allow(clippy::unwrap_used, clippy::expect_used)] +mod tests { + use super::*; + use saorsa_pqc::api::sig::ml_dsa_65; + + /// Build a genuinely-signed commitment (fresh ML-DSA-65 keypair, signed over + /// the exact `commitment_signed_payload` under `DOMAIN_COMMITMENT`) — the same + /// thing the node produces. Returns the commitment and the keypair's public + /// bytes so tamper tests can key-swap. + fn signed_commitment(root: [u8; 32], key_count: u32, peer_id: [u8; 32]) -> StorageCommitment { + let (pk, sk) = ml_dsa_65().generate_keypair().unwrap(); + let pk_bytes = pk.to_bytes(); + let payload = commitment_signed_payload(&root, key_count, &peer_id, &pk_bytes); + let sig = ml_dsa_65() + .sign_with_context(&sk, &payload, DOMAIN_COMMITMENT) + .unwrap(); + StorageCommitment { + root, + key_count, + sender_peer_id: peer_id, + sender_public_key: pk_bytes, + signature: sig.to_bytes(), + } + } + + /// A malformed commitment (bad pubkey / signature) fails verification + /// rather than panicking — the client runs this on untrusted bytes. + #[test] + fn verify_rejects_malformed_without_panic() { + let c = StorageCommitment { + root: [0u8; 32], + key_count: 1, + sender_peer_id: [0u8; 32], + sender_public_key: vec![0u8; 10], + signature: vec![0u8; 10], + }; + assert!(!verify_commitment_signature(&c)); + // hash is still computable over any well-formed struct. + assert!(commitment_hash(&c).is_some()); + } + + /// The pin is deterministic and changes when any field changes. + #[test] + fn commitment_hash_is_deterministic_and_field_sensitive() { + let c = StorageCommitment { + root: [1u8; 32], + key_count: 5, + sender_peer_id: [2u8; 32], + sender_public_key: vec![3u8; 20], + signature: vec![4u8; 20], + }; + let h1 = commitment_hash(&c).unwrap(); + let h2 = commitment_hash(&c).unwrap(); + assert_eq!(h1, h2, "same commitment -> same pin"); + + let mut c2 = c.clone(); + c2.key_count = 6; + assert_ne!( + commitment_hash(&c2).unwrap(), + h1, + "changing key_count must change the pin" + ); + } + + /// A correctly-signed commitment verifies. Without this, a regression that + /// made `verify_commitment_signature` always return `false` (or ignore the + /// signature) would pass every other test in this module. + #[test] + fn verify_accepts_a_correctly_signed_commitment() { + let c = signed_commitment([7u8; 32], 42, [9u8; 32]); + assert!( + verify_commitment_signature(&c), + "a genuinely signed commitment must verify" + ); + } + + /// The signature covers `root`, `key_count`, `peer_id`, and the embedded + /// pubkey — mutating any of them after signing must fail verification. This + /// is the ADR-0004 "the fields are covered by the signature" invariant. + #[test] + fn verify_rejects_any_field_tampered_after_signing() { + // key_count + let mut c = signed_commitment([1u8; 32], 100, [2u8; 32]); + c.key_count = c.key_count.wrapping_add(1); + assert!( + !verify_commitment_signature(&c), + "tampered key_count must fail" + ); + + // root + let mut c = signed_commitment([1u8; 32], 100, [2u8; 32]); + c.root[0] ^= 0xff; + assert!(!verify_commitment_signature(&c), "tampered root must fail"); + + // sender_peer_id + let mut c = signed_commitment([1u8; 32], 100, [2u8; 32]); + c.sender_peer_id[0] ^= 0xff; + assert!( + !verify_commitment_signature(&c), + "tampered peer_id must fail" + ); + + // key-swap: keep the body + signature, swap in a different valid pubkey. + // The pubkey is bound into the signed payload, so this must fail. + let mut c = signed_commitment([1u8; 32], 100, [2u8; 32]); + let (other_pk, _) = ml_dsa_65().generate_keypair().unwrap(); + c.sender_public_key = other_pk.to_bytes(); + assert!( + !verify_commitment_signature(&c), + "swapping the embedded pubkey must fail" + ); + } +} diff --git a/src/payment/mod.rs b/src/payment/mod.rs index 2740fb7..68f10e0 100644 --- a/src/payment/mod.rs +++ b/src/payment/mod.rs @@ -8,6 +8,10 @@ //! on `PaymentVault` — keeping both halves in one crate means the //! encoding, validation, and on-chain interaction are tested end to end. +/// Signed storage-commitment type + verification shared by node and client (ADR-0004). +pub mod commitment; +/// Quadratic storage-pricing formula shared by node and client (ADR-0004). +pub mod pricing; /// Payment proof serialization and type tagging. pub mod proof; /// `SingleNodePayment` construction, on-chain payment, and verification. @@ -15,6 +19,10 @@ pub mod single_node; /// Pure ML-DSA-65 verification helpers for quotes and merkle candidates. pub mod verify; +pub use commitment::{ + commitment_hash, verify_commitment_signature, StorageCommitment, MAX_COMMITMENT_KEY_COUNT, +}; +pub use pricing::{calculate_price, derive_records_stored_from_price}; pub use proof::{ deserialize_merkle_proof, deserialize_proof, detect_proof_type, serialize_merkle_proof, serialize_single_node_proof, PaymentProof, ProofType, diff --git a/src/payment/pricing.rs b/src/payment/pricing.rs new file mode 100644 index 0000000..dd731b5 --- /dev/null +++ b/src/payment/pricing.rs @@ -0,0 +1,232 @@ +//! Quadratic pricing with a baseline floor. +//! +//! Formula: `price_per_chunk_ANT(n) = BASELINE + K × (n / D)²` +//! +//! The non-zero `BASELINE` makes empty nodes charge a meaningful spam-barrier +//! price, and `K` is anchored so per-GB USD pricing matches real-world targets +//! at the current ~$0.10/ANT token price. An earlier formula produced ~$25/GB +//! at the lower stable boundary and ~$0/GB when nodes were empty — both +//! unreasonable. +//! +//! This is the **single source of truth** both the node (when pricing a quote) +//! and the client (when verifying ADR-0004's forced price before paying) must +//! agree on. It lives here, in the shared wire/contract crate, so the two sides +//! can never drift: `ant-node` re-exports [`calculate_price`] from this module +//! rather than defining its own. +//! +//! ## Parameters +//! +//! | Constant | Value | Role | +//! |-----------|---------------|-------------------------------------------------| +//! | BASELINE | 0.00390625 ANT| Price at empty (bootstrap-phase spam barrier) | +//! | K | 0.03515625 ANT| Quadratic coefficient | +//! | D | 6000 | Lower stable boundary (records stored) | + +use evmlib::common::Amount; + +/// Lower stable boundary of the quadratic curve, in records stored. +const PRICING_DIVISOR: u128 = 6000; + +/// `PRICING_DIVISOR²`, precomputed to avoid repeated multiplication. +const DIVISOR_SQUARED: u128 = PRICING_DIVISOR * PRICING_DIVISOR; + +/// Baseline price at empty / bootstrap-phase spam barrier. +/// +/// `0.00390625 ANT × 10¹⁸ wei/ANT = 3_906_250_000_000_000 wei`. +const PRICE_BASELINE_WEI: u128 = 3_906_250_000_000_000; + +/// Quadratic coefficient `K`. +/// +/// `0.03515625 ANT × 10¹⁸ wei/ANT = 35_156_250_000_000_000 wei`. +const PRICE_COEFFICIENT_WEI: u128 = 35_156_250_000_000_000; + +/// Price increment per squared record after simplifying `PRICE_COEFFICIENT_WEI / DIVISOR_SQUARED`. +const PRICE_PER_RECORD_SQUARED_WEI: u128 = PRICE_COEFFICIENT_WEI / DIVISOR_SQUARED; + +/// Derive the quoted record count from a quote price. +/// +/// This is the inverse of [`calculate_price`]. It intentionally floors to the +/// nearest integer record count. +/// +/// Saturates to `u64::MAX` for any price that would otherwise overflow `u64`. +/// This matters because the node verifier calls this on untrusted deserialized +/// `quote.price` values BEFORE signature verification: a panic here is a +/// pre-auth crash vector. Saturating leaves the delta check to reject the +/// quote as out-of-range without aborting the process. +#[must_use] +pub fn derive_records_stored_from_price(price: Amount) -> u64 { + let baseline = Amount::from(PRICE_BASELINE_WEI); + if price <= baseline { + return 0; + } + + let excess = price - baseline; + let n_squared = excess / Amount::from(PRICE_PER_RECORD_SQUARED_WEI); + let root = n_squared.root(2); + // ruint's `Uint::to::()` panics on overflow. We MUST NOT panic here: + // a hostile oversized price would otherwise be a pre-auth crash vector. + // Saturate to `u64::MAX` instead; the delta check rejects out-of-range quotes. + if root > Amount::from(u64::MAX) { + u64::MAX + } else { + root.to::() + } +} + +/// Calculate storage price in wei from the number of close records stored. +/// +/// Formula: `price_wei = BASELINE + n² × K / D²` +/// +/// where `BASELINE = 0.00390625 ANT`, `K = 0.03515625 ANT`, and `D = 6000`. +/// U256 arithmetic prevents overflow for large record counts. +#[must_use] +pub fn calculate_price(close_records_stored: usize) -> Amount { + let n = Amount::from(close_records_stored); + let n_squared = n.saturating_mul(n); + let quadratic_wei = n_squared.saturating_mul(Amount::from(PRICE_COEFFICIENT_WEI)) + / Amount::from(DIVISOR_SQUARED); + Amount::from(PRICE_BASELINE_WEI).saturating_add(quadratic_wei) +} + +#[cfg(test)] +#[allow(clippy::unwrap_used, clippy::expect_used)] +mod tests { + use super::*; + + /// 1 token = 10¹⁸ wei (used for test sanity-checks). + const WEI_PER_TOKEN: u128 = 1_000_000_000_000_000_000; + + /// Helper: expected price matching the formula `BASELINE + n² × K / D²`. + fn expected_price(n: u64) -> Amount { + let n_amt = Amount::from(n); + let quad = + n_amt * n_amt * Amount::from(PRICE_COEFFICIENT_WEI) / Amount::from(DIVISOR_SQUARED); + Amount::from(PRICE_BASELINE_WEI) + quad + } + + #[test] + fn test_zero_records_gets_baseline() { + let price = calculate_price(0); + assert_eq!(price, Amount::from(PRICE_BASELINE_WEI)); + } + + #[test] + fn test_baseline_is_nonzero_spam_barrier() { + assert!(calculate_price(0) > Amount::ZERO); + assert!(calculate_price(1) > calculate_price(0)); + } + + #[test] + fn test_one_record_above_baseline() { + let price = calculate_price(1); + assert_eq!(price, expected_price(1)); + assert!(price > Amount::from(PRICE_BASELINE_WEI)); + } + + #[test] + fn test_at_divisor_is_baseline_plus_k() { + let price = calculate_price(6000); + let expected = Amount::from(PRICE_BASELINE_WEI + PRICE_COEFFICIENT_WEI); + assert_eq!(price, expected); + } + + #[test] + fn test_double_divisor_is_baseline_plus_four_k() { + let price = calculate_price(12000); + let expected = Amount::from(PRICE_BASELINE_WEI + 4 * PRICE_COEFFICIENT_WEI); + assert_eq!(price, expected); + } + + #[test] + fn test_triple_divisor_is_baseline_plus_nine_k() { + let price = calculate_price(18000); + let expected = Amount::from(PRICE_BASELINE_WEI + 9 * PRICE_COEFFICIENT_WEI); + assert_eq!(price, expected); + } + + #[test] + fn test_smooth_pricing_no_staircase() { + let price_6k = calculate_price(6000); + let price_11k = calculate_price(11999); + assert!( + price_11k > price_6k, + "11999 records ({price_11k}) should cost more than 6000 ({price_6k})" + ); + } + + #[test] + fn test_price_increases_with_records() { + let price_low = calculate_price(6000); + let price_mid = calculate_price(12000); + let price_high = calculate_price(18000); + assert!(price_mid > price_low); + assert!(price_high > price_mid); + } + + #[test] + fn test_price_increases_monotonically() { + let mut prev_price = Amount::ZERO; + for records in (0..60000).step_by(100) { + let price = calculate_price(records); + assert!( + price >= prev_price, + "Price at {records} records ({price}) should be >= previous ({prev_price})" + ); + prev_price = price; + } + } + + #[test] + fn test_large_value_no_overflow() { + let price = calculate_price(usize::MAX); + assert!(price > Amount::ZERO); + } + + #[test] + fn test_price_deterministic() { + let price1 = calculate_price(12000); + let price2 = calculate_price(12000); + assert_eq!(price1, price2); + } + + #[test] + fn test_quadratic_growth_excluding_baseline() { + let base = Amount::from(PRICE_BASELINE_WEI); + let quad_6k = calculate_price(6000) - base; + let quad_12k = calculate_price(12000) - base; + let quad_24k = calculate_price(24000) - base; + assert_eq!(quad_12k, quad_6k * Amount::from(4u64)); + assert_eq!(quad_24k, quad_6k * Amount::from(16u64)); + } + + #[test] + fn test_small_record_counts_near_baseline() { + let price = calculate_price(100); + assert_eq!(price, expected_price(100)); + assert!(price < Amount::from(WEI_PER_TOKEN)); + assert!(price > Amount::from(PRICE_BASELINE_WEI)); + } + + #[test] + fn test_derive_records_stored_from_price_round_trips() { + for records in [0usize, 1, 5, 100, 6_000, 12_000, 60_000] { + let price = calculate_price(records); + assert_eq!(derive_records_stored_from_price(price), records as u64); + } + } + + #[test] + fn test_derive_records_stored_from_baseline_or_lower_is_zero() { + assert_eq!(derive_records_stored_from_price(Amount::ZERO), 0); + assert_eq!( + derive_records_stored_from_price(Amount::from(PRICE_BASELINE_WEI)), + 0 + ); + } + + #[test] + fn test_derive_records_stored_from_max_price_saturates_no_panic() { + let v = derive_records_stored_from_price(Amount::MAX); + assert_eq!(v, u64::MAX); + } +} diff --git a/src/payment/proof.rs b/src/payment/proof.rs index ca2dff9..fbb365d 100644 --- a/src/payment/proof.rs +++ b/src/payment/proof.rs @@ -20,6 +20,17 @@ pub struct PaymentProof { /// Transaction hashes from the on-chain payment. /// Typically contains one hash for the median (non-zero) quote. pub tx_hashes: Vec, + /// ADR-0004 commitment sidecars: the signed `StorageCommitment` each quote + /// pinned, so a storer can cross-check the quote's claimed count against the + /// original commitment **synchronously**, without a gossip-cache hit or a + /// post-payment fetch ("the commitment arrived with the quote"). Each entry + /// is an opaque serialized commitment blob — `ant-protocol` stays agnostic + /// of `ant-node`'s commitment type; the node deserializes and validates each + /// with the full peer/pubkey/signature/hash gates before trusting it. + /// Tail-placed, `serde(default)`: an old proof (or a baseline-only bundle) + /// simply carries none, and the node falls back to gossip/fetch. + #[serde(default)] + pub commitment_sidecars: Vec>, } /// The detected type of a payment proof. @@ -83,15 +94,27 @@ pub fn serialize_merkle_proof( /// /// Returns an error if the tag is missing or the bytes cannot be deserialized. pub fn deserialize_proof(bytes: &[u8]) -> Result<(ProofOfPayment, Vec), String> { + let proof = deserialize_single_node_proof(bytes)?; + Ok((proof.proof_of_payment, proof.tx_hashes)) +} + +/// Deserialize the full single-node [`PaymentProof`], including the ADR-0004 +/// `commitment_sidecars`. Use this where the sidecars are needed (the node-side +/// cross-check); [`deserialize_proof`] remains for callers that only want the +/// quotes + tx hashes. +/// +/// # Errors +/// +/// Returns an error if the tag is missing or the bytes cannot be deserialized. +pub fn deserialize_single_node_proof(bytes: &[u8]) -> Result { if bytes.first() != Some(&PROOF_TAG_SINGLE_NODE) { return Err("Missing single-node proof tag byte".to_string()); } let payload = bytes .get(1..) .ok_or_else(|| "Single-node proof tag present but no payload".to_string())?; - let proof = rmp_serde::from_slice::(payload) - .map_err(|e| format!("Failed to deserialize single-node proof: {e}"))?; - Ok((proof.proof_of_payment, proof.tx_hashes)) + rmp_serde::from_slice::(payload) + .map_err(|e| format!("Failed to deserialize single-node proof: {e}")) } /// Deserialize proof bytes as a `MerklePaymentProof`. @@ -139,6 +162,8 @@ mod tests { rewards_address: RewardsAddress::new([1u8; 20]), pub_key: vec![], signature: vec![], + committed_key_count: 0, + commitment_pin: None, } } @@ -155,6 +180,7 @@ mod tests { let proof = PaymentProof { proof_of_payment: make_proof_of_payment(), tx_hashes: vec![tx_hash], + commitment_sidecars: vec![], }; let bytes = serialize_single_node_proof(&proof).unwrap(); @@ -170,6 +196,7 @@ mod tests { let proof = PaymentProof { proof_of_payment: make_proof_of_payment(), tx_hashes: vec![], + commitment_sidecars: vec![], }; let bytes = serialize_single_node_proof(&proof).unwrap(); @@ -192,6 +219,7 @@ mod tests { let proof = PaymentProof { proof_of_payment: make_proof_of_payment(), tx_hashes: vec![], + commitment_sidecars: vec![], }; let raw_bytes = rmp_serde::to_vec(&proof).unwrap(); let result = deserialize_proof(&raw_bytes); @@ -205,6 +233,7 @@ mod tests { let proof = PaymentProof { proof_of_payment: make_proof_of_payment(), tx_hashes: vec![tx1, tx2], + commitment_sidecars: vec![], }; let bytes = serialize_single_node_proof(&proof).unwrap(); @@ -257,6 +286,7 @@ mod tests { let proof = PaymentProof { proof_of_payment: make_proof_of_payment(), tx_hashes: vec![tx_hash], + commitment_sidecars: vec![], }; let tagged_bytes = serialize_single_node_proof(&proof).unwrap(); @@ -306,8 +336,13 @@ mod tests { let price = Amount::from(1024u64); #[allow(clippy::cast_possible_truncation)] let reward_address = RewardsAddress::new([i as u8; 20]); - let msg = - MerklePaymentCandidateNode::bytes_to_sign(&price, &reward_address, timestamp); + let msg = MerklePaymentCandidateNode::bytes_to_sign( + &price, + &reward_address, + timestamp, + 0, + &None, + ); let sk = MlDsaSecretKey::from_bytes(secret_key.as_bytes()).expect("sk"); let signature = ml_dsa.sign(&sk, &msg).expect("sign").as_bytes().to_vec(); @@ -316,6 +351,8 @@ mod tests { price, reward_address, merkle_payment_timestamp: timestamp, + committed_key_count: 0, + commitment_pin: None, signature, } }); diff --git a/src/payment/single_node.rs b/src/payment/single_node.rs index 98e02bd..4fd89e9 100644 --- a/src/payment/single_node.rs +++ b/src/payment/single_node.rs @@ -278,6 +278,8 @@ mod tests { rewards_address: RewardsAddress::new([rewards_addr_seed; 20]), pub_key: vec![], signature: vec![], + committed_key_count: 0, + commitment_pin: None, } } @@ -476,6 +478,8 @@ mod tests { rewards_address: RewardsAddress::new([1u8; 20]), pub_key: vec![], signature: vec![], + committed_key_count: 0, + commitment_pin: None, }; quotes_with_prices.push((quote, Amount::from(*price))); } @@ -586,6 +590,8 @@ mod tests { rewards_address: RewardsAddress::new([i as u8 + 1; 20]), pub_key: vec![], signature: vec![], + committed_key_count: 0, + commitment_pin: None, }; quotes_with_prices.push((quote, Amount::from(*price))); } @@ -684,8 +690,9 @@ mod tests { let chunk_xor = XorName::random(&mut rand::thread_rng()); // Prices are arbitrary but distinct so median selection is unambiguous. - // The ant-node crate owns the real `calculate_price` — this crate only - // exercises payment construction and on-chain verification. + // This test only exercises payment construction and on-chain + // verification; the real `calculate_price` (now in this crate's + // `payment::pricing`, per ADR-0004) is unit-tested there. let mut quotes_with_prices = Vec::new(); for i in 0..CLOSE_GROUP_SIZE { #[allow(clippy::cast_possible_truncation)] @@ -698,6 +705,8 @@ mod tests { rewards_address: wallet.address(), pub_key: vec![], signature: vec![], + committed_key_count: 0, + commitment_pin: None, }; quotes_with_prices.push((quote, price)); diff --git a/src/payment/verify.rs b/src/payment/verify.rs index e44a691..26ff842 100644 --- a/src/payment/verify.rs +++ b/src/payment/verify.rs @@ -116,10 +116,15 @@ pub fn verify_merkle_candidate_signature(candidate: &MerklePaymentCandidateNode) } }; + // ADR-0004: the per-node signature now covers the commitment binding + // (`committed_key_count`, `commitment_pin`) too, so a count/pin mismatch is + // genuine same-key-signed evidence. Must match `bytes_to_sign` in evmlib. let msg = MerklePaymentCandidateNode::bytes_to_sign( &candidate.price, &candidate.reward_address, candidate.merkle_payment_timestamp, + candidate.committed_key_count, + &candidate.commitment_pin, ); let ml_dsa = MlDsa65::new(); @@ -160,6 +165,8 @@ mod tests { rewards_address: RewardsAddress::new([2u8; 20]), pub_key: pub_key_bytes, signature: vec![], + committed_key_count: 0, + commitment_pin: None, }; let msg = quote.bytes_for_sig(); let sk = MlDsaSecretKey::from_bytes(secret_key.as_bytes()).expect("sk"); @@ -206,6 +213,8 @@ mod tests { rewards_address: RewardsAddress::new([0u8; 20]), pub_key: vec![], signature: vec![], + committed_key_count: 0, + commitment_pin: None, }; assert!(!verify_quote_signature("e)); } @@ -221,6 +230,8 @@ mod tests { rewards_address: RewardsAddress::new([0u8; 20]), pub_key: pub_key.as_bytes().to_vec(), signature: vec![], + committed_key_count: 0, + commitment_pin: None, }; assert!(!verify_quote_signature("e)); } @@ -231,10 +242,14 @@ mod tests { let price = Amount::from(1024u64); let reward_address = RewardsAddress::new([3u8; 20]); let merkle_payment_timestamp = 1_700_000_000u64; + let committed_key_count = 7u32; + let commitment_pin = Some([5u8; 32]); let msg = MerklePaymentCandidateNode::bytes_to_sign( &price, &reward_address, merkle_payment_timestamp, + committed_key_count, + &commitment_pin, ); let sk = MlDsaSecretKey::from_bytes(secret_key.as_bytes()).expect("sk"); let signature = ml_dsa.sign(&sk, &msg).expect("sign").as_bytes().to_vec(); @@ -243,6 +258,8 @@ mod tests { price, reward_address, merkle_payment_timestamp, + committed_key_count, + commitment_pin, signature, } }