From 5aa11d9a95c641076d2c793a81cf6b5baab5f1ac Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Thu, 23 Jan 2025 21:03:06 -0600 Subject: [PATCH 001/121] reorganize tutorial --- ...sync-conflict-20250121-102039-CTTYEUX.lock | 6400 +++++++++++++++++ docs/src/README.md | 128 +- docs/src/architecture/transport.md | 2 +- docs/src/components/delegates.md | 8 +- docs/src/components/overview.md | 8 +- docs/src/components/ui.md | 6 +- docs/src/contract-interface.md | 50 +- docs/src/example-app.md | 7 +- docs/src/examples/blind-trust-tokens.md | 2 +- docs/src/introduction.md | 8 +- docs/src/tutorial.md | 506 +- 11 files changed, 6660 insertions(+), 465 deletions(-) create mode 100644 Cargo.sync-conflict-20250121-102039-CTTYEUX.lock diff --git a/Cargo.sync-conflict-20250121-102039-CTTYEUX.lock b/Cargo.sync-conflict-20250121-102039-CTTYEUX.lock new file mode 100644 index 000000000..1851ad59b --- /dev/null +++ b/Cargo.sync-conflict-20250121-102039-CTTYEUX.lock @@ -0,0 +1,6400 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli 0.31.1", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + +[[package]] +name = "anyhow" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-io" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.6.0", + "parking", + "polling 3.7.4", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.4.0", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "async-trait" +version = "0.1.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "asynchronous-codec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" +dependencies = [ + "bytes", + "futures-sink", + "futures-util", + "memchr", + "pin-project-lite", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "base64 0.22.1", + "bytes", + "futures-util", + "http 1.2.0", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sha1", + "sync_wrapper", + "tokio", + "tokio-tungstenite 0.24.0", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.2.0", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object 0.36.7", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.8.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.96", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +dependencies = [ + "serde", +] + +[[package]] +name = "blake3" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bstr" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" +dependencies = [ + "memchr", + "regex-automata 0.4.9", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive 0.6.12", + "ptr_meta 0.1.4", + "simdutf8", +] + +[[package]] +name = "bytecheck" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c8f430744b23b54ad15161fcbc22d82a29b73eacbe425fea23ec822600bc6f" +dependencies = [ + "bytecheck_derive 0.8.0", + "ptr_meta 0.3.0", + "rancor", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytecheck_derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523363cbe1df49b68215efdf500b103ac3b0fb4836aed6d15689a076eadb8fff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "bytemuck" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cache-padded" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" + +[[package]] +name = "castaway" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" + +[[package]] +name = "cc" +version = "1.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "chrono" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +dependencies = [ + "android-tzdata", + "arbitrary", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "cmake" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", + "portable-atomic", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "corosensei" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad067b451c08956709f8762dba86e049c124ea52858e3ab8d076ba2892caa437" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "scopeguard", + "windows-sys 0.59.0", +] + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.110.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "305d51c180ebdc46ef61bc60c54ae6512db3bc9a05842a1f1e762e45977019ab" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-bitset" +version = "0.110.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "690d8ae6c73748e5ce3d8fe59034dceadb8823e6c8994ba324141c5eae909b0e" + +[[package]] +name = "cranelift-codegen" +version = "0.110.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7ca95e831c18d1356da783765c344207cbdffea91e13e47fa9327dbb2e0719" +dependencies = [ + "bumpalo", + "cranelift-bforest", + "cranelift-bitset", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-control", + "cranelift-entity", + "cranelift-isle", + "gimli 0.28.1", + "hashbrown 0.14.5", + "log", + "regalloc2", + "rustc-hash", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.110.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a2d2ab65e6cbf91f81781d8da65ec2005510f18300eff21a99526ed6785863" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.110.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efcff860573cf3db9ae98fbd949240d78b319df686cc306872e7fab60e9c84d7" + +[[package]] +name = "cranelift-control" +version = "0.110.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d70e5b75c2d5541ef80a99966ccd97aaa54d2a6af19ea31759a28538e1685a" +dependencies = [ + "arbitrary", +] + +[[package]] +name = "cranelift-entity" +version = "0.110.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a48cb0a194c9ba82fec35a1e492055388d89b2e3c03dee9dcf2488892be8004d" +dependencies = [ + "cranelift-bitset", +] + +[[package]] +name = "cranelift-frontend" +version = "0.110.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8327afc6c1c05f4be62fefce5b439fa83521c65363a322e86ea32c85e7ceaf64" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.110.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56b08621c00321efcfa3eee6a3179adc009e21ea8d24ca7adc3c326184bc3f48" + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core", + "typenum", +] + +[[package]] +name = "csv" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "ctrlc" +version = "3.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +dependencies = [ + "nix", + "windows-sys 0.59.0", +] + +[[package]] +name = "curl" +version = "0.4.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9fb4d13a1be2b58f14d60adba57c9834b78c62fd86c3e76a148f732686e9265" +dependencies = [ + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2", + "windows-sys 0.52.0", +] + +[[package]] +name = "curl-sys" +version = "0.4.78+curl-8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eec768341c5c7789611ae51cf6c459099f22e64a5d5d0ce4892434e33821eaf" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "windows-sys 0.52.0", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.96", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f" + +[[package]] +name = "deflate64" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" + +[[package]] +name = "delegate" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297806318ef30ad066b15792a8372858020ae3ca2e414ee6c2133b1eb9e9e945" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "directories" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.5.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users 0.4.6", + "winapi", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +dependencies = [ + "serde", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "enum-iterator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "enumset" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", + "portable-atomic", + "portable-atomic-util", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +dependencies = [ + "event-listener 5.4.0", + "pin-project-lite", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fdev" +version = "0.0.7" +dependencies = [ + "anyhow", + "axum", + "bincode", + "bs58", + "chrono", + "clap", + "dashmap", + "either", + "freenet", + "freenet-stdlib", + "futures", + "glob", + "http 1.2.0", + "pico-args", + "prettytable-rs", + "rand", + "reqwest", + "semver", + "serde", + "serde_json", + "serde_with", + "tar", + "thiserror 2.0.11", + "tokio", + "tokio-tungstenite 0.24.0", + "toml", + "tracing", + "tracing-subscriber", + "xz2", +] + +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + +[[package]] +name = "flatbuffers" +version = "24.12.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f1baf0dbf96932ec9a3038d57900329c015b0bfb7b63d904f3bc27e2b02a096" +dependencies = [ + "bitflags 1.3.2", + "rustc_version", +] + +[[package]] +name = "flate2" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "freenet" +version = "0.1.0-rc1" +dependencies = [ + "aes-gcm", + "anyhow", + "arbitrary", + "arc-swap", + "asynchronous-codec", + "axum", + "bincode", + "blake3", + "bs58", + "byteorder", + "bytes", + "cache-padded", + "chacha20poly1305", + "chrono", + "clap", + "cookie", + "crossbeam", + "ctrlc", + "dashmap", + "delegate", + "directories", + "either", + "flatbuffers", + "freenet-stdlib", + "futures", + "headers", + "hickory-resolver", + "httptest", + "itertools 0.14.0", + "notify", + "once_cell", + "opentelemetry 0.27.1", + "opentelemetry-jaeger", + "opentelemetry-otlp", + "opentelemetry_sdk 0.27.1", + "ordered-float 4.6.0", + "parking_lot", + "pav_regression", + "pico-args", + "pkcs8", + "rand", + "redb", + "reqwest", + "rsa", + "semver", + "serde", + "serde_json", + "serde_with", + "sqlx", + "statrs", + "stretto", + "tar", + "tempfile", + "thiserror 2.0.11", + "time", + "tokio", + "tokio-tungstenite 0.26.1", + "toml", + "tower-http", + "tracing", + "tracing-opentelemetry", + "tracing-subscriber", + "ulid", + "unsigned-varint", + "wasmer", + "xz2", +] + +[[package]] +name = "freenet-macros" +version = "0.0.5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "freenet-ping" +version = "0.1.0" +dependencies = [ + "chrono", + "clap", + "freenet-ping-types", + "freenet-stdlib", + "futures", + "names", + "serde_json", + "tokio", + "tokio-tungstenite 0.24.0", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "freenet-ping-contract" +version = "0.1.0" +dependencies = [ + "freenet-ping-types", + "freenet-stdlib", + "serde_json", +] + +[[package]] +name = "freenet-ping-types" +version = "0.1.0" +dependencies = [ + "chrono", + "clap", + "freenet-stdlib", + "humantime", + "humantime-serde", + "serde", +] + +[[package]] +name = "freenet-stdlib" +version = "0.0.8" +dependencies = [ + "arbitrary", + "bincode", + "blake3", + "bs58", + "byteorder", + "chrono", + "flatbuffers", + "freenet-macros", + "futures", + "js-sys", + "once_cell", + "rand", + "semver", + "serde", + "serde-wasm-bindgen 0.6.5", + "serde_bytes", + "serde_json", + "serde_with", + "thiserror 1.0.69", + "tokio", + "tokio-tungstenite 0.24.0", + "tracing", + "tracing-subscriber", + "wasm-bindgen", + "wasmer", + "web-sys", +] + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +dependencies = [ + "fallible-iterator", + "indexmap 2.7.0", + "stable_deref_trait", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "h2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.2.0", + "indexmap 2.7.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.2", +] + +[[package]] +name = "headers" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core", + "http 1.2.0", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http 1.2.0", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hickory-proto" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447afdcdb8afb9d0a852af6dc65d9b285ce720ed7a59e42a8bf2e931c67bc1b5" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", + "thiserror 1.0.69", + "tinyvec", + "tokio", + "tokio-rustls 0.24.1", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2e2aba9c389ce5267d31cf1e4dace82390ae276b0b364ea55630b1fa1b44b4" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand", + "resolv-conf", + "rustls 0.21.12", + "smallvec", + "thiserror 1.0.69", + "tokio", + "tokio-rustls 0.24.1", + "tracing", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.2.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.2.0", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "httptest" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0fc8d140f1f0f3e7f821c8eff55cd13966db7a3370b2d9a7b08e9ec8ee8786" +dependencies = [ + "bstr", + "bytes", + "crossbeam-channel", + "form_urlencoded", + "futures", + "http 1.2.0", + "http-body-util", + "hyper", + "hyper-util", + "log", + "once_cell", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime", + "serde", +] + +[[package]] +name = "hyper" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http 1.2.0", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +dependencies = [ + "futures-util", + "http 1.2.0", + "hyper", + "hyper-util", + "rustls 0.23.21", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.1", + "tower-service", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.2.0", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[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.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", + "serde", +] + +[[package]] +name = "inotify" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" +dependencies = [ + "bitflags 2.8.0", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" + +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "isahc" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9" +dependencies = [ + "async-channel 1.9.0", + "castaway", + "crossbeam-utils", + "curl", + "curl-sys", + "event-listener 2.5.3", + "futures-lite 1.13.0", + "http 0.2.12", + "log", + "once_cell", + "polling 2.8.0", + "slab", + "sluice", + "tracing", + "tracing-futures", + "url", + "waker-fn", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.8.0", + "libc", + "redox_syscall", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "lockfree-object-pool" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" + +[[package]] +name = "log" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "matrixmultiply" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d28bba84adfe6646737845bc5ebbfa2c08424eb1c37e94a1fd2a82adb56a872" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "more-asserts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" + +[[package]] +name = "munge" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64142d38c84badf60abf06ff9bd80ad2174306a5b11bd4706535090a30a419df" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb5c1d8184f13f7d0ccbeeca0def2f9a181bce2624302793005f5ca8aa62e5e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "nalgebra" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +dependencies = [ + "approx", + "matrixmultiply", + "num-complex", + "num-rational", + "num-traits", + "rand", + "rand_distr", + "simba", + "typenum", +] + +[[package]] +name = "names" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc" +dependencies = [ + "rand", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.8.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "notify" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" +dependencies = [ + "bitflags 2.8.0", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "notify-types", + "walkdir", + "windows-sys 0.59.0", +] + +[[package]] +name = "notify-types" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "serde", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "crc32fast", + "flate2", + "hashbrown 0.14.5", + "indexmap 2.7.0", + "memchr", + "ruzstd", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +dependencies = [ + "bitflags 2.8.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "opentelemetry" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b69a91d4893e713e06f724597ad630f1fa76057a5e1026c0ca67054a9032a76" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror 1.0.69", +] + +[[package]] +name = "opentelemetry" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab70038c28ed37b97d8ed414b6429d343a8bbf44c9f79ec854f3a643029ba6d7" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror 1.0.69", + "tracing", +] + +[[package]] +name = "opentelemetry-http" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0ba633e55c5ea6f431875ba55e71664f2fa5d3a90bd34ec9302eecc41c865dd" +dependencies = [ + "async-trait", + "bytes", + "http 0.2.12", + "opentelemetry 0.23.0", +] + +[[package]] +name = "opentelemetry-jaeger" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501b471b67b746d9a07d4c29f8be00f952d1a2eca356922ede0098cbaddff19f" +dependencies = [ + "async-trait", + "futures-core", + "futures-util", + "http 0.2.12", + "isahc", + "opentelemetry 0.23.0", + "opentelemetry-http", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk 0.23.0", + "thrift", + "tokio", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cf61a1868dacc576bf2b2a1c3e9ab150af7272909e80085c3173384fe11f76" +dependencies = [ + "async-trait", + "futures-core", + "http 1.2.0", + "opentelemetry 0.27.1", + "opentelemetry-proto", + "opentelemetry_sdk 0.27.1", + "prost", + "thiserror 1.0.69", + "tokio", + "tonic", + "tracing", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e05acbfada5ec79023c85368af14abd0b307c015e9064d249b2a950ef459a6" +dependencies = [ + "opentelemetry 0.27.1", + "opentelemetry_sdk 0.27.1", + "prost", + "tonic", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1869fb4bb9b35c5ba8a1e40c9b128a7b4c010d07091e864a29da19e4fe2ca4d7" + +[[package]] +name = "opentelemetry_sdk" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae312d58eaa90a82d2e627fd86e075cf5230b3f11794e2ed74199ebbe572d4fd" +dependencies = [ + "async-trait", + "futures-channel", + "futures-executor", + "futures-util", + "lazy_static", + "once_cell", + "opentelemetry 0.23.0", + "ordered-float 4.6.0", + "percent-encoding", + "rand", + "thiserror 1.0.69", + "tokio", + "tokio-stream", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" +dependencies = [ + "async-trait", + "futures-channel", + "futures-executor", + "futures-util", + "glob", + "opentelemetry 0.27.1", + "percent-encoding", + "rand", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pav_regression" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d92b9b41adf4f984e4d6a86ceee68a8a729e539e28a75b65b445c300bcb9f3c" +dependencies = [ + "ordered-float 3.9.2", + "serde", + "thiserror 1.0.69", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" +dependencies = [ + "proc-macro2", + "syn 2.0.96", +] + +[[package]] +name = "prettytable-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" +dependencies = [ + "csv", + "encode_unicode", + "is-terminal", + "lazy_static", + "term", + "unicode-width 0.1.14", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "proc-macro2" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3" +dependencies = [ + "anyhow", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive 0.1.4", +] + +[[package]] +name = "ptr_meta" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90" +dependencies = [ + "ptr_meta_derive 0.3.0", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rancor" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf5f7161924b9d1cea0e4cabc97c372cea92b5f927fc13c6bca67157a0ad947" +dependencies = [ + "ptr_meta 0.3.0", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redb" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0a72cd7140de9fc3e318823b883abf819c20d478ec89ce880466dc2ef263c6" +dependencies = [ + "libc", +] + +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags 2.8.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom", + "libredox", + "thiserror 2.0.11", +] + +[[package]] +name = "regalloc2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" +dependencies = [ + "hashbrown 0.13.2", + "log", + "rustc-hash", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "region" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7" +dependencies = [ + "bitflags 1.3.2", + "libc", + "mach2", + "windows-sys 0.52.0", +] + +[[package]] +name = "rend" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a35e8a6bf28cd121053a66aa2e6a2e3eaffad4a60012179f0e864aa5ffeff215" +dependencies = [ + "bytecheck 0.8.0", +] + +[[package]] +name = "reqwest" +version = "0.12.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http 1.2.0", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.2.0", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower 0.5.2", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rkyv" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b11a153aec4a6ab60795f8ebe2923c597b16b05bb1504377451e705ef1a45323" +dependencies = [ + "bytecheck 0.8.0", + "bytes", + "hashbrown 0.15.2", + "indexmap 2.7.0", + "munge", + "ptr_meta 0.3.0", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beb382a4d9f53bd5c0be86b10d8179c3f8a14c30bf774ff77096ed6581e35981" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "rsa" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "serde", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +dependencies = [ + "bitflags 2.8.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.23.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + +[[package]] +name = "ruzstd" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" +dependencies = [ + "byteorder", + "derive_more", + "twox-hash", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "safe_arch" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.8.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "self_cell" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2fdfc24bc566f839a2da4c4295b82db7d25a24253867d5c64355abb5799bdbe" + +[[package]] +name = "semver" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "serde_json" +version = "1.0.135" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.7.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared-buffer" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" +dependencies = [ + "bytes", + "memmap2", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "simba" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + +[[package]] +name = "sluice" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" +dependencies = [ + "async-channel 1.9.0", + "futures-core", + "futures-io", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlx" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4410e73b3c0d8442c5f99b425d7a435b5ee0ae4167b3196771dd3f7a01be745f" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a007b6936676aa9ab40207cde35daab0a04b823be8ae004368c0793b96a61e0" +dependencies = [ + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener 5.4.0", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.2", + "hashlink", + "indexmap 2.7.0", + "log", + "memchr", + "once_cell", + "percent-encoding", + "rustls 0.23.21", + "rustls-pemfile 2.2.0", + "serde", + "serde_json", + "sha2", + "smallvec", + "thiserror 2.0.11", + "tokio", + "tokio-stream", + "tracing", + "url", + "webpki-roots", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3112e2ad78643fef903618d78cf0aec1cb3134b019730edb039b69eaf531f310" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.96", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9f90acc5ab146a99bf5061a7eb4976b573f560bc898ef3bf8435448dd5e7ad" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.96", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4560278f0e00ce64938540546f59f590d60beee33fffbd3b9cd47851e5fff233" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.8.0", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.11", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b98a57f363ed6764d5b3a12bfedf62f07aa16e1856a7ddc2a0bb190a959613" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.8.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.11", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f85ca71d3a5b24e64e1d08dd8fe36c6c95c339a896cc33068148906784620540" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "tracing", + "url", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "statrs" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e" +dependencies = [ + "approx", + "nalgebra", + "num-traits", + "rand", +] + +[[package]] +name = "stretto" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a313e115c2cd9a88d99d60386bc88641c853d468b2c3bc454c294f385fc084" +dependencies = [ + "async-channel 2.3.1", + "async-io", + "atomic", + "crossbeam-channel", + "futures", + "getrandom", + "parking_lot", + "rand", + "seahash", + "thiserror 1.0.69", + "tracing", + "wg", + "xxhash-rust", +] + +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.8.0", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tar" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "tempfile" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +dependencies = [ + "cfg-if", + "fastrand 2.3.0", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl 2.0.11", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "thrift" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e54bc85fc7faa8bc175c4bab5b92ba8d9a3ce893d0e9f42cc455c8ab16a9e09" +dependencies = [ + "byteorder", + "integer-encoding", + "log", + "ordered-float 2.10.1", + "threadpool", +] + +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +dependencies = [ + "rustls 0.23.21", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.24.0", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4bf6fecd69fcdede0ec680aaf474cdab988f9de6bc73d3758f0160e3b7025a" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.26.1", +] + +[[package]] +name = "tokio-util" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "indexmap 2.7.0", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap 2.7.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2", + "http 1.2.0", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "socket2", + "tokio", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" +dependencies = [ + "bitflags 2.8.0", + "bytes", + "futures-util", + "http 1.2.0", + "http-body", + "http-body-util", + "http-range-header", + "httpdate", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a971f6058498b5c0f1affa23e7ea202057a7301dbff68e968b2d578bcbd053" +dependencies = [ + "js-sys", + "once_cell", + "opentelemetry 0.27.1", + "opentelemetry_sdk 0.27.1", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "triomphe" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" +dependencies = [ + "serde", + "stable_deref_trait", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.2.0", + "httparse", + "log", + "rand", + "sha1", + "thiserror 1.0.69", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.2.0", + "httparse", + "log", + "rand", + "sha1", + "thiserror 2.0.11", + "utf-8", +] + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ulid" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f294bff79170ed1c5633812aff1e565c35d993a36e757f9bc0accf5eec4e6045" +dependencies = [ + "rand", + "serde", + "web-time", +] + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" +dependencies = [ + "asynchronous-codec", + "bytes", + "tokio-util", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +dependencies = [ + "base64 0.22.1", + "flate2", + "log", + "once_cell", + "rustls 0.23.21", + "rustls-pki-types", + "url", + "webpki-roots", +] + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "serde", + "serde_json", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.96", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.223.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e636076193fa68103e937ac951b5f2f587624097017d764b8984d9c0f149464" +dependencies = [ + "leb128", + "wasmparser 0.223.0", +] + +[[package]] +name = "wasmer" +version = "5.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "998dea47d6bb6a8fc7dd8a17b13bf8de277e007229f270c67105cb67fc2d9657" +dependencies = [ + "bindgen", + "bytes", + "cfg-if", + "cmake", + "indexmap 1.9.3", + "js-sys", + "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen 0.4.5", + "shared-buffer", + "tar", + "target-lexicon", + "thiserror 1.0.69", + "tracing", + "ureq", + "wasm-bindgen", + "wasmer-compiler", + "wasmer-compiler-cranelift", + "wasmer-derive", + "wasmer-types", + "wasmer-vm", + "wat", + "windows-sys 0.59.0", + "xz", + "zip", +] + +[[package]] +name = "wasmer-compiler" +version = "5.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "082f48ba006cce2358f6c63d8dba732c9d12ba5833008c9ff2944290eb72c3dc" +dependencies = [ + "backtrace", + "bytes", + "cfg-if", + "enum-iterator", + "enumset", + "lazy_static", + "leb128", + "libc", + "memmap2", + "more-asserts", + "object 0.32.2", + "region", + "rkyv", + "self_cell", + "shared-buffer", + "smallvec", + "target-lexicon", + "thiserror 1.0.69", + "wasmer-types", + "wasmer-vm", + "wasmparser 0.216.0", + "windows-sys 0.59.0", + "xxhash-rust", +] + +[[package]] +name = "wasmer-compiler-cranelift" +version = "5.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0272ad7daf59d43419cda9ae58b9cf8df6a115c8632fbb91c600892dff52f7a8" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "gimli 0.28.1", + "itertools 0.12.1", + "more-asserts", + "rayon", + "smallvec", + "target-lexicon", + "tracing", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-derive" +version = "5.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87b16fa0b2199083143705698ea9fc2ffd0328d7061f54e0e20ccd0ec2020466" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "wasmer-types" +version = "5.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b0b9b3242c1a6269e544401b1741a56502a5f79db8e1b318cacf1b34b2690d" +dependencies = [ + "bytecheck 0.6.12", + "enum-iterator", + "enumset", + "getrandom", + "hex", + "indexmap 2.7.0", + "more-asserts", + "rkyv", + "sha2", + "target-lexicon", + "thiserror 1.0.69", + "xxhash-rust", +] + +[[package]] +name = "wasmer-vm" +version = "5.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c7f8dbaceb0ab7901702e3c2bb43b09d2635aaa5ad39679c6560bcb9acde7c" +dependencies = [ + "backtrace", + "cc", + "cfg-if", + "corosensei", + "crossbeam-queue", + "dashmap", + "enum-iterator", + "fnv", + "indexmap 2.7.0", + "lazy_static", + "libc", + "mach2", + "memoffset", + "more-asserts", + "region", + "scopeguard", + "thiserror 1.0.69", + "wasmer-types", + "windows-sys 0.59.0", +] + +[[package]] +name = "wasmparser" +version = "0.216.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcdee6bea3619d311fb4b299721e89a986c3470f804b6d534340e412589028e3" +dependencies = [ + "ahash", + "bitflags 2.8.0", + "hashbrown 0.14.5", + "indexmap 2.7.0", + "semver", +] + +[[package]] +name = "wasmparser" +version = "0.223.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5a99faceb1a5a84dd6084ec4bfa4b2ab153b5793b43fd8f58b89232634afc35" +dependencies = [ + "bitflags 2.8.0", + "indexmap 2.7.0", + "semver", +] + +[[package]] +name = "wast" +version = "223.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59b2ba8a2ff9f06194b7be9524f92e45e70149f4dacc0d0c7ad92b59ac875e4" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width 0.2.0", + "wasm-encoder", +] + +[[package]] +name = "wat" +version = "1.223.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "662786915c427e4918ff01eabb3c4756d4d947cd8f635761526b4cc9da2eaaad" +dependencies = [ + "wast", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "wg" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aafc5e81e847f05d6770e074faf7b1cd4a5dec9a0e88eac5d55e20fdfebee9a" +dependencies = [ + "event-listener 5.4.0", + "futures-core", + "parking_lot", + "pin-project-lite", + "triomphe", +] + +[[package]] +name = "whoami" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" +dependencies = [ + "redox_syscall", + "wasite", +] + +[[package]] +name = "wide" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b5576b9a81633f3e8df296ce0063042a73507636cbe956c61133dd7034ab22" +dependencies = [ + "bytemuck", + "safe_arch", +] + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 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_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[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_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "xattr" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + +[[package]] +name = "xxhash-rust" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" + +[[package]] +name = "xz" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c887690ff2a2e233e8e49633461521f98ec57fbff9d59a884c9a4f04ec1da34" +dependencies = [ + "xz2", +] + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "zip" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9c1ea7b3a5e1f4b922ff856a129881167511563dc219869afe3787fc0c1a45" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", + "flate2", + "hmac", + "indexmap 2.7.0", + "lzma-rs", + "memchr", + "pbkdf2", + "rand", + "sha1", + "thiserror 2.0.11", + "time", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zopfli" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +dependencies = [ + "bumpalo", + "crc32fast", + "lockfree-object-pool", + "log", + "once_cell", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/docs/src/README.md b/docs/src/README.md index b5649bd9c..559c44d38 100644 --- a/docs/src/README.md +++ b/docs/src/README.md @@ -1,64 +1,64 @@ -**NOTE:** This document is a work in progress. You can [submit an issue](https://github.com/freenet/freenet-core/issues/new?labels=A-documentation) if you find a problem or have a suggestion. The source for this documentation is in our repository at [freenet-core/docs/src](https://github.com/freenet/freenet-core/tree/main/docs/src). We welcome pull requests. - -# Introduction - -## What is Freenet? - -Freenet is a global, [observable](https://en.wikipedia.org/wiki/Small-world_network), decentralized key-value store. Values are arbitrary blocks of data, called the contract's "state." Keys are cryptographic contracts that specify: - -- Whether a given state is permitted under this contract -- How the state can be modified over time -- How two valid states can be merged -- How to efficiently synchronize a contract's state between peers - -Freenet is a true decentralized peer-to-peer network, and is robust and scalable, through its use of a [small-world network](https://en.wikipedia.org/wiki/Small-world_network). - -Applications on Freenet can be built in any language that is supported by web browsers, including JavaScript and WebAssembly. These applications are distributed over Freenet and can create, retrieve, and update contracts through a WebSocket connection to the local Freenet peer. - -## Writing a Contract - -Freenet contracts can be written in any language that compiles to WebAssembly. -This includes [Rust](https://www.rust-lang.org/), and -[AssemblyScript](https://www.assemblyscript.org/), among many others. - -A contract consists of the WebAssembly code itself and its "parameters," which are additional data like cryptographic keys. This makes it easy to configure contracts without having to recompile them. - -A contract can be retrieved using a key, which is a cryptographic hash derived from the contract's WebAssembly code together with its parameters. - -## Small world routing - -Freenet peers self-organize into a [small-world network](https://en.wikipedia.org/wiki/Small-world_routing) to allow contracts to be found in a fast, scalable, and decentralized way. - -Every peer in Freenet is assigned a number between 0 and 1 when it first joins the network, this is the peer's "location". The small world network topology ensures that peers with similar locations are more likely to be connected. - -Contracts also have a location, which is derived from the contract's key. Peers cache contracts close to their locations. - -## Writing an Application - -Creating a decentralized application on Freenet is very similar to creating a normal web application. You can use familiar frameworks like React, Bootstrap, Angular, Vue.js, and so on. - -The main difference is that instead of connecting to a REST API running on a server, the web application connects to the Freenet peer running on the local computer through a [WebSocket](https://en.wikipedia.org/wiki/WebSocket) connection. - -Through this the application can: - -- Create new contracts and their associated state -- Retrieve contracts and their state -- Modify contract state when permitted by the contract - -## How to use Contracts - -Contracts are extremely flexible. they can be used to create decentralized data structures like hashmaps, inverted indices for keyword search, or efficient buffers for streaming audio and video. - -## Delegate Ecosystem - -Applications in Freenet don't need to be built from scratch, they can be built on top of components provided by us or others. - -### Reputation system - -Allows users to build up reputation over time based on feedback from those they interact with. Think of the feedback system in services like Uber, but with Freenet it will be entirely decentralized and cryptographically secure. It can be used for things like spam prevention (with IM and email), or fraud prevention (with an online store). - -This is conceptually similar to Freenet's [Web of Trust](http://www.draketo.de/english/freenet/friendly-communication-with-anonymity) plugin. - -### Arbiters - -Arbiters are trusted services that can perform tasks and authenticate the results, such as verifying that a contract had a particular state at a given time, or that external blockchains (Bitcoin, Ethereum, Solana etc) contain specific transactions. Trust is achieved through the reputation system. +**NOTE:** This document is a work in progress. You can [submit an issue](https://github.com/freenet/freenet-core/issues/new?labels=A-documentation) if you find a problem or have a suggestion. The source for this documentation is in our repository at [freenet-core/docs/src](https://github.com/freenet/freenet-core/tree/main/docs/src). We welcome pull requests. + +# Introduction + +## What is Freenet? + +Freenet is a global, [observable](https://en.wikipedia.org/wiki/Small-world_network), decentralized key-value store. Values are arbitrary blocks of data, called the contract's "state." Keys are cryptographic contracts that specify: + +- Whether a given state is permitted under this contract +- How the state can be modified over time +- How two valid states can be merged +- How to efficiently synchronize a contract's state between peers + +Freenet is a true decentralized peer-to-peer network, and is robust and scalable, through its use of a [small-world network](https://en.wikipedia.org/wiki/Small-world_network). + +Applications on Freenet can be built in any language that is supported by web browsers, including JavaScript and WebAssembly. These applications are distributed over Freenet and can create, retrieve, and update contracts through a WebSocket connection to the local Freenet peer. + +## Writing a Contract + +Freenet contracts can be written in any language that compiles to WebAssembly. +This includes [Rust](https://www.rust-lang.org/), and +[AssemblyScript](https://www.assemblyscript.org/), among many others. + +A contract consists of the WebAssembly code itself and its "parameters," which are additional data like cryptographic keys. This makes it easy to configure contracts without having to recompile them. + +A contract can be retrieved using a key, which is a cryptographic hash derived from the contract's WebAssembly code together with its parameters. + +## Small world routing + +Freenet peers self-organize into a [small-world network](https://en.wikipedia.org/wiki/Small-world_routing) to allow contracts to be found in a fast, scalable, and decentralized way. + +Every peer in Freenet is assigned a number between 0 and 1 when it first joins the network, this is the peer's "location". The small world network topology ensures that peers with similar locations are more likely to be connected. + +Contracts also have a location, which is derived from the contract's key. Peers cache contracts close to their locations. + +## Writing an Application + +Creating a decentralized application on Freenet is very similar to creating a normal web application. You can use familiar frameworks like React, Bootstrap, Angular, Vue.js, and so on. + +The main difference is that instead of connecting to a REST API running on a server, the web application connects to the Freenet peer running on the local computer through a [WebSocket](https://en.wikipedia.org/wiki/WebSocket) connection. + +Through this the application can: + +- Create new contracts and their associated state +- Retrieve contracts and their state +- Modify contract state when permitted by the contract + +## How to use Contracts + +Contracts are extremely flexible. they can be used to create decentralized data structures like hashmaps, inverted indices for keyword search, or efficient buffers for streaming audio and video. + +## Delegate Ecosystem + +Applications in Freenet don't need to be built from scratch, they can be built on top of components provided by us or others. + +### Reputation system + +Allows users to build up reputation over time based on feedback from those they interact with. Think of the feedback system in services like Uber, but with Freenet it will be entirely decentralized and cryptographically secure. It can be used for things like spam prevention (with IM and email), or fraud prevention (with an online store). + +This is conceptually similar to Freenet's [Web of Trust](http://www.draketo.de/english/freenet/friendly-communication-with-anonymity) plugin. + +### Arbiters + +Arbiters are trusted services that can perform tasks and authenticate the results, such as verifying that a contract had a particular state at a given time, or that external blockchains (Bitcoin, Ethereum, Solana etc) contain specific transactions. Trust is achieved through the reputation system. diff --git a/docs/src/architecture/transport.md b/docs/src/architecture/transport.md index c958fbdf9..e8c28c50c 100644 --- a/docs/src/architecture/transport.md +++ b/docs/src/architecture/transport.md @@ -152,7 +152,7 @@ pub enum HelloError { ### Dropped and Out-of-Order Messages -- **Duplicate Detection**: Messages are checked for duplicate `message_id`. Duplicates trigger +- **Duplicate Detection**: Messages are checked for duplicate `message_id`. Duplicates trigger an immediate `NoOperation` message with a reconfirmation in `confirm_receipt`. - **Acknowledgement Timeout**: Messages are resent if not acknowledged within 2 seconds (`MESSAGE_CONFIRMATION_TIMEOUT`). diff --git a/docs/src/components/delegates.md b/docs/src/components/delegates.md index 8aa4dadbe..7dc7b5359 100644 --- a/docs/src/components/delegates.md +++ b/docs/src/components/delegates.md @@ -1,9 +1,9 @@ # Delegates -In Freenet, Delegates are software components that can act on the user's behalf. -Think of them as a more sophisticated version of a web browser's local storage, -with similarities to Unix "Daemons". Operating within the Freenet core on your -device, Delegates are a secure and flexible mechanism for managing private data, +In Freenet, Delegates are software components that can act on the user's behalf. +Think of them as a more sophisticated version of a web browser's local storage, +with similarities to Unix "Daemons". Operating within the Freenet core on your +device, Delegates are a secure and flexible mechanism for managing private data, such as cryptographic keys, tokens, and passwords, and executing complex tasks. Delegates interact with various components within Freenet, including Contracts, diff --git a/docs/src/components/overview.md b/docs/src/components/overview.md index 7896adf0a..0b16eaf3c 100644 --- a/docs/src/components/overview.md +++ b/docs/src/components/overview.md @@ -14,11 +14,11 @@ the P2P network via contracts. The Freenet Core is the software that enables a user's computer to connect to the Freenet network. Its primary functions are: -* Providing a user-friendly interface to access Freenet via a web browser -* Host the user's [delegates](delegates.md) and the private data they store -* Host [contracts](contracts.md) and their associated data on behalf of the +- Providing a user-friendly interface to access Freenet via a web browser +- Host the user's [delegates](delegates.md) and the private data they store +- Host [contracts](contracts.md) and their associated data on behalf of the network -* Manage communication between contracts, delegates, and UI components +- Manage communication between contracts, delegates, and UI components Built with Rust, the core is designed to be compact (ideally under 5 MB), efficient, and capable of running on a variety of devices such as smartphones, diff --git a/docs/src/components/ui.md b/docs/src/components/ui.md index 2550d7628..31323ac90 100644 --- a/docs/src/components/ui.md +++ b/docs/src/components/ui.md @@ -1,7 +1,7 @@ ## User Interface On the normal web, a user might visit `https://gmail.com/`, their browser -will download the Gmail user interface which then runs in their browser and connects back to the Gmail servers. +will download the Gmail user interface which then runs in their browser and connects back to the Gmail servers. On Freenet the user interface is downloaded from a Freenet contract, and it [interacts](overview.md) with contracts and delegates by sending messages @@ -12,7 +12,7 @@ through the Freenet core. These UIs are built using web technologies such as HTML, CSS, and JavaScript, and are distributed over Freenet and run in a web browser. UIs can create, retrieve, and update contracts through a WebSocket connection to the local -Freenet peer, as well as communicate with delegates. +Freenet peer, as well as communicate with delegates. Because UIs run in a web browser, they can be built using any web framework, -such as React, Angular, Vue.js, Bootstrap, and so on. \ No newline at end of file +such as React, Angular, Vue.js, Bootstrap, and so on. diff --git a/docs/src/contract-interface.md b/docs/src/contract-interface.md index 6d6dae08e..d6e3db836 100644 --- a/docs/src/contract-interface.md +++ b/docs/src/contract-interface.md @@ -1,25 +1,25 @@ -# Contract Interface - -## Terms - -- [Contract State](glossary.md#contract-state) - data associated with a contract that can be retrieved by Applications and Delegates. -- [Delta](glossary.md#delta) - Represents a modification to some state - similar to a [diff](https://en.wikipedia.org/wiki/Diff) in source code -- [Parameters](glossary.md#parameters) - Data that forms part of a contract along with the WebAssembly code -- [State Summary](glossary.md#state-summary) - A compact summary of a contract's state that can be used to create a delta - -## Interface - -Freenet contracts must implement the [`ContractInterface`](https://docs.rs/freenet-stdlib/latest/freenet_stdlib/prelude/trait.ContractInterface.html) trait: - -```rust,no_run,noplayground -{{#include ../../stdlib/rust/src/contract_interface.rs:contractifce}} -``` - -[`Parameters`](https://docs.rs/freenet-stdlib/latest/freenet_stdlib/prelude/struct.Parameters.html), -[`State`](https://docs.rs/freenet-stdlib/latest/freenet_stdlib/prelude/struct.State.html), -and [`StateDelta`](https://docs.rs/freenet-stdlib/latest/freenet_stdlib/prelude/struct.StateDelta.html) -are all wrappers around simple `[u8]` byte arrays for maximum efficiency and flexibility. - -## Contract Interaction - -In the (hopefully) near future we'll be adding the ability for contracts to read each other's state while validating and updating their own, see [issue #167](https://github.com/freenet/freenet-core/issues/167) for the latest on this. +# Contract Interface + +## Terms + +- [Contract State](glossary.md#contract-state) - data associated with a contract that can be retrieved by Applications and Delegates. +- [Delta](glossary.md#delta) - Represents a modification to some state - similar to a [diff](https://en.wikipedia.org/wiki/Diff) in source code +- [Parameters](glossary.md#parameters) - Data that forms part of a contract along with the WebAssembly code +- [State Summary](glossary.md#state-summary) - A compact summary of a contract's state that can be used to create a delta + +## Interface + +Freenet contracts must implement the [`ContractInterface`](https://docs.rs/freenet-stdlib/latest/freenet_stdlib/prelude/trait.ContractInterface.html) trait: + +```rust,no_run,noplayground +{{#include ../../stdlib/rust/src/contract_interface.rs:contractifce}} +``` + +[`Parameters`](https://docs.rs/freenet-stdlib/latest/freenet_stdlib/prelude/struct.Parameters.html), +[`State`](https://docs.rs/freenet-stdlib/latest/freenet_stdlib/prelude/struct.State.html), +and [`StateDelta`](https://docs.rs/freenet-stdlib/latest/freenet_stdlib/prelude/struct.StateDelta.html) +are all wrappers around simple `[u8]` byte arrays for maximum efficiency and flexibility. + +## Contract Interaction + +In the (hopefully) near future we'll be adding the ability for contracts to read each other's state while validating and updating their own, see [issue #167](https://github.com/freenet/freenet-core/issues/167) for the latest on this. diff --git a/docs/src/example-app.md b/docs/src/example-app.md index 1a53dbfee..a164dd8c5 100644 --- a/docs/src/example-app.md +++ b/docs/src/example-app.md @@ -11,8 +11,8 @@ then you could test it by building and deploying any web application: ``` .\build-examples.sh ``` -. +. # Build freenet from source on Linux from command line: @@ -68,6 +68,7 @@ Update `npm`. Warning: required! You must do that to have the latest npm package ``` Install typescript and `webpack` to `build` `freenet-email-app` example. + ``` ~/n/bin/npm install -g typescript webpack ``` @@ -83,6 +84,7 @@ export CARGO_TARGET_DIR="$(pwd)/target" ``` build typescript stdlib. + ``` cd stdlib/typescript/ && npm run dev.package && cd ../.. ``` @@ -104,13 +106,12 @@ make build cd ../antiflood-tokens/ ``` - Fix a compile issue with: + ``` rm Cargo.lock ``` - ``` make build ``` diff --git a/docs/src/examples/blind-trust-tokens.md b/docs/src/examples/blind-trust-tokens.md index c83b5f78d..ec5e53a28 100644 --- a/docs/src/examples/blind-trust-tokens.md +++ b/docs/src/examples/blind-trust-tokens.md @@ -51,7 +51,7 @@ struct Attestation { pub authorization : Authorization, pub authorization_sig : Signature, - /// + /// fn is_valid(&self) -> Result { if (!signature.verify(&authorization.pubkey, &self.target)) { return Err("The target's signature is invalid"); diff --git a/docs/src/introduction.md b/docs/src/introduction.md index c4dafeebc..03ce212df 100644 --- a/docs/src/introduction.md +++ b/docs/src/introduction.md @@ -2,11 +2,11 @@ Freenet is a distributed, decentralized alternative to the centralized World Wide Web, designed to unleash a new era of innovation and competition, while -protecting freedom of speech and privacy. +protecting freedom of speech and privacy. -The heart of Freenet is the [Core](https://github.com/freenet/freenet-core), -which runs on users' computer, smartphone, or other devices. The Core is -tiny, less than 5 MB, allowing it to be installed in a matter of seconds and +The heart of Freenet is the [Core](https://github.com/freenet/freenet-core), +which runs on users' computer, smartphone, or other devices. The Core is +tiny, less than 5 MB, allowing it to be installed in a matter of seconds and is compatible with a wide range of hardware. ![Freenet in Context](freenet_in_context.svg) diff --git a/docs/src/tutorial.md b/docs/src/tutorial.md index 4fbddfde8..aac9878c1 100644 --- a/docs/src/tutorial.md +++ b/docs/src/tutorial.md @@ -1,103 +1,81 @@ -# Introduction +# Freenet Decentralized App Tutorial -This tutorial will show you how to build decentralized software on Freenet. For a practical -reference, please see the example application at [apps/freenet-email-app](https://github.com/freenet/freenet-core/tree/main/apps/freenet-email-app). +This tutorial walks you through creating and running a simple web app and a backend contract on Freenet. By the end, you’ll have: +- A **web application** (frontend) that runs in the browser and talks to your local Freenet node. +- A **container contract** that holds and distributes your web application over Freenet. +- A **backend contract** that stores data and provides any server-like logic. - +Use the accompanying example ([freenet-email-app](https://github.com/freenet/freenet-core/tree/main/apps/freenet-email-app)) for reference. -## Prerequisites +--- -### Rust and Cargo +## 1. Prerequisites -To install a Rust development environment, including Cargo, on Linux or macOS -(for Windows installation, refer to [this guide](https://rustup.rs)), use the -following command: +### 1.1 Rust & Cargo + +Install Rust and Cargo (Linux/macOS example): ```bash curl https://sh.rustup.rs -sSf | sh ``` -#### Note for MacOS install - -Note: The Homebrew installation of Rust may interfere with `fdev`. It is -recommended to use `rustup`, as shown above, to avoid these issues. - -### Installing Freenet Core and FDev from Git +> **Important for macOS:** Using Homebrew’s Rust can interfere with `fdev`. Use `rustup` above instead. -- Clone the Freenet Core repository and the stdlib submodule, and navigate to the application directory: +### 1.2 Freenet Core & FDev (Git Installation) -*Note:* Currently these should be installed from the git repo as the code is changing rapidly, once things -are more stable they can be installed from crates.io which will simplify this step. - - ```bash - git clone --recurse-submodules https://github.com/freenet/freenet-core.git - cd freenet-core/apps/freenet-ping - ``` +Freenet Core is under rapid development, so install from Git: -### Freenet Development Tool and Kernel +```bash +git clone --recurse-submodules https://github.com/freenet/freenet-core.git +cd freenet-core/apps/freenet-ping +``` -- Install the Freenet development tool (`fdev`) and the Freenet kernel for local development: +Then install the Freenet kernel (`freenet`) and dev tool (`fdev`): - ```bash - # You should be in freenet-core/apps/freenet-ping - cargo install --path ../../crates/core - cargo install --path ../../crates/fdev - ``` +```bash +cargo install --path ../../crates/core +cargo install --path ../../crates/fdev +``` -### Add WebAssembly target +### 1.3 WebAssembly Target -To allow Rust to compile to WebAssembly, you need to add the WebAssembly target using `rustup`: +Enable the WebAssembly target for Rust: ```bash rustup target add wasm32-unknown-unknown ``` -### Node.js and TypeScript +### 1.4 Node.js & TypeScript -To build user interfaces in JavaScript or TypeScript, you need to have Node.js -and npm installed. For example on Ubuntu Linux: +If you plan to build web UIs using TypeScript: -```bash -sudo apt update -sudo apt install nodejs npm -``` - -For Mac or Windows, you can download Node.js and npm from [here](https://nodejs.org/en/download/). +- **Ubuntu**: + ```bash + sudo apt update + sudo apt install nodejs npm + ``` +- **macOS/Windows**: Install from [Node.js downloads](https://nodejs.org/en/download/). -Once Node.js and npm are installed, you can install TypeScript globally on your -system, which includes the `tsc` command: +Then install TypeScript globally: ```bash sudo npm install -g typescript ``` -You can verify the installation by checking the version of `tsc`: +Check: ```bash tsc --version ``` -This command should output the version of TypeScript that you installed. - -## Creating a new contract +--- -You can create a new [contract](glossary.md#contract) skeleton by executing the -`new` command with `fdev`. Fdev supports two types of contracts: -regular [contracts](glossary.md#contract), and [web application](glossary.md#web-application) [container -contracts](glossary.md#container-contract). Fdev supports several languages: +## 2. Create Your Project Structure -- Regular contracts: - - Rust (_default_) -- Web applications: - - Container development: - - Rust (_default_) - - Web/state development: - - TypeScript. (_default: using npm and webpack_) - - JavaScript. - - Rust (**WIP**). +We’ll create two main pieces: a **web app** (which is essentially our frontend) and a **backend contract**. -We create a directory to hold our web app, and initialize it using `fdev`: +### 2.1 Create a Web App (Container + Frontend) ```bash mkdir -p my-app/web @@ -106,95 +84,35 @@ cd my-app/web fdev new web-app ``` -This will create the skeleton for a web application and its container contract for -Freenet ready for development at the `my-app/web` directory. - -## Making a container contract - -The first thing that we need is to write the code for our container contract. -This contract's role is to contain the web application code itself, allowing it -to be distributed over Freenet. - -The `new` command has created the source ready to be modified for us, in your -favorite editor open the following file: - -```bash -./container/src/lib.rs -``` +This makes a skeleton for: -In this case, and for simplicity's sake, the contract won't be performing any -functions, but in a realistic scenario, this contract would include some basic -security functionality like verifying that whoever is trying to update the -contract has the required credentials. +1. A **container contract** in `./container/` (stores and distributes your web files). +2. A TypeScript-based web app in `./src/`. -To make our contract unique so it doesn't collide with an existing contract, we -can generate a random signature that will be embedded with the contract. +### 2.2 Container Contract Overview - +Open `my-app/web/container/src/lib.rs`. You’ll see something like: -For example in the `lib.rs` file we will write the following: - -```rust,no_run,noplayground -{{#include ../../stdlib/examples/contract.rs:contractifce}} -``` - -That's a lot of information, let's unpack it: - -```rust,noplayground +```rust use freenet_stdlib::prelude::*; -``` - -Here we are importing the necessary types and traits to write a Freenet contract -successfully using Rust. -```rust,noplayground -pub const RANDOM_SIGNATURE: &[u8] = &[6, 8, 2, 5, 6, 9, 9, 10]; -``` - -This will make our contract unique, notice the `pub` qualifier so the compiler -doesn't remove this constant because is unused and is included in the output of -the compiler. - -```rust,noplayground struct Contract; #[contract] impl ContractInterface for Contract { - ... + // ... } ``` - +- `#[contract]` links your code to the Freenet WASM runtime. -Here we create a new type, `Contract` for which we will be implementing the -`ContractInterface` trait. To know more details about the functionality of a -contract, delve into the details of the [contract -interface](contract-interface.md). +**Tip**: Real container contracts typically add checks (e.g., who can update the contract). -Notice the `#[contract]` macro call, this will generate the necessary code for -the WASM runtime to interact with your contract ergonomically and safely. Trying -to use this macro more than once in the same module will result in a compiler -error, and only the code generated at the top-level module will be used by the -runtime. +--- -As a rule of thumb, one contract will require implementing the -`ContractInterface`` exactly once. +## 3. Frontend (Web Application) Basics -### Creating a web application - -Now we have a working example of a contract, but our contract is an empty shell, -which does not do anything yet. To change this, we will start developing our web -application. - -To do that, we can go and modify the code of the contract state, which in this -case is the web application. Freenet offers a standard library (stdlib) that can -be used with Typescript/JavaScript to facilitate the development of web -applications and interfacing with your local node, so we will make our -`package.json` contains the dependency: +Your web files live under `my-app/web/src/`. A typical TypeScript setup might use `npm install` to pull in `@freenetorg/freenet-stdlib`. For example in `package.json`: ```json { @@ -204,330 +122,206 @@ applications and interfacing with your local node, so we will make our } ``` -Open the file `src/index.ts` in a code editor and you can start developing the -web application. - -An important thing to notice is that our application will need to interface with -our local node, the entry point for our machine to communicate with other nodes -in the network. The stdlib offers a series of facilities in which you will be -able to communicate with the network ergonomically. +Then in `src/index.ts`, you can import `@freenetorg/freenet-stdlib` and talk to the node: -Here is an example of how you could write your application to interact with the -node: - -```typescript +```ts import { + FreenetWsApi, GetResponse, HostError, Key, - FreenetWsApi, PutResponse, - UpdateNotification, UpdateResponse, - DelegateResponse, + // ... } from "@freenetorg/freenet-stdlib/websocket-interface"; const handler = { - onContractPut: (_response: PutResponse) => {}, - onContractGet: (_response: GetResponse) => {}, - onContractUpdate: (_up: UpdateResponse) => {}, - onContractUpdateNotification: (_notif: UpdateNotification) => {}, - onDelegateResponse: (_response: DelegateResponse) => {}, - onErr: (err: HostError) => {}, - onOpen: () => {}, -}; - -const API_URL = new URL(`ws://${location.host}/contract/command/`); -const freenetApi = new FreenetWsApi(API_URL, handler); - -const CONTRACT = "DCBi7HNZC3QUZRiZLFZDiEduv5KHgZfgBk8WwTiheGq1"; - -async function loadState() { - let getRequest = { - key: Key.fromSpec(CONTRACT), - fetch_contract: false, - }; - await freenetApi.get(getRequest); -} -``` - -Let's unpack this code: - -```typescript -const handler = { - onPut: (_response: PutResponse) => {}, - onGet: (_response: GetResponse) => {}, - onUpdate: (_up: UpdateResponse) => {}, - onUpdateNotification: (_notif: UpdateNotification) => {}, - onErr: (err: HostError) => {}, - onOpen: () => {}, + onContractPut: (_: PutResponse) => {}, + onContractGet: (_: GetResponse) => {}, + onContractUpdate: (_: UpdateResponse) => {}, + // ... + onErr: (err: HostError) => console.error(err), + onOpen: () => console.log("WebSocket open!"), }; const API_URL = new URL(`ws://${location.host}/contract/command/`); const freenetApi = new FreenetWsApi(API_URL, handler); -``` -This type provides a convenient interface to the WebSocket API. It receives an -object which handles the different responses from the node via callbacks. Here -you would be able to interact with DOM objects or other parts of your code. - -```typescript -const CONTRACT = "DCBi7HNZC3QUZRiZLFZDiEduv5KHgZfgBk8WwTiheGq1"; +// Example contract key +const CONTRACT_KEY = "DCBi7HNZC3QUZRiZLFZDiEduv5KHgZfgBk8WwTiheGq1"; async function loadState() { - let getRequest = { - key: Key.fromSpec(CONTRACT), + await freenetApi.get({ + key: Key.fromSpec(CONTRACT_KEY), fetch_contract: false, - }; - await freenetApi.get(getRequest); + }); } ``` -Here we use the API wrapper to make a get request (which requires a key and -specifies if we require fetching the contract code or not) to get the state for -a contract with the given address. The response from the node will be directed -to the `onGet` callback. You can use any other methods available in the API to -interact with the node. - - +--- -## Writing the backend for our web application +## 4. Backend Contract -In the [creating a new contract](dev-guide.md#creating-a-new-contract) section -we described the contract interface, but we were using it to write a simple -container contract that won't be doing anything in practice, just carrying -around the front end of your application. The core logic of the application, and -a back end where we will be storing all the information, requires another -contract. So we will create a new contract in a different directory for it: +Switch to your backend folder and scaffold a regular contract: ```bash cd ../backend fdev new contract ``` -This will create a regular contract, and we will need to implement the interface -on a type that will handle our contract code. For example: +Edit `./src/lib.rs`. Here’s a skeleton that stores a list of posts: -```rust,noplayground +```rust use freenet_stdlib::prelude::*; -pub const RANDOM_SIGNATURE: &[u8] = &[6, 8, 2, 5, 6, 9, 9, 10]; - struct Contract; -struct Posts(...) +struct Posts(Vec); -impl Posts { - fn add_post(&mut self, post: Post) { ... } +#[derive(Serialize, Deserialize)] +struct Post { + // ... } -struct Post(...) - #[contract] impl ContractInterface for Contract { fn update_state( - _parameters: Parameters<'static>, - state: State<'static>, - data: Vec>, + _params: Parameters<'static>, + current_state: State<'static>, + mut data: Vec>, ) -> Result, ContractError> { - let mut posts: Posts = serde_json::from_slice(&state).map_err(|_| ContractError::InvalidState)?; + // Convert the current state from JSON + let mut posts: Posts = serde_json::from_slice(¤t_state) + .map_err(|_| ContractError::InvalidState)?; + if let Some(UpdateData::Delta(delta)) = data.pop() { - let new_post: Posts = serde_json::from_slice(&delta).map_err(|_| ContractError::InvalidState); - posts.add_post(new_post)?; + // Parse the incoming update as a Post + let new_post: Post = serde_json::from_slice(&delta) + .map_err(|_| ContractError::InvalidUpdate)?; + + // Append to our existing posts + posts.0.push(new_post); } else { - Err(ContractError::InvalidUpdate) + return Err(ContractError::InvalidUpdate); } - Ok(UpdateModification::valid(posts.into())) + + // Serialize back to JSON for the updated state + Ok(UpdateModification::valid(serde_json::to_vec(&posts) + .unwrap() + .into())) } - ... + // ... } ``` -In this simple example, we convert a new incoming delta to a post and the state -to a list of posts we maintain, and we append the post to the list of posts. -After that, we convert back the posts list to an state and return that. - -If we subscribe to the contract changes or our web app, we will receive a -notification with the updates after they are successful, and we will be able to -render them in our browser. We can do that, for example, using the API: - -```typescript -function getUpdateNotification(notification: UpdateNotification) { - let decoder = new TextDecoder("utf8"); - let updatesBox = DOCUMENT.getElementById("updates") as HTMLPreElement; - let delta = notification.update?.updateData as DeltaUpdate; - let newUpdate = decoder.decode(Uint8Array.from(delta.delta)); - let newUpdateJson = JSON.parse(newUpdate.replace("\x00", "")); - updatesBox.textContent = updatesBox.textContent + newUpdateJson; -} -``` +Any time the contract receives an update, it takes the JSON-encoded “post” and appends it to the stored list. The front end can subscribe to these updates and reflect them in the UI. -### Building and packaging a contract +--- -Now that we have the front end and the back end of our web app, we can package -the contracts and run them in the node to test them out. +## 5. Building & Packaging -In order to do that, we can again use the development tool to help us out with -the process. But before doing that, let's take a look at the manifesto format -and understand the different parameters that allow us to specify how this -contract should be compiled (check the [manifest](./manifest.md) details for -more information). In the web app directory, we have a `freenet.toml` file which -contains something similar to: +### 5.1 Manifest Configuration + +Each contract folder has a `freenet.toml` specifying how to build/package. In the **web container** (`my-app/web`), you might see: ```toml [contract] type = "webapp" lang = "rust" -... - [webapp.state-sources] -source_dirs = ["dist"] +source_dirs = ["dist"] # The compiled web files get packaged from this folder ``` -This means that the `dist` directory will be packaged as the initial state for -the webapp (that is the code the browser will be interpreting and in the end, -rendering). - -If we add the following keys to the manifesto: +You can embed your backend contract into the container by adding something like: ```toml [webapp.dependencies] posts = { path = "../backend" } ``` -The WASM code from the `backend` contract will be embedded in our web -application state, so it will be accessible as a resource just via the local -HTTP gateway access and then we can re-use it for publishing additional -contracts. - - - -Currently, wep applications follow a standarized build procedure in case you use -`fdev` and assumptions about your system. For example, in the case of a `type = -"webapp"` contract, if nothing is specified, it will assume you have `npm` and -the `tsc` compiler available at the directory level, as well as `webpack` -installed. - -This means that you have installed either globally or at the directory level, -e.g. globally: - -```bash -npm install -g typescript webpack webpack-cli -``` +### 5.2 Compile -or locally (make sure your `package.json` file has the required dependencies): +From inside `my-app/web`: ```bash -npm install --save-dev typescript webpack webpack-cli +fdev build ``` -If, however, you prefer to follow a different workflow, you can write your own -by enabling/disabling certain parameters or using a blank template. For example: +This runs any necessary steps (like `npm install`, `webpack`, TypeScript compilation) before creating a `.wasm` file and `contract-state` in `build/freenet`. -```toml -[contract] -lang = "rust" +Then do the same in `my-app/backend`: -[state] -files = ["my_packaged_web.tar.xz"] +```bash +fdev build ``` -Would just delegate the work of building the packaged `tar` to the developer. -Or: +You should again see a `.wasm` file and optionally a `contract-state`. -```toml -[contract] -type = "webapp" -lang = "rust" - -[webapp] -lang = "typescript" +--- -[webapp.typescript] -webpack = false -``` +## 6. Test Locally -would disable using `webpack` at all. +### 6.1 Start the Local Freenet Node -Now that we understand the details, and after making any necessary changes, in -each contract directory we run the following commands: +In one terminal: ```bash -fdev build +freenet ``` -This command will read your contract manifest file (`freenet.toml`) and take -care of building the contract and packaging it, ready for the node and the -network to consume it. - - +You’ll see logs indicating the node is running (HTTP gateway on `127.0.0.1:50509` by default). -Under the `./build/freenet` directory, you will see both a `*.wasm` file, which -is the contract file, and `contract-state`, in case it applies, which is the -initial state that will be uploaded when initially putting the contract. +### 6.2 Publish Contracts -Web applications can access the code of backend contracts directly in their -applications and put new contracts (that is, assigning a new location for the -code, plus any parameters that may be generated dynamically by the web app, and -the initial state for that combination of contract code + parameters) -dynamically. +In another terminal, publish both contracts: -Let's take a look at the manifest for our web app container contract: +**Backend**: -## Testing out contracts in the local node +```bash +cd my-app/backend +fdev publish --code="./build/freenet/backend.wasm" --state="./build/freenet/contract-state" +``` -Once we have all our contracts sorted and ready for testing, we can do this in -local mode in our node. For this the node must be running, we can make sure that -is running by running the following command as a background process or in -another terminal; since we have installed it: +**Web Container**: ```bash -freenet +cd ../web +fdev publish --code="./build/freenet/web.wasm" --state="./build/freenet/contract-state" ``` -You should see some logs printed via the stdout of the process indicating that -the node HTTP gateway is running. +### 6.3 View in Browser -Once the HTTP gateway is running, we are ready to publish the contracts to our -local Freenet node: +You’ll get a contract key when you publish (e.g., `CYXGxQGSmcd5xHRJNQygPwmUJsWS2njh3pdVjfVz9EV`). +Open it in your browser: -```bash -cd ../backend && fdev publish --code="./build/freenet/backend.wasm" --state="./build/freenet/contract-state" -cd ../web && fdev publish --code="./build/freenet/web.wasm" --state="./build/freenet/contract-state" ``` +http://127.0.0.1:50509/contract/web/ +``` + +If everything went well, you’ll see your web application loaded from the node. + +--- + +## 7. Updating Your App -In this case, we're not passing any parameters (so our parameters will be an -empty byte array), and we are passing an initial state without the current -backend contract. In typical use, both the parameters would have meaningful -data, and the backend contract may be dynamically generated from the app and -published from there. +Since the app’s code is stored as the contract’s **state**, you can update it at any time by: -Once this is done, you can start your app just by pointing to it in the browser: -`http://127.0.0.1:50509/contract/web/` +1. Changing your TypeScript/Rust source. +2. Rebuilding. +3. Publishing a new version with a new state or new parameters. -For example -`http://127.0.0.1:50509/contract/web/CYXGxQGSmcd5xHRJNQygPwmUJsWS2njh3pdVjfVz9EV/` +The Freenet node treats these as regular contract updates. -Iteratively you can repeat this process of modifying, and publishing locally -until you are confident with the results and ready to publish your application. +--- -Since the web is part of your state, you are always able to update it, pointing -to new contracts, and evolving it over time. +## 8. Current Limitations -## Limitations +- **No Real Network**: Publishing to the production Freenet network is still under development. +- **Language Support**: Currently only Rust for contracts; additional languages (e.g., AssemblyScript) planned. +- **Manual Install**: Binaries for `fdev` and `freenet` require manual build from source. -- Publishing to the Freenet network is not yet supported. -- Only Rust is currently supported for contract development, but we'll support - more languages like [AssemblyScript](https://www.assemblyscript.org/) in the - future. +--- -- Binaries for all the required tools are not yet available, they must be - compiled from source +**That’s it!** You’ve built a basic decentralized web app on Freenet using a container contract (for the UI) and a backend contract (for the data/logic). For a more complete example, check the [freenet-email-app](https://github.com/freenet/freenet-core/tree/main/apps/freenet-email-app). From b72724037e8b2698b532a2976b096d8b0911b389 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Fri, 24 Jan 2025 08:37:02 -0600 Subject: [PATCH 002/121] rewrite README --- crates/fdev/README.md | 728 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 715 insertions(+), 13 deletions(-) diff --git a/crates/fdev/README.md b/crates/fdev/README.md index 65ef8b988..d123e8bb2 100644 --- a/crates/fdev/README.md +++ b/crates/fdev/README.md @@ -1,27 +1,729 @@ +Below is a comprehensive README for `fdev` that combines the existing reference documentation and the original README content. You can drop it in place of your current `README.md`. + +--- + +# fdev + +The Freenet Development Tool (`fdev`) is a command-line utility to create, build, publish, inspect, and test Freenet contracts or delegates. It also supports local node simulations, a TUI-based WASM runtime, and optional network metrics gathering. + +## Table of Contents + +1. [Overview](#overview) +2. [Installation](#installation) +3. [Local Node Example](#local-node-example) +4. [Creating a New Package](#creating-a-new-package) +5. [Building a Contract or Delegate](#building-a-contract-or-delegate) +6. [Publishing a Contract or Delegate](#publishing-a-contract-or-delegate) +7. [Updating a Contract](#updating-a-contract) +8. [Contract State Builder Example](#contract-state-builder-example) +9. [Inspecting a Compiled WASM](#inspecting-a-compiled-wasm) +10. [Using the Local WASM Runtime (TUI)](#using-the-local-wasm-runtime-tui) +11. [Querying Connected Peers](#querying-connected-peers) +12. [Testing (Single-Process or Multi-Process)](#testing-single-process-or-multi-process) +13. [Network Metrics Server](#network-metrics-server) +14. [Directory & Module Structure](#directory--module-structure) +15. [Common Workflows](#common-workflows) + +--- + +## Overview + +`fdev` helps Freenet developers: + +- **Create** new contract or web-app packages. +- **Build** Rust-based WASM contracts/delegates. +- **Publish** new contracts or delegates. +- **Update** existing contracts’ state. +- **Inspect** compiled artifacts (hash, version, etc.). +- **Run** local TUI-based or multi-process network simulations. +- **Query** your node for connected peers. +- **Optionally** run a metrics server for simulation insights. + +--- + +## Installation + +Usually you'll build `fdev` as part of the Freenet project: + +1. Clone or be inside the Freenet repository. +2. Navigate to `freenet-core/main/crates/fdev`. +3. Build in release mode: + ```bash + cargo build --release + ``` +4. You can then run it directly: + ```bash + ./target/release/fdev --help + ``` + Or place `target/release/fdev` on your PATH. + +--- + +## Local Node Example + +If you want to try out a contract in local mode, you typically run a separate “local node” process that listens for contract commands. There is a `local-node` executable (or an equivalent) in the Freenet repository. You can do something like: + +```bash +# Example: run the local node (CLI options may vary) +local-node local-node-cli --help +``` + +Once the local node is up, you can run `fdev` or a script to send commands to it. +Below is a *legacy* style example (paths/names may differ in current code): + +```bash +# Example: older usage for local node exploration +./fdev run-local \ + --input-file /tmp/input \ + --terminal-output \ + --deser-format json \ + "/home/.../freenet/crates/http-gw/examples/test_web_contract.wasm" +``` + +In newer code, you will likely use `fdev wasm-runtime`, described in a [later section](#using-the-local-wasm-runtime-tui), to do an equivalent local testing workflow. + +--- + +## Creating a New Package + +`fdev new` scaffolds a new Freenet package. Two options: + +- **`contract`**: A standard WASM contract. +- **`webapp`**: A contract container that also bundles a front-end (TypeScript/webpack by default). + +Example: +```bash +fdev new contract +``` +Generates Rust cargo boilerplate (and for web apps, TypeScript/webpack scaffolding too). + +--- + +## Building a Contract or Delegate + +Use `fdev build` to compile a Rust-based WASM contract or delegate. For example: + +```bash +fdev build \ + --package-type [contract|delegate] \ + [--features some_features] \ + [--debug] \ + [--version 0.0.2] +``` + +- **`--package-type`** defaults to `contract`. +- **`--features`** can specify crate features, e.g. `freenet-main-contract` or `freenet-main-delegate`. +- **`--debug`** produces an unoptimized WASM (useful for local tests). +- **`--version`** sets the embedded Freenet ABI version (defaults to `0.0.1`). + +`fdev` looks for a `freenet.toml` in your current directory that defines if your contract is standard or a webapp, and (for webapps) how to compile front-end code. + +**After building**, the output artifact is typically placed in `build/freenet/` unless overridden by your config file. + +--- + +## Publishing a Contract or Delegate + +`fdev publish` uploads a **new** contract or delegate to a node (either local or network mode). + +**Example: Publishing a contract**: +```bash +fdev publish \ + --code path/to/my_contract.wasm \ + --parameters path/to/params.json \ + contract \ + --state path/to/initial_state.json +``` +- **`--code`**: path to your built WASM. +- **`--parameters`**: optional contract parameters. +- **`--state`**: optional initial state JSON or binary. + +**Example: Publishing a delegate**: +```bash +fdev publish \ + --code path/to/my_delegate.wasm \ + --parameters delegate_params.json \ + delegate \ + [--nonce ... --cipher ...] +``` +- If you skip `--nonce` and `--cipher`, a default local-only encryption is used (fine for tests, not recommended for production). + +By default, `fdev publish` pushes in **local** mode unless you specify `--mode network` or set `MODE=network`. + +--- + +## Updating a Contract + +To push a state delta to an existing contract (identified by its Base58 key): + +```bash +fdev execute update \ + --delta path/to/delta.json \ + [--address 127.0.0.1 \ + --port 50509 \ + --release] +``` + +- **`--delta`**: The state delta file (JSON or binary). +- **`--release`** indicates you want to push to the network, instead of local-only. + +--- + +## Contract State Builder Example + +Sometimes you only want to build the “state artifact” for a contract or a web front-end. `fdev build` can do this if your `freenet.toml` includes a `state-sources` or webapp config. +Older Freenet docs mention `build_state` as a separate script, but in practice you can do: + +```bash +# Build a web-based front end +fdev build \ + --input-metadata-path /optional/metadata \ + --input-state-path contracts/freenet-microblogging/view/web \ + --output-file contracts/freenet-microblogging-web/freenet_microblogging_view \ + --package-type contract # or 'webapp' if your config demands +``` + +Similarly, you can specify `--state` for a model-only contract: +```bash +fdev build \ + --input-state-path contracts/freenet-microblogging/model/ \ + --output-file contracts/freenet-microblogging-data/freenet_microblogging_model +``` + +*(Adjust paths, actual flags, and config to match your usage.)* + +--- + +## Inspecting a Compiled WASM + +`fdev inspect` prints metadata about a built WASM artifact, such as its hash, version, or a derived contract key. + +Examples: + +```bash +# Show code hash + contract API version +fdev inspect code path/to/contract.wasm + +# Display the contract key (hash+empty params => key) +fdev inspect key path/to/contract.wasm + +# For a delegate +fdev inspect delegate path/to/delegate.wasm +``` + +--- + +## Using the Local WASM Runtime (TUI) + +`fdev wasm-runtime` provides a local, interactive environment to test your contract. For instance: + +```bash +fdev wasm-runtime \ + --input-file /tmp/input.json \ + --deserialization-format json \ + --terminal-output +``` +- The tool will connect to a local Freenet node by default (see `--mode`, `--address`, `--port` if needed). +- Commands you type—like `put`, `get`, `update`, or `exit`—are forwarded to the local node. +- Additional command data is read from the file specified by `--input-file`. + +Common subcommands once inside the TUI: +``` +help # print instructions +put # publish a fresh contract state +get # retrieve the current contract state +update # apply a delta to the contract state +exit # quit TUI +``` + +--- + +## Querying Connected Peers + +You can list a node’s open connections: + +```bash +fdev query +``` + +It prints a table of peer identifiers and socket addresses for debugging or analysis. + +--- + +## Testing (Single-Process or Multi-Process) + +`fdev test` orchestrates an entire simulated network of Freenet nodes for end-to-end testing. + +### Single Process + +Spins up multiple in-memory nodes under one process: + +```bash +fdev test \ + --gateways 2 \ + --nodes 10 \ + --events 100 \ + single-process +``` +- **--gateways**: number of gateway nodes +- **--nodes**: number of normal nodes +- **--events**: random events (contract puts, updates, etc.) + +### Multi-Process + +```bash +fdev test \ + --gateways 2 \ + --nodes 10 \ + network +``` +- One node acts as a **supervisor** (you run `fdev test ... network --mode supervisor`). +- Others run as **peers** (`--mode peer`) connecting to the supervisor. This can scale across multiple machines or containers. + +*(See internal documentation or run `fdev test --help` for more detail.)* + +--- + +## Network Metrics Server + +```bash +fdev network-metrics-server [--log-directory path] +``` +- Launches an HTTP server (default port `55010`) for collecting or pushing network stats and event logs. +- You can then visualize or store the data for debugging or simulation metrics analysis. + +--- + +## Directory & Module Structure + +Here’s a quick look at the major modules in the `fdev` crate: + +``` +fdev +├── src +│ ├── main.rs # CLI entrypoint, top-level subcommands +│ ├── config.rs # Config structs, subcommand definitions +│ ├── commands/ # 'put', 'update', connect to node, etc. +│ ├── build.rs # Builds Rust WASM, web assets, etc. +│ ├── wasm_runtime/ # Local TUI runtime for testing contracts +│ ├── testing/ # Tools for single vs multi-process simulations +│ ├── network_metrics_server # Optional server for collecting network stats +│ └── util.rs # Shared utility helpers +└── Cargo.toml +``` + +--- + +## Common Workflows + +Below are a few typical steps you might perform: + +1. **Create a new contract** (or webapp): + ```bash + fdev new contract + ``` +2. **Build**: + ```bash + fdev build + ``` +3. **Publish** (locally by default): + ```bash + fdev publish \ + --code build/freenet/my_contract.wasm \ + contract \ + --state initial_state.json + ``` +4. **Update** the contract: + ```bash + fdev execute update \ + --delta path/to/delta.json + ``` +5. **Inspect** a compiled WASM: + ```bash + fdev inspect code build/freenet/my_contract.wasm + ``` +6. **Run local TUI** (optionally): + ```bash + fdev wasm-runtime \ + --input-file my_input.json \ + --terminal-output \ + --deserialization-format json + ``` +7. **Check open peers**: + ```bash + fdev query + ``` +8. **Simulate** a small test network: + ```bash + fdev test --nodes 5 --gateways 1 single-process + ``` +9. **(Optional) Start metrics server**: + ```bash + fdev network-metrics-server --log-directory /path/to/logs + ``` + +Feel free to run `fdev --help` for more details on any step. Enjoy building with Freenet!Below is a comprehensive README for `fdev` that combines the existing reference documentation and the original README content. You can drop it in place of your current `README.md`. + +--- + # fdev -A crate for local development purposes. +The Freenet Development Tool (`fdev`) is a command-line utility to create, build, publish, inspect, and test Freenet contracts or delegates. It also supports local node simulations, a TUI-based WASM runtime, and optional network metrics gathering. + +## Table of Contents + +1. [Overview](#overview) +2. [Installation](#installation) +3. [Local Node Example](#local-node-example) +4. [Creating a New Package](#creating-a-new-package) +5. [Building a Contract or Delegate](#building-a-contract-or-delegate) +6. [Publishing a Contract or Delegate](#publishing-a-contract-or-delegate) +7. [Updating a Contract](#updating-a-contract) +8. [Contract State Builder Example](#contract-state-builder-example) +9. [Inspecting a Compiled WASM](#inspecting-a-compiled-wasm) +10. [Using the Local WASM Runtime (TUI)](#using-the-local-wasm-runtime-tui) +11. [Querying Connected Peers](#querying-connected-peers) +12. [Testing (Single-Process or Multi-Process)](#testing-single-process-or-multi-process) +13. [Network Metrics Server](#network-metrics-server) +14. [Directory & Module Structure](#directory--module-structure) +15. [Common Workflows](#common-workflows) + +--- + +## Overview + +`fdev` helps Freenet developers: + +- **Create** new contract or web-app packages. +- **Build** Rust-based WASM contracts/delegates. +- **Publish** new contracts or delegates. +- **Update** existing contracts’ state. +- **Inspect** compiled artifacts (hash, version, etc.). +- **Run** local TUI-based or multi-process network simulations. +- **Query** your node for connected peers. +- **Optionally** run a metrics server for simulation insights. + +--- + +## Installation + +Usually you'll build `fdev` as part of the Freenet project: + +1. Clone or be inside the Freenet repository. +2. Navigate to `freenet-core/main/crates/fdev`. +3. Build in release mode: + ```bash + cargo build --release + ``` +4. You can then run it directly: + ```bash + ./target/release/fdev --help + ``` + Or place `target/release/fdev` on your PATH. + +--- + +## Local Node Example + +If you want to try out a contract in local mode, you typically run a separate “local node” process that listens for contract commands. There is a `local-node` executable (or an equivalent) in the Freenet repository. You can do something like: + +```bash +# Example: run the local node (CLI options may vary) +local-node local-node-cli --help +``` + +Once the local node is up, you can run `fdev` or a script to send commands to it. +Below is a *legacy* style example (paths/names may differ in current code): + +```bash +# Example: older usage for local node exploration +./fdev run-local \ + --input-file /tmp/input \ + --terminal-output \ + --deser-format json \ + "/home/.../freenet/crates/http-gw/examples/test_web_contract.wasm" +``` + +In newer code, you will likely use `fdev wasm-runtime`, described in a [later section](#using-the-local-wasm-runtime-tui), to do an equivalent local testing workflow. + +--- -## Local node example +## Creating a New Package -In order to explore a contract in local mode you need to compile and run the `local-node` executable. The executable -requires a number of input parameters, you can run `local-node local-node-cli --help` in order to see the different options. -Here is an example running the CLI: +`fdev new` scaffolds a new Freenet package. Two options: +- **`contract`**: A standard WASM contract. +- **`webapp`**: A contract container that also bundles a front-end (TypeScript/webpack by default). + +Example: ```bash -./fdev run-local --input-file /tmp/input --terminal-output --deser-format json "/home/.../freenet/crates/http-gw/examples/test_web_contract.wasm" +fdev new contract ``` +Generates Rust cargo boilerplate (and for web apps, TypeScript/webpack scaffolding too). + +--- -## Contract state builder example +## Building a Contract or Delegate -In order to build an initial state for data or web you need to compile and run the `build_state` executable. The executable requires a number of input parameters, -you can run `local-node contract-state-builder --help` in order to see the different options. Here are some examples running the CLI: +Use `fdev build` to compile a Rust-based WASM contract or delegate. For example: ```bash -./fdev build [--input-metadata-path] --input-state-path contracts/freenet-microblogging/view/web --output-file contracts/freenet-microblogging-web/freenet_microblogging_view --contract-type view +fdev build \ + --package-type [contract|delegate] \ + [--features some_features] \ + [--debug] \ + [--version 0.0.2] +``` + +- **`--package-type`** defaults to `contract`. +- **`--features`** can specify crate features, e.g. `freenet-main-contract` or `freenet-main-delegate`. +- **`--debug`** produces an unoptimized WASM (useful for local tests). +- **`--version`** sets the embedded Freenet ABI version (defaults to `0.0.1`). + +`fdev` looks for a `freenet.toml` in your current directory that defines if your contract is standard or a webapp, and (for webapps) how to compile front-end code. + +**After building**, the output artifact is typically placed in `build/freenet/` unless overridden by your config file. -./fdev build [--input-metadata-path] --input-state-path contracts/freenet-microblogging/model/ --output-file contracts/freenet-microblogging-data/freenet_microblogging_model --contract-type model +--- + +## Publishing a Contract or Delegate + +`fdev publish` uploads a **new** contract or delegate to a node (either local or network mode). + +**Example: Publishing a contract**: +```bash +fdev publish \ + --code path/to/my_contract.wasm \ + --parameters path/to/params.json \ + contract \ + --state path/to/initial_state.json +``` +- **`--code`**: path to your built WASM. +- **`--parameters`**: optional contract parameters. +- **`--state`**: optional initial state JSON or binary. + +**Example: Publishing a delegate**: +```bash +fdev publish \ + --code path/to/my_delegate.wasm \ + --parameters delegate_params.json \ + delegate \ + [--nonce ... --cipher ...] +``` +- If you skip `--nonce` and `--cipher`, a default local-only encryption is used (fine for tests, not recommended for production). + +By default, `fdev publish` pushes in **local** mode unless you specify `--mode network` or set `MODE=network`. + +--- + +## Updating a Contract + +To push a state delta to an existing contract (identified by its Base58 key): + +```bash +fdev execute update \ + --delta path/to/delta.json \ + [--address 127.0.0.1 \ + --port 50509 \ + --release] +``` + +- **`--delta`**: The state delta file (JSON or binary). +- **`--release`** indicates you want to push to the network, instead of local-only. + +--- + +## Contract State Builder Example + +Sometimes you only want to build the “state artifact” for a contract or a web front-end. `fdev build` can do this if your `freenet.toml` includes a `state-sources` or webapp config. +Older Freenet docs mention `build_state` as a separate script, but in practice you can do: + +```bash +# Build a web-based front end +fdev build \ + --input-metadata-path /optional/metadata \ + --input-state-path contracts/freenet-microblogging/view/web \ + --output-file contracts/freenet-microblogging-web/freenet_microblogging_view \ + --package-type contract # or 'webapp' if your config demands ``` -Follow the instructions under the `help` command when running the tool in console mode to see the different options and commands to interact -with the contract. +Similarly, you can specify `--state` for a model-only contract: +```bash +fdev build \ + --input-state-path contracts/freenet-microblogging/model/ \ + --output-file contracts/freenet-microblogging-data/freenet_microblogging_model +``` + +*(Adjust paths, actual flags, and config to match your usage.)* + +--- + +## Inspecting a Compiled WASM + +`fdev inspect` prints metadata about a built WASM artifact, such as its hash, version, or a derived contract key. + +Examples: + +```bash +# Show code hash + contract API version +fdev inspect code path/to/contract.wasm + +# Display the contract key (hash+empty params => key) +fdev inspect key path/to/contract.wasm + +# For a delegate +fdev inspect delegate path/to/delegate.wasm +``` + +--- + +## Using the Local WASM Runtime (TUI) + +`fdev wasm-runtime` provides a local, interactive environment to test your contract. For instance: + +```bash +fdev wasm-runtime \ + --input-file /tmp/input.json \ + --deserialization-format json \ + --terminal-output +``` +- The tool will connect to a local Freenet node by default (see `--mode`, `--address`, `--port` if needed). +- Commands you type—like `put`, `get`, `update`, or `exit`—are forwarded to the local node. +- Additional command data is read from the file specified by `--input-file`. + +Common subcommands once inside the TUI: +``` +help # print instructions +put # publish a fresh contract state +get # retrieve the current contract state +update # apply a delta to the contract state +exit # quit TUI +``` + +--- + +## Querying Connected Peers + +You can list a node’s open connections: + +```bash +fdev query +``` + +It prints a table of peer identifiers and socket addresses for debugging or analysis. + +--- + +## Testing (Single-Process or Multi-Process) + +`fdev test` orchestrates an entire simulated network of Freenet nodes for end-to-end testing. + +### Single Process + +Spins up multiple in-memory nodes under one process: + +```bash +fdev test \ + --gateways 2 \ + --nodes 10 \ + --events 100 \ + single-process +``` +- **--gateways**: number of gateway nodes +- **--nodes**: number of normal nodes +- **--events**: random events (contract puts, updates, etc.) + +### Multi-Process + +```bash +fdev test \ + --gateways 2 \ + --nodes 10 \ + network +``` +- One node acts as a **supervisor** (you run `fdev test ... network --mode supervisor`). +- Others run as **peers** (`--mode peer`) connecting to the supervisor. This can scale across multiple machines or containers. + +*(See internal documentation or run `fdev test --help` for more detail.)* + +--- + +## Network Metrics Server + +```bash +fdev network-metrics-server [--log-directory path] +``` +- Launches an HTTP server (default port `55010`) for collecting or pushing network stats and event logs. +- You can then visualize or store the data for debugging or simulation metrics analysis. + +--- + +## Directory & Module Structure + +Here’s a quick look at the major modules in the `fdev` crate: + +``` +fdev +├── src +│ ├── main.rs # CLI entrypoint, top-level subcommands +│ ├── config.rs # Config structs, subcommand definitions +│ ├── commands/ # 'put', 'update', connect to node, etc. +│ ├── build.rs # Builds Rust WASM, web assets, etc. +│ ├── wasm_runtime/ # Local TUI runtime for testing contracts +│ ├── testing/ # Tools for single vs multi-process simulations +│ ├── network_metrics_server # Optional server for collecting network stats +│ └── util.rs # Shared utility helpers +└── Cargo.toml +``` + +--- + +## Common Workflows + +Below are a few typical steps you might perform: + +1. **Create a new contract** (or webapp): + ```bash + fdev new contract + ``` +2. **Build**: + ```bash + fdev build + ``` +3. **Publish** (locally by default): + ```bash + fdev publish \ + --code build/freenet/my_contract.wasm \ + contract \ + --state initial_state.json + ``` +4. **Update** the contract: + ```bash + fdev execute update \ + --delta path/to/delta.json + ``` +5. **Inspect** a compiled WASM: + ```bash + fdev inspect code build/freenet/my_contract.wasm + ``` +6. **Run local TUI** (optionally): + ```bash + fdev wasm-runtime \ + --input-file my_input.json \ + --terminal-output \ + --deserialization-format json + ``` +7. **Check open peers**: + ```bash + fdev query + ``` +8. **Simulate** a small test network: + ```bash + fdev test --nodes 5 --gateways 1 single-process + ``` +9. **(Optional) Start metrics server**: + ```bash + fdev network-metrics-server --log-directory /path/to/logs + ``` + +Feel free to run `fdev --help` for more details on any step. Enjoy building with Freenet! \ No newline at end of file From 38c26e555944801bebc38cebd91fd0ff51132a6b Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Fri, 24 Jan 2025 08:37:15 -0600 Subject: [PATCH 003/121] remove cruft --- crates/fdev/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/fdev/README.md b/crates/fdev/README.md index d123e8bb2..cbc93e86b 100644 --- a/crates/fdev/README.md +++ b/crates/fdev/README.md @@ -1,7 +1,3 @@ -Below is a comprehensive README for `fdev` that combines the existing reference documentation and the original README content. You can drop it in place of your current `README.md`. - ---- - # fdev The Freenet Development Tool (`fdev`) is a command-line utility to create, build, publish, inspect, and test Freenet contracts or delegates. It also supports local node simulations, a TUI-based WASM runtime, and optional network metrics gathering. From f838ca8d8e1073ea3dc3ff338dbea0f55d2c4f27 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Fri, 24 Jan 2025 18:15:51 -0600 Subject: [PATCH 004/121] feat: Add flexible metadata source with generator support --- crates/fdev/src/build.rs | 75 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index ceafc7cf4..5f733f9d1 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -228,10 +228,34 @@ mod contract { pub typescript: Option, #[serde(rename = "state-sources")] pub state_sources: Sources, - pub metadata: Option, + #[serde(rename = "metadata")] + pub metadata_source: Option, pub dependencies: Option, } + #[derive(Serialize, Deserialize)] + #[serde(untagged)] + pub(crate) enum MetadataSource { + // Old style - direct path string + LegacyFile(PathBuf), + // New style - structured config + #[serde(rename_all = "lowercase")] + Structured { + #[serde(flatten)] + source: MetadataSourceType + } + } + + #[derive(Serialize, Deserialize)] + #[serde(rename_all = "lowercase")] + pub(crate) enum MetadataSourceType { + File(PathBuf), + Generator { + binary: PathBuf, + args: Vec, + } + } + #[derive(Serialize, Deserialize, PartialEq)] #[serde(rename_all = "lowercase")] pub(crate) enum SupportedWebLangs { @@ -254,14 +278,55 @@ mod contract { return Ok(()); }; - let metadata = if let Some(md) = config.webapp.as_ref().and_then(|a| a.metadata.as_ref()) { - let mut buf = vec![]; - File::open(md)?.read_to_end(&mut buf)?; - buf + let metadata = if let Some(metadata_source) = config.webapp.as_ref().and_then(|a| a.metadata_source.as_ref()) { + match metadata_source { + MetadataSource::LegacyFile(path) => { + // Handle old-style direct file path + let mut buf = vec![]; + File::open(path)?.read_to_end(&mut buf)?; + buf + } + MetadataSource::Structured { source } => { + match source { + MetadataSourceType::File(path) => { + // Handle new-style file path + let mut buf = vec![]; + File::open(path)?.read_to_end(&mut buf)?; + buf + } + MetadataSourceType::Generator { binary, args } => { + use std::process::{Command, Stdio}; + + // Create child process + let mut child = Command::new(binary) + .args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn()?; + + // Write archive to child's stdin + if let Some(mut stdin) = child.stdin.take() { + let archive_bytes = archive.into_inner().into_inner(); + stdin.write_all(&archive_bytes)?; + } + + // Read metadata from stdout + let output = child.wait_with_output()?; + if !output.status.success() { + anyhow::bail!("Metadata generator failed with status: {}", output.status); + } + output.stdout + } + } + } + } } else { vec![] }; + // Recreate the archive since we consumed it for the generator + let archive = Builder::new(Cursor::new(Vec::new())); + let mut archive: Builder>> = Builder::new(Cursor::new(Vec::new())); println!("Bundling webapp contract state"); match &web_config.lang { From 00e663a1f2ffd69612dc785dcf06094600459ad1 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Fri, 24 Jan 2025 18:32:27 -0600 Subject: [PATCH 005/121] fix: Resolve archive creation and metadata field naming errors --- crates/fdev/src/build.rs | 25 +++++++++++++++++++++++-- crates/fdev/src/new_package.rs | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index 5f733f9d1..422dab2c0 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -304,9 +304,30 @@ mod contract { .stdout(Stdio::piped()) .spawn()?; - // Write archive to child's stdin + // Create archive and write to child's stdin + let mut archive = Builder::new(Cursor::new(Vec::new())); + // Add files to archive + if let Some(sources) = &sources.files { + for src in sources { + for entry in glob::glob(src)? { + let p = entry?; + let mut f = File::open(&p)?; + archive.append_file(p, &mut f)?; + } + } + } + if let Some(src_dirs) = &sources.source_dirs { + for dir in src_dirs { + let dir = cwd.join(dir); + if dir.is_dir() { + archive.append_dir_all(".", &dir)?; + } + } + } + + // Get archive bytes and write to stdin if let Some(mut stdin) = child.stdin.take() { - let archive_bytes = archive.into_inner().into_inner(); + let archive_bytes = archive.into_inner()?.into_inner(); stdin.write_all(&archive_bytes)?; } diff --git a/crates/fdev/src/new_package.rs b/crates/fdev/src/new_package.rs index 55f002e4a..22780aa04 100644 --- a/crates/fdev/src/new_package.rs +++ b/crates/fdev/src/new_package.rs @@ -38,7 +38,7 @@ fn create_view_package(cwd: &Path) -> anyhow::Result<()> { source_dirs: Some(vec![PathBuf::from("dist")]), files: None, }, - metadata: None, + metadata_source: None, dependencies: None, }), state: None, From 651f6a52661c2bcc7134c5ef3e893d9207ad7a6a Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Fri, 24 Jan 2025 18:33:36 -0600 Subject: [PATCH 006/121] docs: Add documentation for dynamic metadata generation in webapp contracts --- crates/fdev/README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/fdev/README.md b/crates/fdev/README.md index cbc93e86b..2ff928b62 100644 --- a/crates/fdev/README.md +++ b/crates/fdev/README.md @@ -114,6 +114,24 @@ fdev build \ `fdev` looks for a `freenet.toml` in your current directory that defines if your contract is standard or a webapp, and (for webapps) how to compile front-end code. +For webapp contracts, you can specify metadata either as a static file or generate it dynamically: + +```toml +[webapp] +# Static file approach: +metadata = "path/to/metadata.json" + +# Or dynamic generator approach: +metadata = { binary = "path/to/generator", args = ["--param1", "value1"] } +``` + +When using a generator, the program: +1. Receives the xzipped state archive via stdin +2. Processes it according to its logic +3. Outputs the metadata via stdout + +This allows dynamic metadata generation based on the actual contract state. + **After building**, the output artifact is typically placed in `build/freenet/` unless overridden by your config file. --- @@ -722,4 +740,4 @@ Below are a few typical steps you might perform: fdev network-metrics-server --log-directory /path/to/logs ``` -Feel free to run `fdev --help` for more details on any step. Enjoy building with Freenet! \ No newline at end of file +Feel free to run `fdev --help` for more details on any step. Enjoy building with Freenet! From ab3ce81635d383b8cc78dc2127e78e05b3c0fa32 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Fri, 24 Jan 2025 18:50:39 -0600 Subject: [PATCH 007/121] fix: Correct sources reference in build archive creation --- crates/fdev/src/build.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index 422dab2c0..92c06c7b1 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -307,8 +307,9 @@ mod contract { // Create archive and write to child's stdin let mut archive = Builder::new(Cursor::new(Vec::new())); // Add files to archive - if let Some(sources) = &sources.files { - for src in sources { + let sources = &web_config.state_sources; + if let Some(files) = &sources.files { + for src in files { for entry in glob::glob(src)? { let p = entry?; let mut f = File::open(&p)?; From 0292ac41fadd24e350d14d2173d7f595265b71c9 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sat, 25 Jan 2025 15:04:14 -0600 Subject: [PATCH 008/121] remove fdev modifications, they were the wrong approach. --- crates/fdev/README.md | 20 +------ crates/fdev/src/build.rs | 97 ++-------------------------------- crates/fdev/src/new_package.rs | 2 +- 3 files changed, 7 insertions(+), 112 deletions(-) diff --git a/crates/fdev/README.md b/crates/fdev/README.md index 2ff928b62..cbc93e86b 100644 --- a/crates/fdev/README.md +++ b/crates/fdev/README.md @@ -114,24 +114,6 @@ fdev build \ `fdev` looks for a `freenet.toml` in your current directory that defines if your contract is standard or a webapp, and (for webapps) how to compile front-end code. -For webapp contracts, you can specify metadata either as a static file or generate it dynamically: - -```toml -[webapp] -# Static file approach: -metadata = "path/to/metadata.json" - -# Or dynamic generator approach: -metadata = { binary = "path/to/generator", args = ["--param1", "value1"] } -``` - -When using a generator, the program: -1. Receives the xzipped state archive via stdin -2. Processes it according to its logic -3. Outputs the metadata via stdout - -This allows dynamic metadata generation based on the actual contract state. - **After building**, the output artifact is typically placed in `build/freenet/` unless overridden by your config file. --- @@ -740,4 +722,4 @@ Below are a few typical steps you might perform: fdev network-metrics-server --log-directory /path/to/logs ``` -Feel free to run `fdev --help` for more details on any step. Enjoy building with Freenet! +Feel free to run `fdev --help` for more details on any step. Enjoy building with Freenet! \ No newline at end of file diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index 92c06c7b1..ceafc7cf4 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -228,34 +228,10 @@ mod contract { pub typescript: Option, #[serde(rename = "state-sources")] pub state_sources: Sources, - #[serde(rename = "metadata")] - pub metadata_source: Option, + pub metadata: Option, pub dependencies: Option, } - #[derive(Serialize, Deserialize)] - #[serde(untagged)] - pub(crate) enum MetadataSource { - // Old style - direct path string - LegacyFile(PathBuf), - // New style - structured config - #[serde(rename_all = "lowercase")] - Structured { - #[serde(flatten)] - source: MetadataSourceType - } - } - - #[derive(Serialize, Deserialize)] - #[serde(rename_all = "lowercase")] - pub(crate) enum MetadataSourceType { - File(PathBuf), - Generator { - binary: PathBuf, - args: Vec, - } - } - #[derive(Serialize, Deserialize, PartialEq)] #[serde(rename_all = "lowercase")] pub(crate) enum SupportedWebLangs { @@ -278,77 +254,14 @@ mod contract { return Ok(()); }; - let metadata = if let Some(metadata_source) = config.webapp.as_ref().and_then(|a| a.metadata_source.as_ref()) { - match metadata_source { - MetadataSource::LegacyFile(path) => { - // Handle old-style direct file path - let mut buf = vec![]; - File::open(path)?.read_to_end(&mut buf)?; - buf - } - MetadataSource::Structured { source } => { - match source { - MetadataSourceType::File(path) => { - // Handle new-style file path - let mut buf = vec![]; - File::open(path)?.read_to_end(&mut buf)?; - buf - } - MetadataSourceType::Generator { binary, args } => { - use std::process::{Command, Stdio}; - - // Create child process - let mut child = Command::new(binary) - .args(args) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn()?; - - // Create archive and write to child's stdin - let mut archive = Builder::new(Cursor::new(Vec::new())); - // Add files to archive - let sources = &web_config.state_sources; - if let Some(files) = &sources.files { - for src in files { - for entry in glob::glob(src)? { - let p = entry?; - let mut f = File::open(&p)?; - archive.append_file(p, &mut f)?; - } - } - } - if let Some(src_dirs) = &sources.source_dirs { - for dir in src_dirs { - let dir = cwd.join(dir); - if dir.is_dir() { - archive.append_dir_all(".", &dir)?; - } - } - } - - // Get archive bytes and write to stdin - if let Some(mut stdin) = child.stdin.take() { - let archive_bytes = archive.into_inner()?.into_inner(); - stdin.write_all(&archive_bytes)?; - } - - // Read metadata from stdout - let output = child.wait_with_output()?; - if !output.status.success() { - anyhow::bail!("Metadata generator failed with status: {}", output.status); - } - output.stdout - } - } - } - } + let metadata = if let Some(md) = config.webapp.as_ref().and_then(|a| a.metadata.as_ref()) { + let mut buf = vec![]; + File::open(md)?.read_to_end(&mut buf)?; + buf } else { vec![] }; - // Recreate the archive since we consumed it for the generator - let archive = Builder::new(Cursor::new(Vec::new())); - let mut archive: Builder>> = Builder::new(Cursor::new(Vec::new())); println!("Bundling webapp contract state"); match &web_config.lang { diff --git a/crates/fdev/src/new_package.rs b/crates/fdev/src/new_package.rs index 22780aa04..55f002e4a 100644 --- a/crates/fdev/src/new_package.rs +++ b/crates/fdev/src/new_package.rs @@ -38,7 +38,7 @@ fn create_view_package(cwd: &Path) -> anyhow::Result<()> { source_dirs: Some(vec![PathBuf::from("dist")]), files: None, }, - metadata_source: None, + metadata: None, dependencies: None, }), state: None, From 552c5d07f93185850d0a48e09fb1b1babf743aad Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:28:29 -0600 Subject: [PATCH 009/121] feat: Add support for pre-compressed webapp archive in fdev publish --- crates/fdev/src/commands.rs | 42 ++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 9b8133d49..05df142e2 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -26,6 +26,12 @@ pub(crate) struct PutContract { /// A path to the initial state for the contract being published. #[arg(long)] pub(crate) state: Option, + /// A path to a pre-compressed tar.xz webapp archive + #[arg(long)] + pub(crate) webapp_archive: Option, + /// A path to the metadata file to include with the webapp + #[arg(long)] + pub(crate) webapp_metadata: Option, } #[derive(clap::Parser, Clone, Debug)] @@ -62,7 +68,41 @@ async fn put_contract( params: Parameters<'static>, ) -> anyhow::Result<()> { let contract = ContractContainer::try_from((config.code.as_path(), params))?; - let state = if let Some(ref state_path) = contract_config.state { + let state = if let Some(ref webapp_archive) = contract_config.webapp_archive { + // Read webapp archive + let mut archive = vec![]; + File::open(webapp_archive)?.read_to_end(&mut archive)?; + + // Read optional metadata + let metadata = if let Some(ref metadata_path) = contract_config.webapp_metadata { + let mut buf = vec![]; + File::open(metadata_path)?.read_to_end(&mut buf)?; + buf + } else { + vec![] + }; + + // Validate archive has index.html (warning only) + use tar::Archive; + use std::io::Cursor; + let mut found_index = false; + let tar = Archive::new(xz::read::XzDecoder::new(Cursor::new(&archive))); + for entry in tar.entries()? { + if let Ok(entry) = entry { + if entry.path()?.to_string_lossy() == "index.html" { + found_index = true; + break; + } + } + } + if !found_index { + tracing::warn!("Warning: No index.html found at root of webapp archive"); + } + + // Create WebApp state + let webapp = freenet_stdlib::prelude::WebApp::from_data(metadata, archive)?; + webapp.pack()? + } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; File::open(state_path)?.read_to_end(&mut buf)?; buf.into() From 68d13a6270db80e4d30c1312a3ba44631182038e Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:30:47 -0600 Subject: [PATCH 010/121] fix: Update xz2 dependency and fix WebApp and XzDecoder imports --- crates/fdev/Cargo.toml | 2 +- crates/fdev/src/commands.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/fdev/Cargo.toml b/crates/fdev/Cargo.toml index 190aa033a..cf2a50cf5 100644 --- a/crates/fdev/Cargo.toml +++ b/crates/fdev/Cargo.toml @@ -33,7 +33,7 @@ tokio-tungstenite = "0.24" toml = { version = "0.8", features = ["default", "preserve_order"] } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] } -xz2 = "0.1" +xz2 = { version = "0.1", features = ["tokio"] } reqwest = { version = "0.12", features = ["json"] } http = "1.2" diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 05df142e2..f427ea85d 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -5,6 +5,8 @@ use freenet_stdlib::{ client_api::{ClientRequest, ContractRequest, DelegateRequest, WebApi}, prelude::*, }; +use freenet::server::WebApp; +use xz2::read::XzDecoder; use crate::config::{BaseConfig, PutConfig, UpdateConfig}; @@ -86,7 +88,7 @@ async fn put_contract( use tar::Archive; use std::io::Cursor; let mut found_index = false; - let tar = Archive::new(xz::read::XzDecoder::new(Cursor::new(&archive))); + let tar = Archive::new(XzDecoder::new(Cursor::new(&archive))); for entry in tar.entries()? { if let Ok(entry) = entry { if entry.path()?.to_string_lossy() == "index.html" { @@ -100,7 +102,7 @@ async fn put_contract( } // Create WebApp state - let webapp = freenet_stdlib::prelude::WebApp::from_data(metadata, archive)?; + let webapp = WebApp::from_data(metadata, archive)?; webapp.pack()? } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From 65d9cc0647ad6488c61a70878d6b21f6c8ee73c6 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:36:26 -0600 Subject: [PATCH 011/121] fix: Resolve type mismatches in WebApp state and archive handling --- crates/fdev/src/commands.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index f427ea85d..7c62793bc 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -102,15 +102,15 @@ async fn put_contract( } // Create WebApp state - let webapp = WebApp::from_data(metadata, archive)?; - webapp.pack()? + let webapp = WebApp::from_data(metadata, archive.into_inner().into_inner())?; + webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; File::open(state_path)?.read_to_end(&mut buf)?; buf.into() } else { tracing::warn!("no state provided for contract, if your contract cannot handle empty state correctly, this will always cause an error."); - vec![].into() + vec![].into().into() }; let related_contracts = if let Some(_related) = &contract_config.related_contracts { todo!("use `related` contracts") From 440b06e027929ccd2f2afc31085dc3ddba0fb724 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:38:05 -0600 Subject: [PATCH 012/121] fix: Remove unnecessary `into_inner()` calls in WebApp creation --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 7c62793bc..f98c8f7ec 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -102,7 +102,7 @@ async fn put_contract( } // Create WebApp state - let webapp = WebApp::from_data(metadata, archive.into_inner().into_inner())?; + let webapp = WebApp::from_data(metadata, archive)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From 40f20a3bc5082bc8a61c171a7a82f8c69ded764e Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:39:16 -0600 Subject: [PATCH 013/121] fix: Convert archive to tar::Builder before passing to WebApp::from_data --- crates/fdev/src/commands.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index f98c8f7ec..82e8b45e4 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -102,7 +102,9 @@ async fn put_contract( } // Create WebApp state - let webapp = WebApp::from_data(metadata, archive)?; + let mut archive_builder = Builder::new(Cursor::new(Vec::new())); + archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &archive)?; + let webapp = WebApp::from_data(metadata, archive_builder)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From d42fbf4e25e97a3edea1ffc85ccc41fde966507d Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:41:33 -0600 Subject: [PATCH 014/121] fix: Update WebApp method calls and add tar::Builder import --- crates/fdev/src/build.rs | 5 +++-- crates/fdev/src/commands.rs | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index ceafc7cf4..465503723 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -1,5 +1,6 @@ use freenet::server::WebApp; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; +use tar::Builder; use serde_with::skip_serializing_none; use std::{ collections::HashMap, @@ -390,7 +391,7 @@ mod contract { if !found_entry { anyhow::bail!("didn't find entry point `index.html` in package"); } else { - let state = WebApp::from_data(metadata, archive)?; + let state = WebApp::nfrom_data(metadata, archive)?; let packed = state.pack()?; output_artifact(&config.contract.output_dir, &packed, cwd)?; println!("Finished bundling webapp contract state"); diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 82e8b45e4..f9f43407e 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -7,6 +7,7 @@ use freenet_stdlib::{ }; use freenet::server::WebApp; use xz2::read::XzDecoder; +use tar::Builder; use crate::config::{BaseConfig, PutConfig, UpdateConfig}; @@ -104,7 +105,7 @@ async fn put_contract( // Create WebApp state let mut archive_builder = Builder::new(Cursor::new(Vec::new())); archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &archive)?; - let webapp = WebApp::from_data(metadata, archive_builder)?; + let webapp = WebApp::nfrom_data(metadata, archive_builder)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From d9670fe03bd07618cc3538341175c8aaba903750 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:43:07 -0600 Subject: [PATCH 015/121] fix: Remove duplicate tar::Builder import and dereference Vec --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index f9f43407e..faf8d8b5c 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -104,7 +104,7 @@ async fn put_contract( // Create WebApp state let mut archive_builder = Builder::new(Cursor::new(Vec::new())); - archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &archive)?; + archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &*archive)?; let webapp = WebApp::nfrom_data(metadata, archive_builder)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { From db0df7f7afb0804dd981747aad3716002ea97508 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:43:18 -0600 Subject: [PATCH 016/121] refactor: Remove duplicate tar::Builder import in build.rs --- crates/fdev/src/build.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index 465503723..3c5648049 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -1,6 +1,5 @@ use freenet::server::WebApp; use serde::{Deserialize, Serialize}; -use tar::Builder; use serde_with::skip_serializing_none; use std::{ collections::HashMap, From ffe6e899118a8567a0232914223708fe2d35febf Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:44:10 -0600 Subject: [PATCH 017/121] fix: Resolve type inference issue with empty State in fdev commands --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index faf8d8b5c..d3fa87c60 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -113,7 +113,7 @@ async fn put_contract( buf.into() } else { tracing::warn!("no state provided for contract, if your contract cannot handle empty state correctly, this will always cause an error."); - vec![].into().into() + freenet_stdlib::prelude::State::from(vec![]) }; let related_contracts = if let Some(_related) = &contract_config.related_contracts { todo!("use `related` contracts") From 28e21ffe3be5cadc412bc15465c735e81bac8e14 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:47:06 -0600 Subject: [PATCH 018/121] fix: Convert State to WrappedState in ContractRequest::Put --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index d3fa87c60..f16c34d48 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -124,7 +124,7 @@ async fn put_contract( println!("Putting contract {}", contract.key()); let request = ContractRequest::Put { contract, - state, + state: state.into(), related_contracts, } .into(); From e194d53263ea592b8291cb244cecd4d0cda727f8 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 15:52:43 -0600 Subject: [PATCH 019/121] fix: convert State to Vec before converting to WrappedState --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index f16c34d48..b4d8184b5 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -124,7 +124,7 @@ async fn put_contract( println!("Putting contract {}", contract.key()); let request = ContractRequest::Put { contract, - state: state.into(), + state: state.to_vec().into(), related_contracts, } .into(); From 455eca6ac851f74a8ba08b762366124af3bd229c Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 16:00:35 -0600 Subject: [PATCH 020/121] fix: Make tar variable mutable to resolve borrow error in entries() --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index b4d8184b5..d534592af 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -89,7 +89,7 @@ async fn put_contract( use tar::Archive; use std::io::Cursor; let mut found_index = false; - let tar = Archive::new(XzDecoder::new(Cursor::new(&archive))); + let mut tar = Archive::new(XzDecoder::new(Cursor::new(&archive))); for entry in tar.entries()? { if let Ok(entry) = entry { if entry.path()?.to_string_lossy() == "index.html" { From 0a05f2029ff5005849d83e06484c1b5e00cd13e8 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 16:04:53 -0600 Subject: [PATCH 021/121] docs: Add documentation for pre-compressed webapp archive publishing method --- crates/fdev/README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/crates/fdev/README.md b/crates/fdev/README.md index cbc93e86b..a001b710c 100644 --- a/crates/fdev/README.md +++ b/crates/fdev/README.md @@ -134,6 +134,25 @@ fdev publish \ - **`--parameters`**: optional contract parameters. - **`--state`**: optional initial state JSON or binary. +**Example: Publishing a webapp contract with pre-compressed archive**: +```bash +# First compress your webapp directory +tar cf - webapp/ | xz > webapp.tar.xz + +# Then publish the webapp contract +fdev publish \ + --code path/to/webapp_contract.wasm \ + --parameters path/to/params.json \ + contract \ + --webapp-archive webapp.tar.xz \ + --webapp-metadata path/to/metadata.json +``` +- **`--webapp-archive`**: path to your xz-compressed tar archive containing the webapp files. + The archive should contain an index.html file at the root level. +- **`--webapp-metadata`**: optional path to metadata file for the webapp. + +This alternative to the TypeScript/webpack build process allows you to provide your own pre-compressed webapp archive. + **Example: Publishing a delegate**: ```bash fdev publish \ @@ -722,4 +741,4 @@ Below are a few typical steps you might perform: fdev network-metrics-server --log-directory /path/to/logs ``` -Feel free to run `fdev --help` for more details on any step. Enjoy building with Freenet! \ No newline at end of file +Feel free to run `fdev --help` for more details on any step. Enjoy building with Freenet! From 5e9d327bcdf75817dc9263148182e71345190081 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 16:06:08 -0600 Subject: [PATCH 022/121] docs: Clarify webapp metadata can be any binary format --- crates/fdev/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/README.md b/crates/fdev/README.md index a001b710c..eb2f6bd2c 100644 --- a/crates/fdev/README.md +++ b/crates/fdev/README.md @@ -149,7 +149,7 @@ fdev publish \ ``` - **`--webapp-archive`**: path to your xz-compressed tar archive containing the webapp files. The archive should contain an index.html file at the root level. -- **`--webapp-metadata`**: optional path to metadata file for the webapp. +- **`--webapp-metadata`**: optional path to metadata file for the webapp (can be any binary format). This alternative to the TypeScript/webpack build process allows you to provide your own pre-compressed webapp archive. From 22c85383a9697307ee9b6c23fd289df91cbc90e6 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 16:09:46 -0600 Subject: [PATCH 023/121] docs: Remove JSON references for parameters, state, and input files --- crates/fdev/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/fdev/README.md b/crates/fdev/README.md index eb2f6bd2c..23b2ac32b 100644 --- a/crates/fdev/README.md +++ b/crates/fdev/README.md @@ -126,13 +126,13 @@ fdev build \ ```bash fdev publish \ --code path/to/my_contract.wasm \ - --parameters path/to/params.json \ + --parameters path/to/params \ contract \ - --state path/to/initial_state.json + --state path/to/initial_state ``` - **`--code`**: path to your built WASM. -- **`--parameters`**: optional contract parameters. -- **`--state`**: optional initial state JSON or binary. +- **`--parameters`**: optional contract parameters file (typically binary format). +- **`--state`**: optional initial state file (typically binary format). **Example: Publishing a webapp contract with pre-compressed archive**: ```bash @@ -142,7 +142,7 @@ tar cf - webapp/ | xz > webapp.tar.xz # Then publish the webapp contract fdev publish \ --code path/to/webapp_contract.wasm \ - --parameters path/to/params.json \ + --parameters path/to/params \ contract \ --webapp-archive webapp.tar.xz \ --webapp-metadata path/to/metadata.json @@ -157,7 +157,7 @@ This alternative to the TypeScript/webpack build process allows you to provide y ```bash fdev publish \ --code path/to/my_delegate.wasm \ - --parameters delegate_params.json \ + --parameters delegate_params \ delegate \ [--nonce ... --cipher ...] ``` @@ -173,7 +173,7 @@ To push a state delta to an existing contract (identified by its Base58 key): ```bash fdev execute update \ - --delta path/to/delta.json \ + --delta path/to/delta \ [--address 127.0.0.1 \ --port 50509 \ --release] @@ -234,8 +234,8 @@ fdev inspect delegate path/to/delegate.wasm ```bash fdev wasm-runtime \ - --input-file /tmp/input.json \ - --deserialization-format json \ + --input-file /tmp/input \ + --deserialization-format binary \ --terminal-output ``` - The tool will connect to a local Freenet node by default (see `--mode`, `--address`, `--port` if needed). @@ -346,7 +346,7 @@ Below are a few typical steps you might perform: fdev publish \ --code build/freenet/my_contract.wasm \ contract \ - --state initial_state.json + --state initial_state ``` 4. **Update** the contract: ```bash From fba5dcdf7cf3d3cb796c2dbb5cb3f2d1550ebfdf Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 25 Jan 2025 18:47:01 -0600 Subject: [PATCH 024/121] docs: Improve CLI help text for contract and delegate publishing options --- crates/fdev/src/commands.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index d534592af..1b0dc1f78 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -15,34 +15,34 @@ mod v1; #[derive(Debug, Clone, clap::Subcommand)] pub(crate) enum PutType { - /// Puts a new contract + /// Publish a new contract to the network Contract(PutContract), - /// Puts a new delegate + /// Publish a new delegate to the network Delegate(PutDelegate), } #[derive(clap::Parser, Clone, Debug)] pub(crate) struct PutContract { - /// A path to a JSON file listing the related contracts. + /// Path to a file listing the related contracts #[arg(long)] pub(crate) related_contracts: Option, - /// A path to the initial state for the contract being published. + /// Path to the initial state for the contract (typically binary format) #[arg(long)] pub(crate) state: Option, - /// A path to a pre-compressed tar.xz webapp archive + /// Path to a pre-compressed tar.xz webapp archive containing the webapp files (must include index.html at root) #[arg(long)] pub(crate) webapp_archive: Option, - /// A path to the metadata file to include with the webapp + /// Path to the metadata file to include with the webapp (can be any binary format) #[arg(long)] pub(crate) webapp_metadata: Option, } #[derive(clap::Parser, Clone, Debug)] pub(crate) struct PutDelegate { - /// Base58 encoded nonce. If empty the default value will be used, this is only allowed in local mode. + /// Base58 encoded nonce for delegate encryption. If empty the default value will be used (only allowed in local mode) #[arg(long, env = "DELEGATE_NONCE", default_value_t = String::new())] pub(crate) nonce: String, - /// Base58 encoded cipher. If empty the default value will be used, this is only allowed in local mode. + /// Base58 encoded cipher for delegate encryption. If empty the default value will be used (only allowed in local mode) #[arg(long, env = "DELEGATE_CIPHER", default_value_t = String::new())] pub(crate) cipher: String, } From b2daf1d304b9d981f570f93704fe98b9ae5fee6f Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 26 Jan 2025 21:13:06 -0600 Subject: [PATCH 025/121] feat: Add version wrapper for raw WASM files in contract put command --- crates/fdev/src/commands.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 1b0dc1f78..6893a22f7 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -4,6 +4,7 @@ use freenet::dev_tool::OperationMode; use freenet_stdlib::{ client_api::{ClientRequest, ContractRequest, DelegateRequest, WebApi}, prelude::*, + versioning::Version, }; use freenet::server::WebApp; use xz2::read::XzDecoder; @@ -70,7 +71,15 @@ async fn put_contract( other: BaseConfig, params: Parameters<'static>, ) -> anyhow::Result<()> { - let contract = ContractContainer::try_from((config.code.as_path(), params))?; + // Try to load as raw WASM first + let contract = if let Ok(code) = ContractCode::load_raw(&config.code) { + // Add version wrapper + let version = Version::new(0, 0, 1); + ContractContainer::from_code_versioned(code, version.into())? + } else { + // Fall back to trying as already versioned + ContractContainer::try_from((config.code.as_path(), params))? + }; let state = if let Some(ref webapp_archive) = contract_config.webapp_archive { // Read webapp archive let mut archive = vec![]; From 0bbe1999eaf7d8826551ef60074b60b5f55dff18 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 26 Jan 2025 21:13:41 -0600 Subject: [PATCH 026/121] fix: Update contract versioning and import for fdev CLI --- crates/fdev/src/commands.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 6893a22f7..40ecf825a 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -4,8 +4,8 @@ use freenet::dev_tool::OperationMode; use freenet_stdlib::{ client_api::{ClientRequest, ContractRequest, DelegateRequest, WebApi}, prelude::*, - versioning::Version, }; +use semver::Version; use freenet::server::WebApp; use xz2::read::XzDecoder; use tar::Builder; @@ -75,7 +75,7 @@ async fn put_contract( let contract = if let Ok(code) = ContractCode::load_raw(&config.code) { // Add version wrapper let version = Version::new(0, 0, 1); - ContractContainer::from_code_versioned(code, version.into())? + ContractContainer::try_from((code.data(), params))? } else { // Fall back to trying as already versioned ContractContainer::try_from((config.code.as_path(), params))? From 1191598e1ab9f1c7078b9e3d7604731e22189604 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 26 Jan 2025 21:14:06 -0600 Subject: [PATCH 027/121] fix: Correct ContractContainer creation from raw WASM code --- crates/fdev/src/commands.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 40ecf825a..f71a81dfb 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -72,10 +72,11 @@ async fn put_contract( params: Parameters<'static>, ) -> anyhow::Result<()> { // Try to load as raw WASM first - let contract = if let Ok(code) = ContractCode::load_raw(&config.code) { + let contract = if let Ok(raw_code) = ContractCode::load_raw(&config.code) { // Add version wrapper let version = Version::new(0, 0, 1); - ContractContainer::try_from((code.data(), params))? + let code = ContractCode::from(raw_code.data().to_vec()); + ContractContainer::try_from((code, params))? } else { // Fall back to trying as already versioned ContractContainer::try_from((config.code.as_path(), params))? From 1579ae3de45837da51f85ffdf377003485577985 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 26 Jan 2025 21:14:31 -0600 Subject: [PATCH 028/121] fix: Resolve ContractContainer conversion in fdev contract deployment --- crates/fdev/src/commands.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index f71a81dfb..c466f9beb 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -74,9 +74,10 @@ async fn put_contract( // Try to load as raw WASM first let contract = if let Ok(raw_code) = ContractCode::load_raw(&config.code) { // Add version wrapper - let version = Version::new(0, 0, 1); + let version = Version::new(0, 0, 1); let code = ContractCode::from(raw_code.data().to_vec()); - ContractContainer::try_from((code, params))? + let api_version = ContractWasmAPIVersion::new(code, params); + ContractContainer::from(api_version) } else { // Fall back to trying as already versioned ContractContainer::try_from((config.code.as_path(), params))? From 065901ffcd0addc3e99e20b4133afd7e34f369fd Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 26 Jan 2025 21:14:56 -0600 Subject: [PATCH 029/121] fix: Replace ContractWasmAPIVersion::new() with From trait implementation --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index c466f9beb..2d38ed57d 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -76,7 +76,7 @@ async fn put_contract( // Add version wrapper let version = Version::new(0, 0, 1); let code = ContractCode::from(raw_code.data().to_vec()); - let api_version = ContractWasmAPIVersion::new(code, params); + let api_version = ContractWasmAPIVersion::from((code, params)); ContractContainer::from(api_version) } else { // Fall back to trying as already versioned From b52ab1747de67875a170f7fb71fd9e742ebf0a8d Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 26 Jan 2025 21:15:16 -0600 Subject: [PATCH 030/121] fix: Correct ContractWasmAPIVersion construction in put_contract --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 2d38ed57d..c0d880ab2 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -76,7 +76,7 @@ async fn put_contract( // Add version wrapper let version = Version::new(0, 0, 1); let code = ContractCode::from(raw_code.data().to_vec()); - let api_version = ContractWasmAPIVersion::from((code, params)); + let api_version = ContractWasmAPIVersion::V1 { code, params }; ContractContainer::from(api_version) } else { // Fall back to trying as already versioned From 7c100540fe0ab8cf223f7268f2e8a7bcf1708f7b Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 26 Jan 2025 21:15:37 -0600 Subject: [PATCH 031/121] fix: Correct ContractWasmAPIVersion::V1 variant usage in contract deployment --- crates/fdev/src/commands.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index c0d880ab2..773f76d29 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -76,7 +76,8 @@ async fn put_contract( // Add version wrapper let version = Version::new(0, 0, 1); let code = ContractCode::from(raw_code.data().to_vec()); - let api_version = ContractWasmAPIVersion::V1 { code, params }; + let wrapped = WrappedContract::new(code, params); + let api_version = ContractWasmAPIVersion::V1(wrapped); ContractContainer::from(api_version) } else { // Fall back to trying as already versioned From 19863312a89393f38f02424286b49e47bdb4a53a Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 26 Jan 2025 21:16:05 -0600 Subject: [PATCH 032/121] fix: Wrap ContractCode in Arc for WrappedContract::new() --- crates/fdev/src/commands.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 773f76d29..a429bf533 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -1,4 +1,4 @@ -use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf}; +use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc}; use freenet::dev_tool::OperationMode; use freenet_stdlib::{ @@ -76,7 +76,7 @@ async fn put_contract( // Add version wrapper let version = Version::new(0, 0, 1); let code = ContractCode::from(raw_code.data().to_vec()); - let wrapped = WrappedContract::new(code, params); + let wrapped = WrappedContract::new(Arc::new(code), params); let api_version = ContractWasmAPIVersion::V1(wrapped); ContractContainer::from(api_version) } else { From 80631525dcabe497e6736cb02409bbd9875fdeb0 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 26 Jan 2025 21:16:33 -0600 Subject: [PATCH 033/121] refactor: Remove unused version variable in contract deployment --- crates/fdev/src/commands.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index a429bf533..03afe42ea 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -74,7 +74,6 @@ async fn put_contract( // Try to load as raw WASM first let contract = if let Ok(raw_code) = ContractCode::load_raw(&config.code) { // Add version wrapper - let version = Version::new(0, 0, 1); let code = ContractCode::from(raw_code.data().to_vec()); let wrapped = WrappedContract::new(Arc::new(code), params); let api_version = ContractWasmAPIVersion::V1(wrapped); From 94c743057f2de5f108e21f1672681ecb1a8145d5 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 26 Jan 2025 21:16:59 -0600 Subject: [PATCH 034/121] wip --- Cargo.lock | 110 ++++++++++++++++-------- crates/core/src/server/app_packaging.rs | 2 +- crates/fdev/src/commands.rs | 1 - 3 files changed, 75 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f68794c1c..728b8c84a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -278,7 +278,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-sink", "futures-util", "memchr", @@ -324,7 +324,7 @@ dependencies = [ "async-trait", "axum-core", "base64 0.22.1", - "bytes", + "bytes 1.9.0", "futures-util", "http 1.2.0", "http-body", @@ -358,7 +358,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", - "bytes", + "bytes 1.9.0", "futures-util", "http 1.2.0", "http-body", @@ -554,6 +554,16 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +dependencies = [ + "byteorder", + "iovec", +] + [[package]] name = "bytes" version = "1.9.0" @@ -1416,7 +1426,7 @@ dependencies = [ "either", "freenet", "freenet-stdlib", - "futures", + "futures 0.3.31", "glob", "http 1.2.0", "pico-args", @@ -1530,7 +1540,7 @@ dependencies = [ "blake3", "bs58", "byteorder", - "bytes", + "bytes 1.9.0", "cache-padded", "chacha20poly1305", "chrono", @@ -1544,7 +1554,7 @@ dependencies = [ "either", "flatbuffers", "freenet-stdlib", - "futures", + "futures 0.3.31", "headers", "hickory-resolver", "httptest", @@ -1605,7 +1615,7 @@ dependencies = [ "clap", "freenet-ping-types", "freenet-stdlib", - "futures", + "futures 0.3.31", "serde_json", "tokio", "tokio-tungstenite 0.24.0", @@ -1646,7 +1656,7 @@ dependencies = [ "chrono", "flatbuffers", "freenet-macros", - "futures", + "futures 0.3.31", "js-sys", "once_cell", "rand", @@ -1675,6 +1685,12 @@ dependencies = [ "libc", ] +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + [[package]] name = "futures" version = "0.3.31" @@ -1863,7 +1879,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", - "bytes", + "bytes 1.9.0", "fnv", "futures-core", "futures-sink", @@ -1926,7 +1942,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" dependencies = [ "base64 0.21.7", - "bytes", + "bytes 1.9.0", "headers-core", "http 1.2.0", "httpdate", @@ -2061,7 +2077,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes", + "bytes 1.9.0", "fnv", "itoa", ] @@ -2072,7 +2088,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ - "bytes", + "bytes 1.9.0", "fnv", "itoa", ] @@ -2083,7 +2099,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes", + "bytes 1.9.0", "http 1.2.0", ] @@ -2093,7 +2109,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-util", "http 1.2.0", "http-body", @@ -2125,10 +2141,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae0fc8d140f1f0f3e7f821c8eff55cd13966db7a3370b2d9a7b08e9ec8ee8786" dependencies = [ "bstr", - "bytes", + "bytes 1.9.0", "crossbeam-channel", "form_urlencoded", - "futures", + "futures 0.3.31", "http 1.2.0", "http-body-util", "hyper", @@ -2164,7 +2180,7 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-channel", "futures-util", "h2", @@ -2215,7 +2231,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes", + "bytes 1.9.0", "http-body-util", "hyper", "hyper-util", @@ -2231,7 +2247,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-channel", "futures-util", "http 1.2.0", @@ -2478,6 +2494,15 @@ version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + [[package]] name = "ipconfig" version = "0.3.2" @@ -3193,7 +3218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0ba633e55c5ea6f431875ba55e71664f2fa5d3a90bd34ec9302eecc41c865dd" dependencies = [ "async-trait", - "bytes", + "bytes 1.9.0", "http 0.2.12", "opentelemetry 0.23.0", ] @@ -3616,7 +3641,7 @@ version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec" dependencies = [ - "bytes", + "bytes 1.9.0", "prost-derive", ] @@ -3888,7 +3913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" dependencies = [ "base64 0.22.1", - "bytes", + "bytes 1.9.0", "encoding_rs", "futures-core", "futures-util", @@ -3957,7 +3982,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b11a153aec4a6ab60795f8ebe2923c597b16b05bb1504377451e705ef1a45323" dependencies = [ "bytecheck 0.8.0", - "bytes", + "bytes 1.9.0", "hashbrown 0.15.2", "indexmap 2.7.0", "munge", @@ -4378,7 +4403,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" dependencies = [ - "bytes", + "bytes 1.9.0", "memmap2", ] @@ -4515,7 +4540,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a007b6936676aa9ab40207cde35daab0a04b823be8ae004368c0793b96a61e0" dependencies = [ - "bytes", + "bytes 1.9.0", "crc", "crossbeam-queue", "either", @@ -4594,7 +4619,7 @@ dependencies = [ "base64 0.22.1", "bitflags 2.8.0", "byteorder", - "bytes", + "bytes 1.9.0", "crc", "digest", "dotenvy", @@ -4720,7 +4745,7 @@ dependencies = [ "async-io", "atomic", "crossbeam-channel", - "futures", + "futures 0.3.31", "getrandom", "parking_lot", "rand", @@ -4994,7 +5019,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", - "bytes", + "bytes 1.9.0", "libc", "mio", "parking_lot", @@ -5005,6 +5030,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "tokio-io" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", + "log", +] + [[package]] name = "tokio-macros" version = "2.5.0" @@ -5087,7 +5123,7 @@ version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ - "bytes", + "bytes 1.9.0", "futures-core", "futures-sink", "pin-project-lite", @@ -5139,7 +5175,7 @@ dependencies = [ "async-trait", "axum", "base64 0.22.1", - "bytes", + "bytes 1.9.0", "h2", "http 1.2.0", "http-body", @@ -5202,7 +5238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" dependencies = [ "bitflags 2.8.0", - "bytes", + "bytes 1.9.0", "futures-util", "http 1.2.0", "http-body", @@ -5345,7 +5381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" dependencies = [ "byteorder", - "bytes", + "bytes 1.9.0", "data-encoding", "http 1.2.0", "httparse", @@ -5363,7 +5399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24" dependencies = [ "byteorder", - "bytes", + "bytes 1.9.0", "data-encoding", "http 1.2.0", "httparse", @@ -5463,7 +5499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" dependencies = [ "asynchronous-codec", - "bytes", + "bytes 1.9.0", "tokio-util", ] @@ -5675,7 +5711,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "998dea47d6bb6a8fc7dd8a17b13bf8de277e007229f270c67105cb67fc2d9657" dependencies = [ "bindgen", - "bytes", + "bytes 1.9.0", "cfg-if", "cmake", "indexmap 1.9.3", @@ -5709,7 +5745,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "082f48ba006cce2358f6c63d8dba732c9d12ba5833008c9ff2944290eb72c3dc" dependencies = [ "backtrace", - "bytes", + "bytes 1.9.0", "cfg-if", "enum-iterator", "enumset", @@ -6207,7 +6243,9 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" dependencies = [ + "futures 0.1.31", "lzma-sys", + "tokio-io", ] [[package]] diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index 02f6ffb7a..f37602861 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -25,7 +25,7 @@ pub struct WebApp { } impl WebApp { - pub fn from_data( + pub fn nfrom_data( metadata: Vec, web: Builder>>, ) -> Result { diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 03afe42ea..d9cc58fee 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -5,7 +5,6 @@ use freenet_stdlib::{ client_api::{ClientRequest, ContractRequest, DelegateRequest, WebApi}, prelude::*, }; -use semver::Version; use freenet::server::WebApp; use xz2::read::XzDecoder; use tar::Builder; From e19a7b0d1fa37d2dfa626523471f65876b783d11 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Mon, 27 Jan 2025 09:48:56 -0600 Subject: [PATCH 035/121] update to stdlib branch --- .gitmodules | 2 +- stdlib | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 0a1016135..13782bb2f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "stdlib"] path = stdlib - url = https://github.com/freenet/freenet-stdlib + url = git@github.com:freenet/freenet-stdlib.git diff --git a/stdlib b/stdlib index e582de3ed..94777c275 160000 --- a/stdlib +++ b/stdlib @@ -1 +1 @@ -Subproject commit e582de3ed49ea102f84fffba68f07dc934ac4d0a +Subproject commit 94777c2751cb1c9259a48b5addeec13064e7f8c4 From 221a0ec2723726591d5ea2476f036b78d303ab08 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Mon, 27 Jan 2025 09:57:28 -0600 Subject: [PATCH 036/121] point stdlib at main branch --- stdlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib b/stdlib index 94777c275..e582de3ed 160000 --- a/stdlib +++ b/stdlib @@ -1 +1 @@ -Subproject commit 94777c2751cb1c9259a48b5addeec13064e7f8c4 +Subproject commit e582de3ed49ea102f84fffba68f07dc934ac4d0a From 7343baee5aa7465c71dda20cb1905ea359aea26b Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 27 Jan 2025 10:38:22 -0600 Subject: [PATCH 037/121] fix: Remove unnecessary tar wrapping and fix index.html validation --- crates/fdev/src/commands.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index d9cc58fee..ef23ac5dd 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -99,7 +99,8 @@ async fn put_contract( use tar::Archive; use std::io::Cursor; let mut found_index = false; - let mut tar = Archive::new(XzDecoder::new(Cursor::new(&archive))); + let decoder = XzDecoder::new(Cursor::new(&archive)); + let mut tar = Archive::new(decoder); for entry in tar.entries()? { if let Ok(entry) = entry { if entry.path()?.to_string_lossy() == "index.html" { @@ -112,10 +113,8 @@ async fn put_contract( tracing::warn!("Warning: No index.html found at root of webapp archive"); } - // Create WebApp state - let mut archive_builder = Builder::new(Cursor::new(Vec::new())); - archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &*archive)?; - let webapp = WebApp::nfrom_data(metadata, archive_builder)?; + // Create WebApp state from the archive directly + let webapp = WebApp::nfrom_data(metadata, archive)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From 2f2ed64db46f0e7d9b4e80fe00929ed9bb42ce75 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 27 Jan 2025 10:38:54 -0600 Subject: [PATCH 038/121] fix: Correctly create tar Builder for WebApp::nfrom_data --- crates/fdev/src/commands.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index ef23ac5dd..33cf5b212 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -113,8 +113,10 @@ async fn put_contract( tracing::warn!("Warning: No index.html found at root of webapp archive"); } - // Create WebApp state from the archive directly - let webapp = WebApp::nfrom_data(metadata, archive)?; + // Create WebApp state + let mut archive_builder = Builder::new(Cursor::new(Vec::new())); + archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &archive)?; + let webapp = WebApp::nfrom_data(metadata, archive_builder)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From 0961580bc50ee43b4dba0d1560ae314fdc9269d5 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 27 Jan 2025 10:39:13 -0600 Subject: [PATCH 039/121] fix: Wrap archive bytes in Cursor to implement Read trait for tar::Builder --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 33cf5b212..dfb2c36be 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -115,7 +115,7 @@ async fn put_contract( // Create WebApp state let mut archive_builder = Builder::new(Cursor::new(Vec::new())); - archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &archive)?; + archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &mut std::io::Cursor::new(&archive))?; let webapp = WebApp::nfrom_data(metadata, archive_builder)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { From d04a06f51b9a637de330cd4f657d171209c24a44 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Mon, 27 Jan 2025 10:40:20 -0600 Subject: [PATCH 040/121] fix typo in function name --- crates/core/src/server/app_packaging.rs | 2 +- crates/fdev/src/build.rs | 2 +- crates/fdev/src/commands.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index f37602861..02f6ffb7a 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -25,7 +25,7 @@ pub struct WebApp { } impl WebApp { - pub fn nfrom_data( + pub fn from_data( metadata: Vec, web: Builder>>, ) -> Result { diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index 3c5648049..0927d3372 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -390,7 +390,7 @@ mod contract { if !found_entry { anyhow::bail!("didn't find entry point `index.html` in package"); } else { - let state = WebApp::nfrom_data(metadata, archive)?; + let state = WebApp::from_data(metadata, archive)?; let packed = state.pack()?; output_artifact(&config.contract.output_dir, &packed, cwd)?; println!("Finished bundling webapp contract state"); diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index dfb2c36be..0fcc4a300 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -116,7 +116,7 @@ async fn put_contract( // Create WebApp state let mut archive_builder = Builder::new(Cursor::new(Vec::new())); archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &mut std::io::Cursor::new(&archive))?; - let webapp = WebApp::nfrom_data(metadata, archive_builder)?; + let webapp = WebApp::from_data(metadata, archive_builder)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From 3a71ababd885abb5fe6e8e841f4a2a94bcf0856b Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 27 Jan 2025 10:48:19 -0600 Subject: [PATCH 041/121] fix: Improve index.html detection in tar archive extraction --- crates/fdev/src/commands.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 0fcc4a300..34f63d6a8 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -101,12 +101,13 @@ async fn put_contract( let mut found_index = false; let decoder = XzDecoder::new(Cursor::new(&archive)); let mut tar = Archive::new(decoder); - for entry in tar.entries()? { - if let Ok(entry) = entry { - if entry.path()?.to_string_lossy() == "index.html" { - found_index = true; - break; - } + let entries = tar.entries()?; + for entry in entries { + let entry = entry?; + let path = entry.path()?; + if path.to_string_lossy() == "index.html" { + found_index = true; + break; } } if !found_index { From b61db45cffa8fdd230a7d8f02eaf586ac8c99b59 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 27 Jan 2025 10:53:41 -0600 Subject: [PATCH 042/121] refactor: Improve index.html detection in tar archive with robust path matching and debug logging --- crates/fdev/src/commands.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 34f63d6a8..f51717325 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -105,7 +105,9 @@ async fn put_contract( for entry in entries { let entry = entry?; let path = entry.path()?; - if path.to_string_lossy() == "index.html" { + tracing::debug!("Found file in archive: {}", path.display()); + if path.file_name().map(|f| f.to_string_lossy()) == Some("index.html".into()) { + tracing::debug!("Found index.html at path: {}", path.display()); found_index = true; break; } From 14806e91338dc3864f200fbbd3f649cf591eb226 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Thu, 30 Jan 2025 14:22:20 -0600 Subject: [PATCH 043/121] format --- crates/fdev/src/build.rs | 2 +- crates/fdev/src/commands.rs | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index 0927d3372..ceafc7cf4 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -1,5 +1,5 @@ use freenet::server::WebApp; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use std::{ collections::HashMap, diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index f51717325..488ebed3b 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -1,13 +1,13 @@ use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc}; use freenet::dev_tool::OperationMode; +use freenet::server::WebApp; use freenet_stdlib::{ client_api::{ClientRequest, ContractRequest, DelegateRequest, WebApi}, prelude::*, }; -use freenet::server::WebApp; -use xz2::read::XzDecoder; use tar::Builder; +use xz2::read::XzDecoder; use crate::config::{BaseConfig, PutConfig, UpdateConfig}; @@ -85,7 +85,7 @@ async fn put_contract( // Read webapp archive let mut archive = vec![]; File::open(webapp_archive)?.read_to_end(&mut archive)?; - + // Read optional metadata let metadata = if let Some(ref metadata_path) = contract_config.webapp_metadata { let mut buf = vec![]; @@ -96,8 +96,8 @@ async fn put_contract( }; // Validate archive has index.html (warning only) - use tar::Archive; use std::io::Cursor; + use tar::Archive; let mut found_index = false; let decoder = XzDecoder::new(Cursor::new(&archive)); let mut tar = Archive::new(decoder); @@ -118,7 +118,11 @@ async fn put_contract( // Create WebApp state let mut archive_builder = Builder::new(Cursor::new(Vec::new())); - archive_builder.append_data(&mut tar::Header::new_gnu(), "archive.tar.xz", &mut std::io::Cursor::new(&archive))?; + archive_builder.append_data( + &mut tar::Header::new_gnu(), + "archive.tar.xz", + &mut std::io::Cursor::new(&archive), + )?; let webapp = WebApp::from_data(metadata, archive_builder)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { From c6ea69f0131ed61e15290904f8d3597644040bdf Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Thu, 30 Jan 2025 14:48:59 -0600 Subject: [PATCH 044/121] hopefully fix lock file --- Cargo.lock | 202 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 116 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 728b8c84a..faf94303d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -493,9 +493,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bytecheck" @@ -699,9 +699,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.26" +version = "4.5.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" +checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" dependencies = [ "clap_builder", "clap_derive", @@ -709,9 +709,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.26" +version = "4.5.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" +checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" dependencies = [ "anstream", "anstyle", @@ -739,9 +739,9 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cmake" -version = "0.1.52" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" +checksum = "e24a03c8b52922d68a1589ad61032f2c1aa5a8158d2aa0d93c6e9534944bbad6" dependencies = [ "cc", ] @@ -815,9 +815,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -1835,10 +1835,22 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets 0.52.6", +] + [[package]] name = "ghash" version = "0.5.1" @@ -1856,7 +1868,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" dependencies = [ "fallible-iterator", - "indexmap 2.7.0", + "indexmap 2.7.1", "stable_deref_trait", ] @@ -1884,7 +1896,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.2.0", - "indexmap 2.7.0", + "indexmap 2.7.1", "slab", "tokio", "tokio-util", @@ -2124,9 +2136,9 @@ checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" [[package]] name = "httparse" -version = "1.9.5" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" [[package]] name = "httpdate" @@ -2176,9 +2188,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes 1.9.0", "futures-channel", @@ -2205,7 +2217,7 @@ dependencies = [ "http 1.2.0", "hyper", "hyper-util", - "rustls 0.23.21", + "rustls 0.23.22", "rustls-pki-types", "tokio", "tokio-rustls 0.26.1", @@ -2441,9 +2453,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -2517,19 +2529,19 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.10.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "is-terminal" -version = "0.4.13" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37" dependencies = [ "hermit-abi 0.4.0", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2889,7 +2901,7 @@ checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -2938,9 +2950,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c" dependencies = [ "libc", "log", @@ -3113,7 +3125,7 @@ dependencies = [ "crc32fast", "flate2", "hashbrown 0.14.5", - "indexmap 2.7.0", + "indexmap 2.7.1", "memchr", "ruzstd", ] @@ -3141,9 +3153,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "f5e534d133a060a3c19daec1eb3e98ec6f4685978834f2dbadfe2ec215bab64e" dependencies = [ "bitflags 2.8.0", "cfg-if", @@ -3167,9 +3179,9 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" @@ -3749,7 +3761,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -3812,7 +3824,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror 1.0.69", ] @@ -3823,7 +3835,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror 2.0.11", ] @@ -3968,7 +3980,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "spin", "untrusted", @@ -3977,14 +3989,14 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b11a153aec4a6ab60795f8ebe2923c597b16b05bb1504377451e705ef1a45323" +checksum = "1e147371c75553e1e2fcdb483944a8540b8438c31426279553b9a8182a9b7b65" dependencies = [ "bytecheck 0.8.0", "bytes 1.9.0", "hashbrown 0.15.2", - "indexmap 2.7.0", + "indexmap 2.7.1", "munge", "ptr_meta 0.3.0", "rancor", @@ -3996,9 +4008,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb382a4d9f53bd5c0be86b10d8179c3f8a14c30bf774ff77096ed6581e35981" +checksum = "246b40ac189af6c675d124b802e8ef6d5246c53e17367ce9501f8f66a81abb7a" dependencies = [ "proc-macro2", "quote", @@ -4049,9 +4061,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.43" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags 2.8.0", "errno", @@ -4074,9 +4086,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.21" +version = "0.23.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" +checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7" dependencies = [ "log", "once_cell", @@ -4107,9 +4119,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" [[package]] name = "rustls-webpki" @@ -4151,9 +4163,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "safe_arch" @@ -4295,9 +4307,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.137" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "itoa", "memchr", @@ -4346,7 +4358,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_derive", "serde_json", @@ -4551,12 +4563,12 @@ dependencies = [ "futures-util", "hashbrown 0.15.2", "hashlink", - "indexmap 2.7.0", + "indexmap 2.7.1", "log", "memchr", "once_cell", "percent-encoding", - "rustls 0.23.21", + "rustls 0.23.22", "rustls-pemfile 2.2.0", "serde", "serde_json", @@ -4746,7 +4758,7 @@ dependencies = [ "atomic", "crossbeam-channel", "futures 0.3.31", - "getrandom", + "getrandom 0.2.15", "parking_lot", "rand", "seahash", @@ -4861,13 +4873,13 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.15.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" dependencies = [ "cfg-if", "fastrand 2.3.0", - "getrandom", + "getrandom 0.3.1", "once_cell", "rustix", "windows-sys 0.59.0", @@ -5078,7 +5090,7 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ - "rustls 0.23.21", + "rustls 0.23.22", "tokio", ] @@ -5136,7 +5148,7 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_spanned", "toml_datetime", @@ -5154,11 +5166,11 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "02a8b472d1a3d7c18e2d61a489aee3453fd9031c33e4f55bd533f4a7adca1bee" dependencies = [ - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_spanned", "toml_datetime", @@ -5451,9 +5463,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" [[package]] name = "unicode-normalization" @@ -5519,7 +5531,7 @@ dependencies = [ "flate2", "log", "once_cell", - "rustls 0.23.21", + "rustls 0.23.22", "rustls-pki-types", "url", "webpki-roots", @@ -5562,9 +5574,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" +checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b" [[package]] name = "valuable" @@ -5615,6 +5627,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasite" version = "0.1.0" @@ -5696,12 +5717,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.223.0" +version = "0.224.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e636076193fa68103e937ac951b5f2f587624097017d764b8984d9c0f149464" +checksum = "b7249cf8cb0c6b9cb42bce90c0a5feb276fbf963fa385ff3d818ab3d90818ed6" dependencies = [ "leb128", - "wasmparser 0.223.0", + "wasmparser 0.224.0", ] [[package]] @@ -5810,9 +5831,9 @@ dependencies = [ "bytecheck 0.6.12", "enum-iterator", "enumset", - "getrandom", + "getrandom 0.2.15", "hex", - "indexmap 2.7.0", + "indexmap 2.7.1", "more-asserts", "rkyv", "sha2", @@ -5835,7 +5856,7 @@ dependencies = [ "dashmap", "enum-iterator", "fnv", - "indexmap 2.7.0", + "indexmap 2.7.1", "lazy_static", "libc", "mach2", @@ -5857,26 +5878,26 @@ dependencies = [ "ahash", "bitflags 2.8.0", "hashbrown 0.14.5", - "indexmap 2.7.0", + "indexmap 2.7.1", "semver", ] [[package]] name = "wasmparser" -version = "0.223.0" +version = "0.224.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5a99faceb1a5a84dd6084ec4bfa4b2ab153b5793b43fd8f58b89232634afc35" +checksum = "65881a664fdd43646b647bb27bf186ab09c05bf56779d40aed4c6dce47d423f5" dependencies = [ "bitflags 2.8.0", - "indexmap 2.7.0", + "indexmap 2.7.1", "semver", ] [[package]] name = "wast" -version = "223.0.0" +version = "224.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59b2ba8a2ff9f06194b7be9524f92e45e70149f4dacc0d0c7ad92b59ac875e4" +checksum = "d722a51e62b669d17e5a9f6bc8ec210178b37d869114355aa46989686c5c6391" dependencies = [ "bumpalo", "leb128", @@ -5887,9 +5908,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.223.0" +version = "1.224.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662786915c427e4918ff01eabb3c4756d4d947cd8f635761526b4cc9da2eaaad" +checksum = "71dece6a7dd5bcbcf8d256606c7fb3faa36286d46bf3f98185407719a5ceede2" dependencies = [ "wast", ] @@ -6182,9 +6203,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.24" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" +checksum = "7e49d2d35d3fad69b39b94139037ecfb4f359f08958b9c11e7315ce770462419" dependencies = [ "memchr", ] @@ -6199,6 +6220,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.8.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -6372,7 +6402,7 @@ dependencies = [ "displaydoc", "flate2", "hmac", - "indexmap 2.7.0", + "indexmap 2.7.1", "lzma-rs", "memchr", "pbkdf2", From 6c46bec75b31c907c8d00ae3a8fa973f8248803e Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Fri, 31 Jan 2025 12:30:13 -0600 Subject: [PATCH 045/121] feat: Add tracing for contract state operations to diagnose state handling issues --- crates/core/src/contract/executor/runtime.rs | 27 +++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index ef09ee55b..59642bd83 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -6,7 +6,23 @@ impl ContractExecutor for Executor { key: ContractKey, return_contract_code: bool, ) -> Result<(Option, Option), ExecutorError> { - match self.perform_contract_get(return_contract_code, key).await { + tracing::debug!( + contract = %key, + return_code = return_contract_code, + "fetching contract" + ); + let result = self.perform_contract_get(return_contract_code, key).await; + if let Ok((Some(ref state), ref code)) = result { + let hash = blake3::hash(state.as_ref()); + tracing::debug!( + contract = %key, + state_size = state.as_ref().len(), + state_hash = %hash, + has_code = code.is_some(), + "fetched contract state" + ); + } + match result { Ok((state, code)) => Ok((state, code)), Err(err) => Err(err), } @@ -19,6 +35,15 @@ impl ContractExecutor for Executor { related_contracts: RelatedContracts<'static>, code: Option, ) -> Result { + if let Either::Left(ref state) = update { + let hash = blake3::hash(state.as_ref()); + tracing::debug!( + contract = %key, + state_size = state.as_ref().len(), + state_hash = %hash, + "upserting contract state" + ); + } let params = if let Some(code) = &code { code.params() } else { From e6262171f82c12c97f9c3a981a94d91ea08f1197 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Fri, 31 Jan 2025 18:59:17 -0600 Subject: [PATCH 046/121] fix: Add trace logging for contract state retrieval error --- crates/core/src/contract/executor/runtime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 59642bd83..00190fc0a 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -341,7 +341,7 @@ impl Executor { state: state.ok_or_else(|| { ExecutorError::request(StdContractError::Get { key, - cause: "contract state not found".into(), + cause: "contract state not found".into(), // Getting this error in the browser but trying to figure out why, can you add trace logging to help debug? AI! }) })?, contract, From ae2993a9759b1ffdaec2975bf2e706316b0a9a83 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Fri, 31 Jan 2025 18:59:24 -0600 Subject: [PATCH 047/121] feat: Add trace logging for contract state not found error --- crates/core/src/contract/executor/runtime.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 00190fc0a..1e0e54b0d 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -339,9 +339,13 @@ impl Executor { Ok((state, contract)) => Ok(ContractResponse::GetResponse { key, state: state.ok_or_else(|| { + tracing::trace!( + contract = %key, + "Contract state not found during get request" + ); ExecutorError::request(StdContractError::Get { key, - cause: "contract state not found".into(), // Getting this error in the browser but trying to figure out why, can you add trace logging to help debug? AI! + cause: "contract state not found".into(), }) })?, contract, From b5f3884b3677eed92c3968da536cbe9948214d68 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Wed, 5 Feb 2025 18:42:17 -0600 Subject: [PATCH 048/121] fix: Add debug comment for contract state retrieval error --- crates/core/src/contract/executor/runtime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 47cf0df89..838aa7f64 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -345,7 +345,7 @@ impl Executor { ); ExecutorError::request(StdContractError::Get { key, - cause: "contract state not found".into(), + cause: "contract state not found".into(), // Getting this error, need to add debug/trace logging to figure out why - most likely I'm using the wrong key - }) })?, contract, From 92356b936ae5ab185b4c141766e9ce759c6ff9fd Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 5 Feb 2025 18:42:23 -0600 Subject: [PATCH 049/121] fix: Improve logging for contract state retrieval errors --- crates/core/src/contract/executor/runtime.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 838aa7f64..7e50ade83 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -339,9 +339,9 @@ impl Executor { Ok((state, contract)) => Ok(ContractResponse::GetResponse { key, state: state.ok_or_else(|| { - tracing::trace!( + tracing::debug!( contract = %key, - "Contract state not found during get request" + "Contract state not found during get request. This could indicate using an incorrect key." ); ExecutorError::request(StdContractError::Get { key, From 052f2218811618fb8d55688c7d8b9c4989f5f877 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 5 Feb 2025 18:42:36 -0600 Subject: [PATCH 050/121] fix: Remove comment about contract state not found error --- crates/core/src/contract/executor/runtime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 7e50ade83..21d6ffd2b 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -345,7 +345,7 @@ impl Executor { ); ExecutorError::request(StdContractError::Get { key, - cause: "contract state not found".into(), // Getting this error, need to add debug/trace logging to figure out why - most likely I'm using the wrong key - + cause: "contract state not found".into(), }) })?, contract, From 2d1defb2b6edb30d2fb1c7be4b509ec882a4a7d4 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Wed, 5 Feb 2025 18:48:50 -0600 Subject: [PATCH 051/121] add debug logging --- crates/core/src/contract/executor/runtime.rs | 3 ++- stdlib | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 21d6ffd2b..7fdbf0966 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -326,6 +326,7 @@ impl Executor { state, related_contracts, } => { + tracing::debug!("putting contract {}", contract.key()); self.perform_contract_put(contract, state, related_contracts) .await } @@ -341,7 +342,7 @@ impl Executor { state: state.ok_or_else(|| { tracing::debug!( contract = %key, - "Contract state not found during get request. This could indicate using an incorrect key." + "Contract state not found during get request." ); ExecutorError::request(StdContractError::Get { key, diff --git a/stdlib b/stdlib index e582de3ed..cc5094d68 160000 --- a/stdlib +++ b/stdlib @@ -1 +1 @@ -Subproject commit e582de3ed49ea102f84fffba68f07dc934ac4d0a +Subproject commit cc5094d6815f2cc534371c940b34602e2279915c From 86b78e7e12f7515665535dc469736e5e62e6f805 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Thu, 6 Feb 2025 10:39:41 -0600 Subject: [PATCH 052/121] refactor: Prepare for improved logging in contract_requests method --- crates/core/src/contract/executor/runtime.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 7fdbf0966..b3226420f 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -313,6 +313,7 @@ impl Executor { } } + // Can you add better trace and debug logging to this function? AI! /// Responde to requests made through any API's from client applications in local mode. pub async fn contract_requests( &mut self, From b48173f83a8d536cd0d91827b3286c6f43b5520c Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 10:39:47 -0600 Subject: [PATCH 053/121] feat: Enhance contract request logging with client context and error details --- crates/core/src/contract/executor/runtime.rs | 42 +++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index b3226420f..7ef12b4c5 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -309,25 +309,50 @@ impl Executor { } Err(RequestError::Disconnect.into()) } - _ => Err(ExecutorError::other(anyhow::anyhow!("not supported"))), + other => { + tracing::warn!( + client = %cli_id, + request = ?other, + "unsupported contract request" + ); + Err(ExecutorError::other(anyhow::anyhow!("not supported"))) + } + }; + + if let Err(ref e) = result { + tracing::error!( + client = %cli_id, + error = %e, + "contract request failed" + ); } + + result } - // Can you add better trace and debug logging to this function? AI! - /// Responde to requests made through any API's from client applications in local mode. + /// Respond to requests made through any API's from client applications in local mode. pub async fn contract_requests( &mut self, req: ContractRequest<'_>, cli_id: ClientId, updates: Option>>, ) -> Response { - match req { + tracing::debug!( + client = %cli_id, + "received contract request" + ); + let result = match req { ContractRequest::Put { contract, state, related_contracts, } => { - tracing::debug!("putting contract {}", contract.key()); + tracing::debug!( + client = %cli_id, + contract = %contract.key(), + state_size = state.as_ref().len(), + "putting contract" + ); self.perform_contract_put(contract, state, related_contracts) .await } @@ -356,7 +381,12 @@ impl Executor { Err(err) => Err(err), }, ContractRequest::Subscribe { key, summary } => { - tracing::debug!("subscribing to contract {key}"); + tracing::debug!( + client = %cli_id, + contract = %key, + has_summary = summary.is_some(), + "subscribing to contract" + ); let updates = updates.ok_or_else(|| { ExecutorError::other(anyhow::anyhow!("missing update channel")) })?; From ed7b967dd3b90eb94b612da2507f60457723e79b Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 10:40:28 -0600 Subject: [PATCH 054/121] fix: Correct match expression syntax and logging in contract request handler --- crates/core/src/contract/executor/runtime.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 7ef12b4c5..d6e8928ea 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -311,23 +311,13 @@ impl Executor { } other => { tracing::warn!( - client = %cli_id, + client = %id, request = ?other, - "unsupported contract request" + "unsupported client request" ); Err(ExecutorError::other(anyhow::anyhow!("not supported"))) } - }; - - if let Err(ref e) = result { - tracing::error!( - client = %cli_id, - error = %e, - "contract request failed" - ); } - - result } /// Respond to requests made through any API's from client applications in local mode. From 5b67c978eda4ea4f188f91004fae46a4f3a5a308 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 10:40:46 -0600 Subject: [PATCH 055/121] fix: Improve error handling and logging in contract_requests method --- crates/core/src/contract/executor/runtime.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index d6e8928ea..7d0764009 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -391,8 +391,25 @@ impl Executor { } .into()) } - _ => Err(ExecutorError::other(anyhow::anyhow!("not supported"))), + other => { + tracing::warn!( + client = %cli_id, + request = ?other, + "unsupported contract request" + ); + Err(ExecutorError::other(anyhow::anyhow!("not supported"))) + } + }; + + if let Err(ref e) = result { + tracing::error!( + client = %cli_id, + error = %e, + "contract request failed" + ); } + + result } pub fn delegate_request( From d25bb88e472add8a68c86c7ff17634560ae62a12 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 12:57:33 -0600 Subject: [PATCH 056/121] feat: Add tracing logs for contract publishing and retrieval --- crates/core/src/contract/executor/runtime.rs | 23 +++++++++++++++++--- crates/fdev/src/commands.rs | 8 ++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 7d0764009..a9c92fd1e 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -748,6 +748,11 @@ impl Executor { return_contract_code: bool, key: ContractKey, ) -> Result<(Option, Option), ExecutorError> { + tracing::debug!( + contract = %key, + return_code = return_contract_code, + "Getting contract" + ); let mut got_contract: Option = None; if return_contract_code { @@ -756,10 +761,22 @@ impl Executor { } } - match self.state_store.get(&key).await { + let state_result = self.state_store.get(&key).await; + tracing::debug!( + contract = %key, + state_found = state_result.is_ok(), + has_contract = got_contract.is_some(), + "Contract get result" + ); + match state_result { Ok(state) => Ok((Some(state), got_contract)), - Err(StateStoreError::MissingContract(_)) => Ok((None, got_contract)), - Err(err) => Err(ExecutorError::request(RequestError::from( + Err(StateStoreError::MissingContract(_)) => { + tracing::warn!(contract = %key, "Contract state not found in store"); + Ok((None, got_contract)) + }, + Err(err) => { + tracing::error!(contract = %key, error = %err, "Failed to get contract state"); + Err(ExecutorError::request(RequestError::from( StdContractError::Get { key, cause: format!("{err}").into(), diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 488ebed3b..dba7fdd4d 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -139,7 +139,13 @@ async fn put_contract( Default::default() }; - println!("Putting contract {}", contract.key()); + let key = contract.key(); + tracing::info!("Publishing contract {key}"); + tracing::debug!( + state_size = state.as_ref().len(), + has_related = !related_contracts.is_empty(), + "Contract details" + ); let request = ContractRequest::Put { contract, state: state.to_vec().into(), From 4591ecb33f6d69173f1d398bcaabc8733de324b5 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 12:57:48 -0600 Subject: [PATCH 057/121] refactor: Fix indentation and add implementation block comment --- crates/core/src/contract/executor/runtime.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index a9c92fd1e..93ada8c74 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -212,6 +212,10 @@ impl ContractExecutor for Executor { } } +impl Executor { + // Private implementation methods +} + impl Executor { pub async fn from_config( config: Arc, @@ -777,11 +781,11 @@ impl Executor { Err(err) => { tracing::error!(contract = %key, error = %err, "Failed to get contract state"); Err(ExecutorError::request(RequestError::from( - StdContractError::Get { - key, - cause: format!("{err}").into(), - }, - ))), + StdContractError::Get { + key, + cause: format!("{err}").into(), + }, + ))), } } From 582ac68fb9c42fae8370350a6356d183a11b0d19 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 13:07:28 -0600 Subject: [PATCH 058/121] fix: Remove extra comma in error handling match arm --- crates/core/src/contract/executor/runtime.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 93ada8c74..532658f57 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -784,8 +784,8 @@ impl Executor { StdContractError::Get { key, cause: format!("{err}").into(), - }, - ))), + } + ))) } } From 9ab6b5ec99f1b7ba585c40758b3f23f4360b4b89 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 13:08:06 -0600 Subject: [PATCH 059/121] fix: Resolve unclosed implementation block in runtime.rs --- crates/core/src/contract/executor/runtime.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 532658f57..223645a8a 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -786,6 +786,7 @@ impl Executor { cause: format!("{err}").into(), } ))) + } } } From 0ca26fa8d3685039e4fdba8d170f4b580e6006c0 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 13:53:13 -0600 Subject: [PATCH 060/121] fix: Add type annotation for related_contracts in commands.rs --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index dba7fdd4d..c853799f5 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -133,7 +133,7 @@ async fn put_contract( tracing::warn!("no state provided for contract, if your contract cannot handle empty state correctly, this will always cause an error."); freenet_stdlib::prelude::State::from(vec![]) }; - let related_contracts = if let Some(_related) = &contract_config.related_contracts { + let related_contracts: freenet_stdlib::prelude::RelatedContracts = if let Some(_related) = &contract_config.related_contracts { todo!("use `related` contracts") } else { Default::default() From 3eac1c43c8a220ae62e81d2c608a282f52d6385e Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 16:15:11 -0600 Subject: [PATCH 061/121] I understand now. Could you confirm the implementation of `RelatedContracts`? Without seeing its definition, I can suggest a few potential fixes: 1. If `RelatedContracts` is a custom type without `is_empty()`: ```rust has_related = related_contracts.contracts().len() > 0, ``` 2. If it's a collection-like type: ```rust has_related = !related_contracts.is_empty(), ``` 3. If it's a struct with a `contracts` method: ```rust has_related = !related_contracts.contracts().is_empty(), ``` To provide the most precise fix, could you show me: 1. The definition of `RelatedContracts` 2. Its implementation or methods This will help me recommend the exact correct solution. --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index c853799f5..f4bb56447 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -143,7 +143,7 @@ async fn put_contract( tracing::info!("Publishing contract {key}"); tracing::debug!( state_size = state.as_ref().len(), - has_related = !related_contracts.is_empty(), + has_related = !related_contracts.contracts().is_empty(), "Contract details" ); let request = ContractRequest::Put { From 6437ac1e2eca3ff7d076f218eaf64fc2fd46da88 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Thu, 6 Feb 2025 16:26:49 -0600 Subject: [PATCH 062/121] fix: Handle missing CARGO_TARGET_DIR in tests with temporary directory --- crates/fdev/src/build.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index ceafc7cf4..3b07ca049 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -143,9 +143,14 @@ fn get_out_lib(work_dir: &Path, cli_config: &BuildToolConfig) -> anyhow::Result< "debug" }; let output_lib = env::var("CARGO_TARGET_DIR") - .inspect_err(|_| { - println!("Missing environment variable `CARGO_TARGET_DIR"); - })? + .unwrap_or_else(|_| { + // For tests, use a temporary directory if CARGO_TARGET_DIR is not set + if cfg!(test) { + env::temp_dir().join("cargo_target") + } else { + panic!("Missing environment variable CARGO_TARGET_DIR") + } + }) .parse::()? .join(target) .join(opt_dir) From e05759a53fcc18f2c99f7ace4fb274dcdf609e55 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 16:26:54 -0600 Subject: [PATCH 063/121] fix: Convert PathBuf to String in fdev build configuration --- crates/fdev/src/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/build.rs b/crates/fdev/src/build.rs index 3b07ca049..3b9060645 100644 --- a/crates/fdev/src/build.rs +++ b/crates/fdev/src/build.rs @@ -146,7 +146,7 @@ fn get_out_lib(work_dir: &Path, cli_config: &BuildToolConfig) -> anyhow::Result< .unwrap_or_else(|_| { // For tests, use a temporary directory if CARGO_TARGET_DIR is not set if cfg!(test) { - env::temp_dir().join("cargo_target") + env::temp_dir().join("cargo_target").to_string_lossy().to_string() } else { panic!("Missing environment variable CARGO_TARGET_DIR") } From 613e191961693cda7e1fca28d41f9ac200cc28b2 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Thu, 6 Feb 2025 20:26:47 -0600 Subject: [PATCH 064/121] refactor: Improve related contracts state check in contract publishing log --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index f4bb56447..503e4d21b 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -143,7 +143,7 @@ async fn put_contract( tracing::info!("Publishing contract {key}"); tracing::debug!( state_size = state.as_ref().len(), - has_related = !related_contracts.contracts().is_empty(), + has_related = related_contracts.states().next().is_some(), // FIXME: Should have a better way to test whether there are related contracts "Contract details" ); let request = ContractRequest::Put { From 574275566cd45706ebd60d95f5714e3aea18af6c Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 20:26:51 -0600 Subject: [PATCH 065/121] feat: Add detailed logging for WebSocket client operations in fdev tool --- crates/fdev/src/commands.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 503e4d21b..c39b16f17 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -152,8 +152,12 @@ async fn put_contract( related_contracts, } .into(); + tracing::debug!("Starting WebSocket client connection"); let mut client = start_api_client(other).await?; - execute_command(request, &mut client).await + tracing::debug!("WebSocket client connected successfully"); + let result = execute_command(request, &mut client).await; + tracing::debug!(success = ?result.is_ok(), "WebSocket client operation complete"); + result } async fn put_delegate( @@ -220,5 +224,8 @@ pub(crate) async fn execute_command( request: ClientRequest<'static>, api_client: &mut WebApi, ) -> anyhow::Result<()> { - v1::execute_command(request, api_client).await + tracing::debug!("Starting execute_command with request: {request}"); + let result = v1::execute_command(request, api_client).await; + tracing::debug!(success = ?result.is_ok(), "Finished execute_command"); + result } From aeeb3984b0ea1187f3d6645161d7391f77f09ce1 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 6 Feb 2025 20:31:49 -0600 Subject: [PATCH 066/121] fix: Improve WebSocket error handling and logging in client-server communication --- crates/core/src/client_events/websocket.rs | 12 ++++++++++-- crates/fdev/src/commands.rs | 14 +++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/crates/core/src/client_events/websocket.rs b/crates/core/src/client_events/websocket.rs index ba6faf8b8..99f961b12 100644 --- a/crates/core/src/client_events/websocket.rs +++ b/crates/core/src/client_events/websocket.rs @@ -212,8 +212,16 @@ async fn websocket_commands( ) -> axum::response::Response { let on_upgrade = move |ws: WebSocket| async move { tracing::debug!(protoc = ?ws.protocol(), "websocket connection established"); - if let Err(error) = websocket_interface(rs.clone(), auth_token, encoding_protoc, ws).await { - tracing::error!("{error}"); + match websocket_interface(rs.clone(), auth_token, encoding_protoc, ws).await { + Ok(_) => { + tracing::debug!("WebSocket interface completed normally"); + } + Err(error) => { + tracing::error!("WebSocket interface error: {}", error); + if let Some(source) = error.source() { + tracing::error!("Caused by: {}", source); + } + } } }; ws.on_upgrade(on_upgrade) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index c39b16f17..0a58ce451 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -225,7 +225,15 @@ pub(crate) async fn execute_command( api_client: &mut WebApi, ) -> anyhow::Result<()> { tracing::debug!("Starting execute_command with request: {request}"); - let result = v1::execute_command(request, api_client).await; - tracing::debug!(success = ?result.is_ok(), "Finished execute_command"); - result + tracing::debug!("Sending request to server and waiting for response..."); + match v1::execute_command(request, api_client).await { + Ok(_) => { + tracing::debug!("Server confirmed successful execution"); + Ok(()) + } + Err(e) => { + tracing::error!("Server returned error: {}", e); + Err(e) + } + } } From a168b69f2926bf48598278a67465007f314f75cc Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 8 Feb 2025 19:34:49 -0600 Subject: [PATCH 067/121] feat: Add detailed debug logging for websocket contract operations --- crates/core/src/client_events/websocket.rs | 84 +++++++++++++++++----- 1 file changed, 66 insertions(+), 18 deletions(-) diff --git a/crates/core/src/client_events/websocket.rs b/crates/core/src/client_events/websocket.rs index 99f961b12..fb0e48f4f 100644 --- a/crates/core/src/client_events/websocket.rs +++ b/crates/core/src/client_events/websocket.rs @@ -366,8 +366,14 @@ async fn process_client_request( encoding_protoc: EncodingProtocol, ) -> Result, Option> { let msg = match msg { - Ok(Message::Binary(data)) => data, - Ok(Message::Text(data)) => data.into_bytes(), + Ok(Message::Binary(data)) => { + tracing::debug!(size = data.len(), "received binary message"); + data + } + Ok(Message::Text(data)) => { + tracing::debug!(size = data.len(), "received text message"); + data.into_bytes() + } Ok(Message::Close(_)) => return Err(None), Ok(Message::Ping(ping)) => return Ok(Some(Message::Pong(ping))), Ok(m) => { @@ -381,12 +387,22 @@ async fn process_client_request( let req = { match encoding_protoc { EncodingProtocol::Flatbuffers => match ClientRequest::try_decode_fbs(&msg) { - Ok(decoded) => decoded.into_owned(), - Err(err) => return Ok(Some(Message::Binary(err.into_fbs_bytes()))), + Ok(decoded) => { + tracing::debug!(protocol = "flatbuffers", "successfully decoded client request"); + decoded.into_owned() + } + Err(err) => { + tracing::error!(error = %err, protocol = "flatbuffers", "failed to decode client request"); + return Ok(Some(Message::Binary(err.into_fbs_bytes()))) + } }, EncodingProtocol::Native => match bincode::deserialize::(&msg) { - Ok(decoded) => decoded.into_owned(), + Ok(decoded) => { + tracing::debug!(protocol = "native", "successfully decoded client request"); + decoded.into_owned() + } Err(err) => { + tracing::error!(error = %err, protocol = "native", "failed to decode client request"); let result_error = bincode::serialize(&Err::( ErrorKind::DeserializationError { cause: format!("{err}").into(), @@ -401,9 +417,32 @@ async fn process_client_request( }; if let ClientRequest::Authenticate { token } = &req { *auth_token = Some(AuthToken::from(token.clone())); + tracing::debug!("client authenticated"); } - tracing::debug!(req = %req, "received client request"); + // Log specific details for contract operations + match &req { + ClientRequest::ContractOp(op) => { + match op { + ContractRequest::Put { contract, state, .. } => { + tracing::debug!( + contract_key = %contract.key(), + state_size = state.as_ref().len(), + "received PUT contract request" + ); + } + ContractRequest::Get { key, return_contract_code } => { + tracing::debug!( + contract_key = %key, + return_code = return_contract_code, + "received GET contract request" + ); + } + _ => tracing::debug!(operation = ?op, "received contract operation request"), + } + } + _ => tracing::debug!(req = %req, "received client request"), + } request_sender .send(ClientConnection::Request { client_id, @@ -426,20 +465,29 @@ async fn process_host_response( debug_assert_eq!(id, client_id); let result = match result { Ok(res) => { - tracing::debug!(response = %res, cli_id = %id, "sending response"); - match res { - HostResponse::ContractResponse(ContractResponse::GetResponse { - key, - contract, - state, - }) => Ok(ContractResponse::GetResponse { - key, - contract, - state, + match &res { + HostResponse::ContractResponse(resp) => { + match resp { + ContractResponse::GetResponse { key, contract, state } => { + tracing::debug!( + contract_key = %key, + has_contract = contract.is_some(), + state_size = state.as_ref().len(), + "sending GET response" + ); + } + ContractResponse::PutResponse { key } => { + tracing::debug!( + contract_key = %key, + "sending PUT response" + ); + } + _ => tracing::debug!(response = %resp, "sending contract response"), + } } - .into()), - other => Ok(other), + _ => tracing::debug!(response = %res, "sending response"), } + Ok(res) } Err(err) => { tracing::debug!(response = %err, cli_id = %id, "sending response error"); From 38432b907415bf1981a3420080c8f553b93ec255 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 8 Feb 2025 19:39:04 -0600 Subject: [PATCH 068/121] fix: Use debug formatting for ContractResponse logging This change replaces the `%` format specifier with `?` for logging `ContractResponse` to use its `Debug` implementation instead of the unimplemented `Display` trait. --- crates/core/src/client_events/websocket.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/client_events/websocket.rs b/crates/core/src/client_events/websocket.rs index fb0e48f4f..86f90aed5 100644 --- a/crates/core/src/client_events/websocket.rs +++ b/crates/core/src/client_events/websocket.rs @@ -482,7 +482,7 @@ async fn process_host_response( "sending PUT response" ); } - _ => tracing::debug!(response = %resp, "sending contract response"), + _ => tracing::debug!(response = ?resp, "sending contract response"), } } _ => tracing::debug!(response = %res, "sending response"), From 9c11f174ae1e3b32572cf4e58942cc88c7b842b6 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 8 Feb 2025 19:47:34 -0600 Subject: [PATCH 069/121] feat: Add detailed logging for contract verification and storage process --- crates/core/src/contract/executor/runtime.rs | 33 ++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 223645a8a..bee379cc7 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -814,6 +814,12 @@ impl Executor { ) -> Result<(), ExecutorError> { let key = trying_container.key(); let params = trying_container.params(); + + tracing::debug!( + contract = %key, + state_size = state.as_ref().len(), + "starting contract verification and storage" + ); const DEPENDENCY_CYCLE_LIMIT_GUARD: usize = 100; let mut iterations = 0; @@ -828,10 +834,21 @@ impl Executor { while iterations < DEPENDENCY_CYCLE_LIMIT_GUARD { if let Some(contract) = trying_contract.take() { + tracing::debug!( + contract = %trying_key, + "storing contract in runtime store" + ); self.runtime .contract_store .store_contract(contract) - .map_err(ExecutorError::other)?; + .map_err(|e| { + tracing::error!( + contract = %trying_key, + error = %e, + "failed to store contract in runtime" + ); + ExecutorError::other(e) + })?; } let result = self @@ -888,10 +905,22 @@ impl Executor { })); } + tracing::debug!( + contract = %trying_key, + state_size = trying_state.as_ref().len(), + "storing contract state" + ); self.state_store .store(trying_key, trying_state.clone(), trying_params.clone()) .await - .map_err(ExecutorError::other)?; + .map_err(|e| { + tracing::error!( + contract = %trying_key, + error = %e, + "failed to store contract state" + ); + ExecutorError::other(e) + })?; if trying_key != original_key { trying_key = original_key; trying_params = original_params.clone(); From aaee36e9e4c325f841bcf722d357c21dbb436e28 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sat, 8 Feb 2025 20:11:05 -0600 Subject: [PATCH 070/121] feat: Enhance websocket and contract verification logging for better debugging --- crates/core/src/client_events/websocket.rs | 21 ++++++++++++++++---- crates/core/src/contract/executor/runtime.rs | 3 +++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/crates/core/src/client_events/websocket.rs b/crates/core/src/client_events/websocket.rs index 86f90aed5..97d8919db 100644 --- a/crates/core/src/client_events/websocket.rs +++ b/crates/core/src/client_events/websocket.rs @@ -233,8 +233,12 @@ async fn websocket_interface( encoding_protoc: EncodingProtocol, ws: WebSocket, ) -> anyhow::Result<()> { + tracing::debug!("starting websocket interface handler"); let (mut response_rx, client_id) = new_client_connection(&request_sender).await?; + tracing::debug!(client_id = %client_id, "client connection established"); + let (mut server_sink, mut client_stream) = ws.split(); + tracing::debug!("websocket stream split for bidirectional communication"); let contract_updates: Arc)>>> = Arc::new(Mutex::new(VecDeque::new())); loop { @@ -374,13 +378,22 @@ async fn process_client_request( tracing::debug!(size = data.len(), "received text message"); data.into_bytes() } - Ok(Message::Close(_)) => return Err(None), - Ok(Message::Ping(ping)) => return Ok(Some(Message::Pong(ping))), + Ok(Message::Close(frame)) => { + tracing::debug!(?frame, "received close frame"); + return Err(None); + } + Ok(Message::Ping(ping)) => { + tracing::debug!("received ping"); + return Ok(Some(Message::Pong(ping))); + } Ok(m) => { - tracing::debug!(msg = ?m, "received random message"); + tracing::debug!(msg = ?m, "received unexpected message type"); return Ok(None); } - Err(err) => return Err(Some(err.into())), + Err(err) => { + tracing::error!(error = %err, "error receiving websocket message"); + return Err(Some(err.into())); + } }; // Try to deserialize the ClientRequest message diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index bee379cc7..98ae4e85e 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -814,10 +814,13 @@ impl Executor { ) -> Result<(), ExecutorError> { let key = trying_container.key(); let params = trying_container.params(); + let state_hash = blake3::hash(state.as_ref()); tracing::debug!( contract = %key, state_size = state.as_ref().len(), + state_hash = %state_hash, + params_size = params.as_ref().len(), "starting contract verification and storage" ); From 54edf458a3cb011dc91a92461ecba5aa5d5ad5f6 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 9 Feb 2025 10:42:32 -0600 Subject: [PATCH 071/121] feat: Add tracing logging comment for HttpGateway implementation --- crates/core/src/server/http_gateway/v1.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/core/src/server/http_gateway/v1.rs b/crates/core/src/server/http_gateway/v1.rs index 3998b7f68..249351ef8 100644 --- a/crates/core/src/server/http_gateway/v1.rs +++ b/crates/core/src/server/http_gateway/v1.rs @@ -1,5 +1,7 @@ use super::*; +// Please add detailed tracing logging to this code, particularly to the `web_home` function. AI! + impl HttpGateway { /// Returns the uninitialized axum router to compose with other routing handling or websockets. pub fn as_router_v1(socket: &SocketAddr) -> (Self, Router) { From e66fbdddc7370022f70a801fe719f790c1087da2 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 10:42:36 -0600 Subject: [PATCH 072/121] feat: Add detailed tracing logging to web_home and web_subpages functions --- crates/core/src/server/http_gateway/v1.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/core/src/server/http_gateway/v1.rs b/crates/core/src/server/http_gateway/v1.rs index 249351ef8..d60a08465 100644 --- a/crates/core/src/server/http_gateway/v1.rs +++ b/crates/core/src/server/http_gateway/v1.rs @@ -1,6 +1,5 @@ use super::*; - -// Please add detailed tracing logging to this code, particularly to the `web_home` function. AI! +use tracing::{debug, info, warn}; impl HttpGateway { /// Returns the uninitialized axum router to compose with other routing handling or websockets. @@ -40,14 +39,18 @@ async fn web_home( Extension(rs): Extension, axum::extract::State(config): axum::extract::State, ) -> Result { + info!("Handling web_home request for contract key: {}", key); use headers::{Header, HeaderMapExt}; + debug!("Checking localhost configuration"); let domain = config .localhost .then_some("localhost") .expect("non-local connections not supported yet"); let token = AuthToken::generate(); + debug!("Generated new auth token"); + info!("Setting up authentication headers and cookie"); let auth_header = headers::Authorization::::name().to_string(); let cookie = cookie::Cookie::build((auth_header, format!("Bearer {}", token.as_str()))) .domain(domain) @@ -59,7 +62,9 @@ async fn web_home( .build(); let token_header = headers::Authorization::bearer(token.as_str()).unwrap(); - let contract_idx = path_handlers::contract_home(key, rs, token).await?; + debug!("Requesting contract home page"); + let contract_idx = path_handlers::contract_home(key.clone(), rs, token).await?; + info!("Successfully retrieved contract home for key: {}", key); let mut response = contract_idx.into_response(); response.headers_mut().typed_insert(token_header); response.headers_mut().insert( @@ -73,7 +78,9 @@ async fn web_home( async fn web_subpages( Path((key, last_path)): Path<(String, String)>, ) -> Result { + info!("Handling web subpage request for contract: {}, path: {}", key, last_path); let full_path: String = format!("/v1/contract/web/{}/{}", key, last_path); + debug!("Constructed full path: {}", full_path); path_handlers::variable_content(key, full_path) .await .map_err(|e| *e) From 2d520e4f96da7295c18a9061a8128889493d0c8b Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 9 Feb 2025 10:46:21 -0600 Subject: [PATCH 073/121] chore: Add comment about adding debug tracing logs in path_handlers --- crates/core/src/server/path_handlers.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index f8f94d83e..3cafc1a1c 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -22,6 +22,7 @@ mod v1; const ALPHABET: &str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +// Please add debug! tracing logs to this file, trying to diagnose an issue with failing to GET a contract after supposedly PUTting it AI! pub(super) async fn contract_home( key: String, request_sender: HttpGatewayRequest, From f521efac18bdea6b35722901f6e1ee0ef34501a9 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 10:46:26 -0600 Subject: [PATCH 074/121] feat: Add debug logging to path_handlers for contract retrieval diagnostics --- crates/core/src/server/path_handlers.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index 3cafc1a1c..d84b82ff5 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -22,18 +22,23 @@ mod v1; const ALPHABET: &str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; -// Please add debug! tracing logs to this file, trying to diagnose an issue with failing to GET a contract after supposedly PUTting it AI! pub(super) async fn contract_home( key: String, request_sender: HttpGatewayRequest, assigned_token: AuthToken, ) -> Result { + debug!("contract_home: Converting string key to ContractKey: {}", key); let key = ContractKey::from_id(key) - .map_err(|err| WebSocketApiError::InvalidParam { - error_cause: format!("{err}"), + .map_err(|err| { + debug!("contract_home: Failed to parse contract key: {}", err); + WebSocketApiError::InvalidParam { + error_cause: format!("{err}"), + } }) .unwrap(); + debug!("contract_home: Successfully parsed contract key"); let (response_sender, mut response_recv) = mpsc::unbounded_channel(); + debug!("contract_home: Sending NewConnection request"); request_sender .send(ClientConnection::NewConnection { callbacks: response_sender, @@ -51,6 +56,7 @@ pub(super) async fn contract_home( error_cause: "Couldn't register new client in the node".into(), }); }; + debug!("contract_home: Sending GET request for contract"); request_sender .send(ClientConnection::Request { client_id, @@ -68,6 +74,7 @@ pub(super) async fn contract_home( error_cause: format!("{err}"), }) .unwrap(); + debug!("contract_home: Waiting for GET response"); let response = match response_recv.recv().await { Some(HostCallbackResult::Result { result: @@ -160,6 +167,7 @@ pub(super) async fn variable_content( key: String, req_path: String, ) -> Result> { + debug!("variable_content: Processing request for key: {}, path: {}", key, req_path); // compose the correct absolute path let key = ContractKey::from_id(key).map_err(|err| WebSocketApiError::InvalidParam { error_cause: format!("{err}"), @@ -188,7 +196,9 @@ pub(super) async fn variable_content( } async fn get_web_body(path: &Path) -> Result { + debug!("get_web_body: Attempting to read index.html from path: {:?}", path); let web_path = path.join("web").join("index.html"); + debug!("get_web_body: Full web path: {:?}", web_path); let mut key_file = File::open(&web_path) .await .map_err(|err| WebSocketApiError::NodeError { From 4a7c466264ca36b32e68584cd7d80923b2ee7cb2 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 9 Feb 2025 10:46:55 -0600 Subject: [PATCH 075/121] refactor: Change log level from info to debug in web_home and web_subpages --- crates/core/src/server/http_gateway/v1.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/core/src/server/http_gateway/v1.rs b/crates/core/src/server/http_gateway/v1.rs index d60a08465..cd249ce05 100644 --- a/crates/core/src/server/http_gateway/v1.rs +++ b/crates/core/src/server/http_gateway/v1.rs @@ -39,7 +39,7 @@ async fn web_home( Extension(rs): Extension, axum::extract::State(config): axum::extract::State, ) -> Result { - info!("Handling web_home request for contract key: {}", key); + debug!("Handling web_home request for contract key: {}", key); use headers::{Header, HeaderMapExt}; debug!("Checking localhost configuration"); @@ -50,7 +50,7 @@ async fn web_home( let token = AuthToken::generate(); debug!("Generated new auth token"); - info!("Setting up authentication headers and cookie"); + debug!("Setting up authentication headers and cookie"); let auth_header = headers::Authorization::::name().to_string(); let cookie = cookie::Cookie::build((auth_header, format!("Bearer {}", token.as_str()))) .domain(domain) @@ -64,7 +64,7 @@ async fn web_home( let token_header = headers::Authorization::bearer(token.as_str()).unwrap(); debug!("Requesting contract home page"); let contract_idx = path_handlers::contract_home(key.clone(), rs, token).await?; - info!("Successfully retrieved contract home for key: {}", key); + debug!("Successfully retrieved contract home for key: {}", key); let mut response = contract_idx.into_response(); response.headers_mut().typed_insert(token_header); response.headers_mut().insert( @@ -78,7 +78,7 @@ async fn web_home( async fn web_subpages( Path((key, last_path)): Path<(String, String)>, ) -> Result { - info!("Handling web subpage request for contract: {}, path: {}", key, last_path); + debug!("Handling web subpage request for contract: {}, path: {}", key, last_path); let full_path: String = format!("/v1/contract/web/{}/{}", key, last_path); debug!("Constructed full path: {}", full_path); path_handlers::variable_content(key, full_path) From 609b3ad10e1ec3d8672204e4ad0f7f452d9c9af5 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 10:47:00 -0600 Subject: [PATCH 076/121] fix: Add missing tracing debug import and remove unused imports --- crates/core/src/server/http_gateway/v1.rs | 2 +- crates/core/src/server/path_handlers.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/core/src/server/http_gateway/v1.rs b/crates/core/src/server/http_gateway/v1.rs index cd249ce05..ad1865500 100644 --- a/crates/core/src/server/http_gateway/v1.rs +++ b/crates/core/src/server/http_gateway/v1.rs @@ -1,5 +1,5 @@ use super::*; -use tracing::{debug, info, warn}; +use tracing::debug; impl HttpGateway { /// Returns the uninitialized axum router to compose with other routing handling or websockets. diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index d84b82ff5..db3b5f6f6 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -11,6 +11,7 @@ use tokio::{fs::File, io::AsyncReadExt, sync::mpsc}; use crate::client_events::AuthToken; +use tracing::debug; use super::{ app_packaging::{WebApp, WebContractError}, errors::WebSocketApiError, From 3f96f31486c1eb8754abb66edfd9517b9feeca53 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 9 Feb 2025 10:53:08 -0600 Subject: [PATCH 077/121] feat: Add placeholder comment for tracing debug logs in WebApp implementation --- crates/core/src/server/app_packaging.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index 02f6ffb7a..385b06f70 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -24,6 +24,7 @@ pub struct WebApp { pub web: Vec, } +// Please add detailed tracing debug! logs to this file AI! impl WebApp { pub fn from_data( metadata: Vec, From 0f5a8f85d7084ae0db26d2ded02bdf196974335c Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 10:53:13 -0600 Subject: [PATCH 078/121] feat: Add detailed tracing debug logs to WebApp operations --- crates/core/src/server/app_packaging.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index 385b06f70..36d2111ce 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -3,6 +3,7 @@ use std::{ io::{Cursor, Read}, path::Path, }; +use tracing::debug; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use tar::{Archive, Builder}; @@ -24,12 +25,12 @@ pub struct WebApp { pub web: Vec, } -// Please add detailed tracing debug! logs to this file AI! impl WebApp { pub fn from_data( metadata: Vec, web: Builder>>, ) -> Result { + debug!("Creating WebApp from metadata ({} bytes)", metadata.len()); let buf = web.into_inner().unwrap().into_inner(); let mut encoder = XzEncoder::new(Cursor::new(buf), 6); let mut compressed = vec![]; @@ -52,6 +53,7 @@ impl WebApp { } pub fn unpack(&mut self, dst: impl AsRef) -> Result<(), WebContractError> { + debug!("Unpacking web content to {:?}", dst.as_ref()); let mut decoded_web = self.decode_web(); decoded_web .unpack(dst) @@ -60,6 +62,7 @@ impl WebApp { } pub fn get_file(&mut self, path: &str) -> Result, WebContractError> { + debug!("Retrieving file from web content: {}", path); let mut decoded_web = self.decode_web(); for e in decoded_web .entries() @@ -81,6 +84,7 @@ impl WebApp { } fn decode_web(&self) -> Archive> { + debug!("Decoding compressed web content ({} bytes)", self.web.len()); let decoder = XzDecoder::new(self.web.as_slice()); Archive::new(decoder) } @@ -90,6 +94,7 @@ impl<'a> TryFrom<&'a [u8]> for WebApp { type Error = WebContractError; fn try_from(state: &'a [u8]) -> Result { + debug!("Attempting to create WebApp from {} bytes of state", state.len()); const MAX_METADATA_SIZE: u64 = 1024; const MAX_WEB_SIZE: u64 = 1024 * 1024 * 100; // Decompose the state and extract the compressed web interface From b3102d542b7edf2c4cb3c66dd841b6aaeaa9bcf6 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 11:34:48 -0600 Subject: [PATCH 079/121] feat: Add #[instrument] macro to improve function tracing and logging --- crates/core/src/server/app_packaging.rs | 5 ++++- crates/core/src/server/http_gateway/v1.rs | 4 +++- crates/core/src/server/path_handlers.rs | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index 36d2111ce..2ed02e6e2 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -3,7 +3,7 @@ use std::{ io::{Cursor, Read}, path::Path, }; -use tracing::debug; +use tracing::{debug, instrument}; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use tar::{Archive, Builder}; @@ -26,6 +26,7 @@ pub struct WebApp { } impl WebApp { + #[instrument(skip(web))] pub fn from_data( metadata: Vec, web: Builder>>, @@ -52,6 +53,7 @@ impl WebApp { Ok(output) } + #[instrument(skip(self))] pub fn unpack(&mut self, dst: impl AsRef) -> Result<(), WebContractError> { debug!("Unpacking web content to {:?}", dst.as_ref()); let mut decoded_web = self.decode_web(); @@ -61,6 +63,7 @@ impl WebApp { Ok(()) } + #[instrument(skip(self))] pub fn get_file(&mut self, path: &str) -> Result, WebContractError> { debug!("Retrieving file from web content: {}", path); let mut decoded_web = self.decode_web(); diff --git a/crates/core/src/server/http_gateway/v1.rs b/crates/core/src/server/http_gateway/v1.rs index ad1865500..7b1a6b689 100644 --- a/crates/core/src/server/http_gateway/v1.rs +++ b/crates/core/src/server/http_gateway/v1.rs @@ -1,5 +1,5 @@ use super::*; -use tracing::debug; +use tracing::{debug, instrument}; impl HttpGateway { /// Returns the uninitialized axum router to compose with other routing handling or websockets. @@ -34,6 +34,7 @@ impl HttpGateway { } } +#[instrument(skip(rs))] async fn web_home( Path(key): Path, Extension(rs): Extension, @@ -75,6 +76,7 @@ async fn web_home( Ok(response) } +#[instrument] async fn web_subpages( Path((key, last_path)): Path<(String, String)>, ) -> Result { diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index db3b5f6f6..b64a73539 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -11,7 +11,7 @@ use tokio::{fs::File, io::AsyncReadExt, sync::mpsc}; use crate::client_events::AuthToken; -use tracing::debug; +use tracing::{debug, instrument}; use super::{ app_packaging::{WebApp, WebContractError}, errors::WebSocketApiError, @@ -23,6 +23,7 @@ mod v1; const ALPHABET: &str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +#[instrument(skip(request_sender))] pub(super) async fn contract_home( key: String, request_sender: HttpGatewayRequest, @@ -164,6 +165,7 @@ pub(super) async fn contract_home( Ok(response) } +#[instrument] pub(super) async fn variable_content( key: String, req_path: String, From ac5975336b103e8806a58d126a8bbd0e0534c5c4 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 11:35:00 -0600 Subject: [PATCH 080/121] feat: Add instrumentation to get_web_body function --- crates/core/src/server/path_handlers.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index b64a73539..92affda79 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -198,6 +198,7 @@ pub(super) async fn variable_content( .map(|r| r.into_response()) } +#[instrument] async fn get_web_body(path: &Path) -> Result { debug!("get_web_body: Attempting to read index.html from path: {:?}", path); let web_path = path.join("web").join("index.html"); From 906ea4edea705a46007ad0ecca90907a5cb553c1 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 11:36:18 -0600 Subject: [PATCH 081/121] fix: Add Debug derive and skip non-Debug parameters in instrumentation --- crates/core/src/server/app_packaging.rs | 2 +- crates/core/src/server/http_gateway.rs | 2 +- crates/core/src/server/http_gateway/v1.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index 2ed02e6e2..90a963bd3 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -53,7 +53,7 @@ impl WebApp { Ok(output) } - #[instrument(skip(self))] + #[instrument(skip(self, dst))] pub fn unpack(&mut self, dst: impl AsRef) -> Result<(), WebContractError> { debug!("Unpacking web content to {:?}", dst.as_ref()); let mut decoded_web = self.decode_web(); diff --git a/crates/core/src/server/http_gateway.rs b/crates/core/src/server/http_gateway.rs index c0b247a0a..4391a7e96 100644 --- a/crates/core/src/server/http_gateway.rs +++ b/crates/core/src/server/http_gateway.rs @@ -48,7 +48,7 @@ impl HttpGateway { } } -#[derive(Clone)] +#[derive(Clone, Debug)] struct Config { localhost: bool, } diff --git a/crates/core/src/server/http_gateway/v1.rs b/crates/core/src/server/http_gateway/v1.rs index 7b1a6b689..5e4f7b23c 100644 --- a/crates/core/src/server/http_gateway/v1.rs +++ b/crates/core/src/server/http_gateway/v1.rs @@ -34,7 +34,7 @@ impl HttpGateway { } } -#[instrument(skip(rs))] +#[instrument(skip(rs, config))] async fn web_home( Path(key): Path, Extension(rs): Extension, From 6a2f78d96802ca7f3d60f69ab7f18a0192d08c4c Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 11:37:44 -0600 Subject: [PATCH 082/121] refactor: Change instrumentation level to debug for tracing --- crates/core/src/server/app_packaging.rs | 6 +++--- crates/core/src/server/http_gateway/v1.rs | 4 ++-- crates/core/src/server/path_handlers.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index 90a963bd3..f493663af 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -26,7 +26,7 @@ pub struct WebApp { } impl WebApp { - #[instrument(skip(web))] + #[instrument(level = "debug", skip(web))] pub fn from_data( metadata: Vec, web: Builder>>, @@ -53,7 +53,7 @@ impl WebApp { Ok(output) } - #[instrument(skip(self, dst))] + #[instrument(level = "debug", skip(self, dst))] pub fn unpack(&mut self, dst: impl AsRef) -> Result<(), WebContractError> { debug!("Unpacking web content to {:?}", dst.as_ref()); let mut decoded_web = self.decode_web(); @@ -63,7 +63,7 @@ impl WebApp { Ok(()) } - #[instrument(skip(self))] + #[instrument(level = "debug", skip(self))] pub fn get_file(&mut self, path: &str) -> Result, WebContractError> { debug!("Retrieving file from web content: {}", path); let mut decoded_web = self.decode_web(); diff --git a/crates/core/src/server/http_gateway/v1.rs b/crates/core/src/server/http_gateway/v1.rs index 5e4f7b23c..fd0b5597d 100644 --- a/crates/core/src/server/http_gateway/v1.rs +++ b/crates/core/src/server/http_gateway/v1.rs @@ -34,7 +34,7 @@ impl HttpGateway { } } -#[instrument(skip(rs, config))] +#[instrument(level = "debug", skip(rs, config))] async fn web_home( Path(key): Path, Extension(rs): Extension, @@ -76,7 +76,7 @@ async fn web_home( Ok(response) } -#[instrument] +#[instrument(level = "debug")] async fn web_subpages( Path((key, last_path)): Path<(String, String)>, ) -> Result { diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index 92affda79..d2f14f981 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -23,7 +23,7 @@ mod v1; const ALPHABET: &str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; -#[instrument(skip(request_sender))] +#[instrument(level = "debug", skip(request_sender))] pub(super) async fn contract_home( key: String, request_sender: HttpGatewayRequest, @@ -165,7 +165,7 @@ pub(super) async fn contract_home( Ok(response) } -#[instrument] +#[instrument(level = "debug")] pub(super) async fn variable_content( key: String, req_path: String, From bd2490f9a848564d0cbeb1b2f112a0cb11cfd02c Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 11:37:59 -0600 Subject: [PATCH 083/121] fix: Update `get_web_body` instrumentation with debug level --- crates/core/src/server/path_handlers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index d2f14f981..d99e490b9 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -198,7 +198,7 @@ pub(super) async fn variable_content( .map(|r| r.into_response()) } -#[instrument] +#[instrument(level = "debug")] async fn get_web_body(path: &Path) -> Result { debug!("get_web_body: Attempting to read index.html from path: {:?}", path); let web_path = path.join("web").join("index.html"); From 64f57675f88b3454d723c9175fc52a909047f48e Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 9 Feb 2025 11:39:41 -0600 Subject: [PATCH 084/121] chore: Add comment for adding tracing instrumentation to HTTP gateway --- crates/core/src/server/http_gateway.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/core/src/server/http_gateway.rs b/crates/core/src/server/http_gateway.rs index 4391a7e96..3f6397c32 100644 --- a/crates/core/src/server/http_gateway.rs +++ b/crates/core/src/server/http_gateway.rs @@ -18,6 +18,8 @@ use super::{errors::WebSocketApiError, path_handlers, AuthToken, ClientConnectio mod v1; +// Please add debug level instrument! tracing to relevant functions in this file to help with debugging AI! + #[derive(Clone)] pub(super) struct HttpGatewayRequest(mpsc::Sender); From 1c48e7a962535aad23e38497d05d2fedceb466f7 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 11:39:46 -0600 Subject: [PATCH 085/121] feat: Add debug-level tracing to HttpGateway functions for improved debugging --- crates/core/src/server/http_gateway.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/core/src/server/http_gateway.rs b/crates/core/src/server/http_gateway.rs index 3f6397c32..ae451eaa1 100644 --- a/crates/core/src/server/http_gateway.rs +++ b/crates/core/src/server/http_gateway.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::net::{IpAddr, SocketAddr}; use axum::extract::Path; +use tracing::instrument; use axum::response::IntoResponse; use axum::routing::get; use axum::{Extension, Router}; @@ -18,8 +19,6 @@ use super::{errors::WebSocketApiError, path_handlers, AuthToken, ClientConnectio mod v1; -// Please add debug level instrument! tracing to relevant functions in this file to help with debugging AI! - #[derive(Clone)] pub(super) struct HttpGatewayRequest(mpsc::Sender); @@ -55,11 +54,13 @@ struct Config { localhost: bool, } +#[instrument(level = "debug")] async fn home() -> axum::response::Response { axum::response::Response::default() } impl ClientEventsProxy for HttpGateway { + #[instrument(level = "debug", skip(self))] fn recv(&mut self) -> BoxFuture, ClientError>> { async move { while let Some(msg) = self.proxy_server_request.recv().await { @@ -92,6 +93,7 @@ impl ClientEventsProxy for HttpGateway { .boxed() } + #[instrument(level = "debug", skip(self))] fn send( &mut self, id: ClientId, From 85661541e60b8b558677c4aa2bc2c774bf4b8be3 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 9 Feb 2025 12:02:39 -0600 Subject: [PATCH 086/121] feat: Add comment suggesting debug tracing for HttpGateway functions --- crates/core/src/server/http_gateway/v1.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/core/src/server/http_gateway/v1.rs b/crates/core/src/server/http_gateway/v1.rs index fd0b5597d..ef58a45c0 100644 --- a/crates/core/src/server/http_gateway/v1.rs +++ b/crates/core/src/server/http_gateway/v1.rs @@ -1,6 +1,8 @@ use super::*; use tracing::{debug, instrument}; +// Please add debug level instrument! tracing to relevant functions in this file to help with debugging AI! + impl HttpGateway { /// Returns the uninitialized axum router to compose with other routing handling or websockets. pub fn as_router_v1(socket: &SocketAddr) -> (Self, Router) { From e10c95fe89b2b706984b46edd9d6b35e70e766a9 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Sun, 9 Feb 2025 12:02:44 -0600 Subject: [PATCH 087/121] feat: Add debug instrumentation to as_router_v1 function --- crates/core/src/server/http_gateway/v1.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/core/src/server/http_gateway/v1.rs b/crates/core/src/server/http_gateway/v1.rs index ef58a45c0..0f6fcefb6 100644 --- a/crates/core/src/server/http_gateway/v1.rs +++ b/crates/core/src/server/http_gateway/v1.rs @@ -1,10 +1,9 @@ use super::*; use tracing::{debug, instrument}; -// Please add debug level instrument! tracing to relevant functions in this file to help with debugging AI! - impl HttpGateway { /// Returns the uninitialized axum router to compose with other routing handling or websockets. + #[instrument(level = "debug")] pub fn as_router_v1(socket: &SocketAddr) -> (Self, Router) { let localhost = match socket.ip() { IpAddr::V4(ip) if ip.is_loopback() => true, From 9ea86e27c66871d3b8388b5b8eba90eeb1ff067b Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 12 Feb 2025 20:57:23 -0600 Subject: [PATCH 088/121] refactor: Optimize webapp archive handling to use pre-compressed input directly --- crates/fdev/src/commands.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 0a58ce451..e8ef597e5 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -82,7 +82,7 @@ async fn put_contract( ContractContainer::try_from((config.code.as_path(), params))? }; let state = if let Some(ref webapp_archive) = contract_config.webapp_archive { - // Read webapp archive + // Read pre-compressed webapp archive let mut archive = vec![]; File::open(webapp_archive)?.read_to_end(&mut archive)?; @@ -95,7 +95,7 @@ async fn put_contract( vec![] }; - // Validate archive has index.html (warning only) + // Validate archive has index.html (warning only) use std::io::Cursor; use tar::Archive; let mut found_index = false; @@ -116,15 +116,9 @@ async fn put_contract( tracing::warn!("Warning: No index.html found at root of webapp archive"); } - // Create WebApp state - let mut archive_builder = Builder::new(Cursor::new(Vec::new())); - archive_builder.append_data( - &mut tar::Header::new_gnu(), - "archive.tar.xz", - &mut std::io::Cursor::new(&archive), - )?; - let webapp = WebApp::from_data(metadata, archive_builder)?; - webapp.pack()?.into() + // Create WebApp state directly from pre-compressed archive + let webapp = WebApp::from_data(metadata, archive)?; + webapp.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; File::open(state_path)?.read_to_end(&mut buf)?; From acfab4a7a4e09c97b8810ccddb579cb18f63d6a1 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 12 Feb 2025 20:58:22 -0600 Subject: [PATCH 089/121] test: Fix WebApp state conversion and remove unused import --- crates/fdev/src/commands.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index e8ef597e5..8ee71d2d9 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -6,7 +6,6 @@ use freenet_stdlib::{ client_api::{ClientRequest, ContractRequest, DelegateRequest, WebApi}, prelude::*, }; -use tar::Builder; use xz2::read::XzDecoder; use crate::config::{BaseConfig, PutConfig, UpdateConfig}; @@ -117,8 +116,8 @@ async fn put_contract( } // Create WebApp state directly from pre-compressed archive - let webapp = WebApp::from_data(metadata, archive)?; - webapp.into() + let webapp = WebApp::from_data(metadata, archive.into_inner().into_inner())?; + webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; File::open(state_path)?.read_to_end(&mut buf)?; From 73f193e025847f25480f18e959a903b394db97e7 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 12 Feb 2025 20:59:31 -0600 Subject: [PATCH 090/121] fix: Correct WebApp creation from archive bytes --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 8ee71d2d9..2803b8459 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -116,7 +116,7 @@ async fn put_contract( } // Create WebApp state directly from pre-compressed archive - let webapp = WebApp::from_data(metadata, archive.into_inner().into_inner())?; + let webapp = WebApp::from_data(metadata, archive)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From 22778ba7312b4c0e8534720d985dd3dd66e5e589 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 12 Feb 2025 21:01:06 -0600 Subject: [PATCH 091/121] feat: Fix WebApp creation by converting archive to tar::Builder --- crates/fdev/src/commands.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 2803b8459..6faa878de 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -1,4 +1,5 @@ -use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc}; +use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc, io::Cursor}; +use tar::Builder; use freenet::dev_tool::OperationMode; use freenet::server::WebApp; @@ -115,8 +116,14 @@ async fn put_contract( tracing::warn!("Warning: No index.html found at root of webapp archive"); } - // Create WebApp state directly from pre-compressed archive - let webapp = WebApp::from_data(metadata, archive)?; + // Create WebApp state from pre-compressed archive + let mut builder = Builder::new(Cursor::new(Vec::new())); + builder.append_data( + &mut tar::Header::new_gnu(), + "archive.tar.xz", + &mut std::io::Cursor::new(&archive), + )?; + let webapp = WebApp::from_data(metadata, builder)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From 7b2081c719c88037881513d8a025066d6d04ea7b Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 12 Feb 2025 21:28:28 -0600 Subject: [PATCH 092/121] feat: Add WebApp method to handle pre-compressed web archives directly --- crates/core/src/server/app_packaging.rs | 13 +++++++++++++ crates/fdev/src/commands.rs | 8 +------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index f493663af..49801a5fe 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -42,6 +42,19 @@ impl WebApp { }) } + #[instrument(level = "debug")] + pub fn from_compressed( + metadata: Vec, + compressed_web: Vec, + ) -> Result { + debug!("Creating WebApp from metadata ({} bytes) and pre-compressed web content ({} bytes)", + metadata.len(), compressed_web.len()); + Ok(Self { + metadata, + web: compressed_web, + }) + } + pub fn pack(mut self) -> std::io::Result> { let mut output = Vec::with_capacity( self.metadata.len() + self.web.len() + (std::mem::size_of::() * 2), diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 6faa878de..386c4633f 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -117,13 +117,7 @@ async fn put_contract( } // Create WebApp state from pre-compressed archive - let mut builder = Builder::new(Cursor::new(Vec::new())); - builder.append_data( - &mut tar::Header::new_gnu(), - "archive.tar.xz", - &mut std::io::Cursor::new(&archive), - )?; - let webapp = WebApp::from_data(metadata, builder)?; + let webapp = WebApp::from_compressed(metadata, archive)?; webapp.pack()?.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; From eb3480bce199cc58ee4aa05933585326ade936c8 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 13 Feb 2025 14:42:39 -0600 Subject: [PATCH 093/121] refactor: Improve debug log message for WebApp creation --- crates/core/src/server/app_packaging.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index 49801a5fe..c0c05b3eb 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -47,7 +47,7 @@ impl WebApp { metadata: Vec, compressed_web: Vec, ) -> Result { - debug!("Creating WebApp from metadata ({} bytes) and pre-compressed web content ({} bytes)", + debug!("Creating WebApp with metadata size {} bytes and pre-compressed web content {} bytes", metadata.len(), compressed_web.len()); Ok(Self { metadata, From 3c63c94c96ddbfd68c9135126f1fb44590be3989 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Thu, 13 Feb 2025 14:44:08 -0600 Subject: [PATCH 094/121] test: Remove tracing instrument from WebApp::from_compressed --- crates/core/src/server/app_packaging.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index c0c05b3eb..188c9fd5a 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -42,7 +42,6 @@ impl WebApp { }) } - #[instrument(level = "debug")] pub fn from_compressed( metadata: Vec, compressed_web: Vec, From c6e05b22eff787176257fddf7581216895a40276 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Fri, 14 Feb 2025 09:48:44 -0600 Subject: [PATCH 095/121] feat: Add detailed logging for metadata and packed state in put_contract() --- crates/fdev/src/commands.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 386c4633f..aac3ecd23 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -117,8 +117,29 @@ async fn put_contract( } // Create WebApp state from pre-compressed archive - let webapp = WebApp::from_compressed(metadata, archive)?; - webapp.pack()?.into() + let webapp = WebApp::from_compressed(metadata.clone(), archive)?; + tracing::info!( + metadata_len = metadata.len(), + "Metadata being packed into WebApp state" + ); + if !metadata.is_empty() { + tracing::info!( + first_32_bytes = format!("{:02x?}", &metadata[..metadata.len().min(32)]), + "First 32 bytes of metadata" + ); + } + let packed = webapp.pack()?; + tracing::info!( + packed_len = packed.len(), + "WebApp state after packing" + ); + if !packed.is_empty() { + tracing::info!( + first_32_bytes = format!("{:02x?}", &packed[..packed.len().min(32)]), + "First 32 bytes of packed state" + ); + } + packed.into() } else if let Some(ref state_path) = contract_config.state { let mut buf = vec![]; File::open(state_path)?.read_to_end(&mut buf)?; From 0b22009adcff4e6a1a01c7127d5cc8e7c9f8d020 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Fri, 14 Feb 2025 15:49:42 -0600 Subject: [PATCH 096/121] refactor: Add debug logging for web archive contents --- crates/core/src/server/app_packaging.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index 188c9fd5a..2d213263a 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -101,7 +101,25 @@ impl WebApp { fn decode_web(&self) -> Archive> { debug!("Decoding compressed web content ({} bytes)", self.web.len()); let decoder = XzDecoder::new(self.web.as_slice()); - Archive::new(decoder) + let archive = Archive::new(decoder); + + // Debug log the archive contents + match archive.entries() { + Ok(entries) => { + debug!("Archive contents:"); + for entry in entries { + if let Ok(entry) = entry { + if let Ok(path) = entry.path() { + debug!(" {}", path.display()); + } + } + } + } + Err(e) => debug!("Failed to read archive entries: {}", e), + } + + // Create a fresh archive since we consumed the entries + Archive::new(XzDecoder::new(self.web.as_slice())) } } From 77baf94a4610b651afd0a1aaa6571a686edc84b3 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Fri, 14 Feb 2025 15:49:59 -0600 Subject: [PATCH 097/121] fix: Make archive mutable to call entries() method --- crates/core/src/server/app_packaging.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/server/app_packaging.rs b/crates/core/src/server/app_packaging.rs index 2d213263a..126c16db7 100644 --- a/crates/core/src/server/app_packaging.rs +++ b/crates/core/src/server/app_packaging.rs @@ -101,7 +101,7 @@ impl WebApp { fn decode_web(&self) -> Archive> { debug!("Decoding compressed web content ({} bytes)", self.web.len()); let decoder = XzDecoder::new(self.web.as_slice()); - let archive = Archive::new(decoder); + let mut archive = Archive::new(decoder); // Debug log the archive contents match archive.entries() { From f7e072df3ce2aab6ce5c57ef99326e32f5d49946 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Mon, 17 Feb 2025 10:17:50 -0600 Subject: [PATCH 098/121] refactor: Replace tracing::info with println for contract publishing log --- crates/fdev/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index aac3ecd23..1ccd16c34 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -155,7 +155,7 @@ async fn put_contract( }; let key = contract.key(); - tracing::info!("Publishing contract {key}"); + println!("Publishing contract {key}"); tracing::debug!( state_size = state.as_ref().len(), has_related = related_contracts.states().next().is_some(), // FIXME: Should have a better way to test whether there are related contracts From a530b17a1629f6f9e83e3545944e1f278fb9813e Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 17 Feb 2025 10:17:55 -0600 Subject: [PATCH 099/121] refactor: Fix tokio-tungstenite version mismatch and remove unused imports --- crates/fdev/src/commands.rs | 3 +-- crates/fdev/src/commands/v1.rs | 4 ++-- crates/fdev/src/wasm_runtime/state/v1.rs | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 1ccd16c34..c5db74e7d 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -1,5 +1,4 @@ -use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc, io::Cursor}; -use tar::Builder; +use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc}; use freenet::dev_tool::OperationMode; use freenet::server::WebApp; diff --git a/crates/fdev/src/commands/v1.rs b/crates/fdev/src/commands/v1.rs index f9970718f..1d87b6a8c 100644 --- a/crates/fdev/src/commands/v1.rs +++ b/crates/fdev/src/commands/v1.rs @@ -15,7 +15,7 @@ pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result OperationMode::Network => SocketAddr::new(address, cfg.port), }; - let (stream, _) = tokio_tungstenite::connect_async(&format!( + let stream = tokio_tungstenite::connect_async(&format!( "ws://{}/v1/contract/command?encodingProtocol=native", target )) @@ -25,7 +25,7 @@ pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result anyhow::anyhow!(format!("fail to connect to the host({target}): {e}")) })?; - Ok(WebApi::start(stream)) + Ok(WebApi::start(stream.0.into())) } pub(super) async fn execute_command( diff --git a/crates/fdev/src/wasm_runtime/state/v1.rs b/crates/fdev/src/wasm_runtime/state/v1.rs index d164cf484..1bb5bb8bf 100644 --- a/crates/fdev/src/wasm_runtime/state/v1.rs +++ b/crates/fdev/src/wasm_runtime/state/v1.rs @@ -3,7 +3,7 @@ use super::*; impl AppState { pub async fn new_v1(config: &ExecutorConfig) -> anyhow::Result { let target: SocketAddr = (config.address, config.port).into(); - let (stream, _) = tokio_tungstenite::connect_async(&format!( + let stream = tokio_tungstenite::connect_async(&format!( "ws://{}/v1/contract/command?encodingProtocol=native", target )) @@ -14,7 +14,7 @@ impl AppState { })?; Ok(AppState { - local_node: Arc::new(RwLock::new(WebApi::start(stream))), + local_node: Arc::new(RwLock::new(WebApi::start(stream.0.into()))), config: config.clone(), }) } From e362fa865addf2c9de414e0d4e86275f413c80b9 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 17 Feb 2025 10:21:24 -0600 Subject: [PATCH 100/121] fix: Remove unnecessary `.into()` conversion for WebSocketStream This commit removes the `.into()` conversion when passing WebSocket streams to `WebApi::start()`, as the conversion was causing type compatibility issues. The changes directly pass the WebSocket stream without attempting to convert it, which resolves the compilation errors in the `fdev` crate. --- crates/fdev/src/commands/v1.rs | 2 +- crates/fdev/src/wasm_runtime/state/v1.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands/v1.rs b/crates/fdev/src/commands/v1.rs index 1d87b6a8c..628da2349 100644 --- a/crates/fdev/src/commands/v1.rs +++ b/crates/fdev/src/commands/v1.rs @@ -25,7 +25,7 @@ pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result anyhow::anyhow!(format!("fail to connect to the host({target}): {e}")) })?; - Ok(WebApi::start(stream.0.into())) + Ok(WebApi::start(stream.0)) } pub(super) async fn execute_command( diff --git a/crates/fdev/src/wasm_runtime/state/v1.rs b/crates/fdev/src/wasm_runtime/state/v1.rs index 1bb5bb8bf..1ccbb1b2e 100644 --- a/crates/fdev/src/wasm_runtime/state/v1.rs +++ b/crates/fdev/src/wasm_runtime/state/v1.rs @@ -14,7 +14,7 @@ impl AppState { })?; Ok(AppState { - local_node: Arc::new(RwLock::new(WebApi::start(stream.0.into()))), + local_node: Arc::new(RwLock::new(WebApi::start(stream.0))), config: config.clone(), }) } From 5483e437eecdde04676f20b059d9fa9f8ab54992 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 17 Feb 2025 10:22:40 -0600 Subject: [PATCH 101/121] fix: Resolve tokio-tungstenite version mismatch using unsafe conversion --- crates/fdev/src/commands/v1.rs | 11 ++++++++++- crates/fdev/src/wasm_runtime/state/v1.rs | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands/v1.rs b/crates/fdev/src/commands/v1.rs index 628da2349..b795324b5 100644 --- a/crates/fdev/src/commands/v1.rs +++ b/crates/fdev/src/commands/v1.rs @@ -1,4 +1,13 @@ use super::*; +use freenet_stdlib::client_api::Connection; + +fn convert_websocket_stream( + stream: tokio_tungstenite::WebSocketStream, +) -> Connection { + // This is safe because the WebSocketStream types are structurally identical + // even though they come from different versions + unsafe { std::mem::transmute(stream) } +} pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result { let mode = cfg.mode; @@ -25,7 +34,7 @@ pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result anyhow::anyhow!(format!("fail to connect to the host({target}): {e}")) })?; - Ok(WebApi::start(stream.0)) + Ok(WebApi::start(convert_websocket_stream(stream.0))) } pub(super) async fn execute_command( diff --git a/crates/fdev/src/wasm_runtime/state/v1.rs b/crates/fdev/src/wasm_runtime/state/v1.rs index 1ccbb1b2e..189a1cd96 100644 --- a/crates/fdev/src/wasm_runtime/state/v1.rs +++ b/crates/fdev/src/wasm_runtime/state/v1.rs @@ -14,7 +14,7 @@ impl AppState { })?; Ok(AppState { - local_node: Arc::new(RwLock::new(WebApi::start(stream.0))), + local_node: Arc::new(RwLock::new(WebApi::start(convert_websocket_stream(stream.0)))), config: config.clone(), }) } From 9aebd2ba15cc7ef8ed9d88dce6a5a2a086b893d8 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 17 Feb 2025 10:27:59 -0600 Subject: [PATCH 102/121] refactor: Move websocket conversion function to shared module and fix imports --- crates/fdev/src/commands/v1.rs | 12 ++---------- crates/fdev/src/wasm_runtime/state/v1.rs | 1 + crates/fdev/src/websocket.rs | 9 +++++++++ 3 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 crates/fdev/src/websocket.rs diff --git a/crates/fdev/src/commands/v1.rs b/crates/fdev/src/commands/v1.rs index b795324b5..353a7aab1 100644 --- a/crates/fdev/src/commands/v1.rs +++ b/crates/fdev/src/commands/v1.rs @@ -1,13 +1,5 @@ use super::*; -use freenet_stdlib::client_api::Connection; - -fn convert_websocket_stream( - stream: tokio_tungstenite::WebSocketStream, -) -> Connection { - // This is safe because the WebSocketStream types are structurally identical - // even though they come from different versions - unsafe { std::mem::transmute(stream) } -} +use freenet_stdlib::prelude::Connection; pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result { let mode = cfg.mode; @@ -34,7 +26,7 @@ pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result anyhow::anyhow!(format!("fail to connect to the host({target}): {e}")) })?; - Ok(WebApi::start(convert_websocket_stream(stream.0))) + Ok(WebApi::start(crate::websocket::convert_websocket_stream(stream.0))) } pub(super) async fn execute_command( diff --git a/crates/fdev/src/wasm_runtime/state/v1.rs b/crates/fdev/src/wasm_runtime/state/v1.rs index 189a1cd96..8cb22d299 100644 --- a/crates/fdev/src/wasm_runtime/state/v1.rs +++ b/crates/fdev/src/wasm_runtime/state/v1.rs @@ -1,4 +1,5 @@ use super::*; +use crate::websocket::convert_websocket_stream; impl AppState { pub async fn new_v1(config: &ExecutorConfig) -> anyhow::Result { diff --git a/crates/fdev/src/websocket.rs b/crates/fdev/src/websocket.rs new file mode 100644 index 000000000..69bd33f21 --- /dev/null +++ b/crates/fdev/src/websocket.rs @@ -0,0 +1,9 @@ +use freenet_stdlib::prelude::Connection; + +pub fn convert_websocket_stream( + stream: tokio_tungstenite::WebSocketStream, +) -> Connection { + // This is safe because the WebSocketStream types are structurally identical + // even though they come from different versions + unsafe { std::mem::transmute(stream) } +} From 202b99cd32941fbe4a276d121d2faf70b470b156 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 17 Feb 2025 10:28:18 -0600 Subject: [PATCH 103/121] fix: Correct Connection import and module resolution in fdev crate --- crates/fdev/src/commands/v1.rs | 2 +- crates/fdev/src/websocket.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fdev/src/commands/v1.rs b/crates/fdev/src/commands/v1.rs index 353a7aab1..68888fdb5 100644 --- a/crates/fdev/src/commands/v1.rs +++ b/crates/fdev/src/commands/v1.rs @@ -1,5 +1,5 @@ use super::*; -use freenet_stdlib::prelude::Connection; +use freenet_stdlib::client_api::Connection; pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result { let mode = cfg.mode; diff --git a/crates/fdev/src/websocket.rs b/crates/fdev/src/websocket.rs index 69bd33f21..cd82c8aea 100644 --- a/crates/fdev/src/websocket.rs +++ b/crates/fdev/src/websocket.rs @@ -1,4 +1,4 @@ -use freenet_stdlib::prelude::Connection; +use freenet_stdlib::client_api::Connection; pub fn convert_websocket_stream( stream: tokio_tungstenite::WebSocketStream, From 0a62acd3531775883535adc27b82bd99f68b93a0 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Mon, 17 Feb 2025 10:30:32 -0600 Subject: [PATCH 104/121] revert first attempt to correct issues with stdlib modifications --- Cargo.lock | 6 +-- apps/freenet-ping/Cargo.lock | 66 +++++++++++++++++++++--- crates/fdev/src/commands.rs | 3 +- crates/fdev/src/commands/v1.rs | 5 +- crates/fdev/src/wasm_runtime/state/v1.rs | 5 +- crates/fdev/src/websocket.rs | 9 ---- stdlib | 2 +- tests/test-contract-1/Cargo.lock | 6 +-- tests/test-contract-2/Cargo.lock | 6 +-- tests/test-contract-metering/Cargo.lock | 4 +- tests/test-delegate-1/Cargo.lock | 6 +-- 11 files changed, 79 insertions(+), 39 deletions(-) delete mode 100644 crates/fdev/src/websocket.rs diff --git a/Cargo.lock b/Cargo.lock index 071188d04..31f9a5737 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1631,7 +1631,7 @@ dependencies = [ [[package]] name = "freenet-macros" -version = "0.0.5" +version = "0.1.0-rc1" dependencies = [ "proc-macro2", "quote", @@ -1677,7 +1677,7 @@ dependencies = [ [[package]] name = "freenet-stdlib" -version = "0.0.8" +version = "0.1.0-rc1" dependencies = [ "arbitrary", "bincode", @@ -1699,7 +1699,7 @@ dependencies = [ "serde_with", "thiserror 1.0.69", "tokio", - "tokio-tungstenite 0.24.0", + "tokio-tungstenite 0.26.1", "tracing", "tracing-subscriber", "wasm-bindgen", diff --git a/apps/freenet-ping/Cargo.lock b/apps/freenet-ping/Cargo.lock index 4b766efca..23e7b4f8a 100644 --- a/apps/freenet-ping/Cargo.lock +++ b/apps/freenet-ping/Cargo.lock @@ -393,7 +393,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "freenet-macros" -version = "0.0.5" +version = "0.1.0-rc1" dependencies = [ "proc-macro2", "quote", @@ -411,7 +411,7 @@ dependencies = [ "futures", "serde_json", "tokio", - "tokio-tungstenite", + "tokio-tungstenite 0.24.0", "tracing", "tracing-subscriber", ] @@ -439,7 +439,7 @@ dependencies = [ [[package]] name = "freenet-stdlib" -version = "0.0.8" +version = "0.1.0-rc1" dependencies = [ "bincode", "blake3", @@ -457,9 +457,9 @@ dependencies = [ "serde_bytes", "serde_json", "serde_with", - "thiserror", + "thiserror 1.0.69", "tokio", - "tokio-tungstenite", + "tokio-tungstenite 0.26.1", "tracing", "tracing-subscriber", "wasm-bindgen", @@ -1179,7 +1179,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl 2.0.11", ] [[package]] @@ -1193,6 +1202,17 @@ dependencies = [ "syn", ] +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -1287,7 +1307,19 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite", + "tungstenite 0.24.0", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4bf6fecd69fcdede0ec680aaf474cdab988f9de6bc73d3758f0160e3b7025a" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.26.1", ] [[package]] @@ -1366,7 +1398,25 @@ dependencies = [ "log", "rand", "sha1", - "thiserror", + "thiserror 1.0.69", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "sha1", + "thiserror 2.0.11", "utf-8", ] diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index c5db74e7d..1ccd16c34 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -1,4 +1,5 @@ -use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc}; +use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc, io::Cursor}; +use tar::Builder; use freenet::dev_tool::OperationMode; use freenet::server::WebApp; diff --git a/crates/fdev/src/commands/v1.rs b/crates/fdev/src/commands/v1.rs index 68888fdb5..f9970718f 100644 --- a/crates/fdev/src/commands/v1.rs +++ b/crates/fdev/src/commands/v1.rs @@ -1,5 +1,4 @@ use super::*; -use freenet_stdlib::client_api::Connection; pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result { let mode = cfg.mode; @@ -16,7 +15,7 @@ pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result OperationMode::Network => SocketAddr::new(address, cfg.port), }; - let stream = tokio_tungstenite::connect_async(&format!( + let (stream, _) = tokio_tungstenite::connect_async(&format!( "ws://{}/v1/contract/command?encodingProtocol=native", target )) @@ -26,7 +25,7 @@ pub(super) async fn start_api_client(cfg: BaseConfig) -> anyhow::Result anyhow::anyhow!(format!("fail to connect to the host({target}): {e}")) })?; - Ok(WebApi::start(crate::websocket::convert_websocket_stream(stream.0))) + Ok(WebApi::start(stream)) } pub(super) async fn execute_command( diff --git a/crates/fdev/src/wasm_runtime/state/v1.rs b/crates/fdev/src/wasm_runtime/state/v1.rs index 8cb22d299..d164cf484 100644 --- a/crates/fdev/src/wasm_runtime/state/v1.rs +++ b/crates/fdev/src/wasm_runtime/state/v1.rs @@ -1,10 +1,9 @@ use super::*; -use crate::websocket::convert_websocket_stream; impl AppState { pub async fn new_v1(config: &ExecutorConfig) -> anyhow::Result { let target: SocketAddr = (config.address, config.port).into(); - let stream = tokio_tungstenite::connect_async(&format!( + let (stream, _) = tokio_tungstenite::connect_async(&format!( "ws://{}/v1/contract/command?encodingProtocol=native", target )) @@ -15,7 +14,7 @@ impl AppState { })?; Ok(AppState { - local_node: Arc::new(RwLock::new(WebApi::start(convert_websocket_stream(stream.0)))), + local_node: Arc::new(RwLock::new(WebApi::start(stream))), config: config.clone(), }) } diff --git a/crates/fdev/src/websocket.rs b/crates/fdev/src/websocket.rs deleted file mode 100644 index cd82c8aea..000000000 --- a/crates/fdev/src/websocket.rs +++ /dev/null @@ -1,9 +0,0 @@ -use freenet_stdlib::client_api::Connection; - -pub fn convert_websocket_stream( - stream: tokio_tungstenite::WebSocketStream, -) -> Connection { - // This is safe because the WebSocketStream types are structurally identical - // even though they come from different versions - unsafe { std::mem::transmute(stream) } -} diff --git a/stdlib b/stdlib index cc5094d68..4d5a2eb8e 160000 --- a/stdlib +++ b/stdlib @@ -1 +1 @@ -Subproject commit cc5094d6815f2cc534371c940b34602e2279915c +Subproject commit 4d5a2eb8e7f9ac7d8535f38d441aaae901504496 diff --git a/tests/test-contract-1/Cargo.lock b/tests/test-contract-1/Cargo.lock index 31caac0d5..ab7f67027 100644 --- a/tests/test-contract-1/Cargo.lock +++ b/tests/test-contract-1/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -236,7 +236,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "freenet-macros" -version = "0.0.5" +version = "0.1.0-rc1" dependencies = [ "proc-macro2", "quote", @@ -245,7 +245,7 @@ dependencies = [ [[package]] name = "freenet-stdlib" -version = "0.0.8" +version = "0.1.0-rc1" dependencies = [ "bincode", "blake3", diff --git a/tests/test-contract-2/Cargo.lock b/tests/test-contract-2/Cargo.lock index 819f1fc7a..c8b2f633c 100644 --- a/tests/test-contract-2/Cargo.lock +++ b/tests/test-contract-2/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -236,7 +236,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "freenet-macros" -version = "0.0.5" +version = "0.1.0-rc1" dependencies = [ "proc-macro2", "quote", @@ -245,7 +245,7 @@ dependencies = [ [[package]] name = "freenet-stdlib" -version = "0.0.8" +version = "0.1.0-rc1" dependencies = [ "bincode", "blake3", diff --git a/tests/test-contract-metering/Cargo.lock b/tests/test-contract-metering/Cargo.lock index 924405b09..543b97d38 100644 --- a/tests/test-contract-metering/Cargo.lock +++ b/tests/test-contract-metering/Cargo.lock @@ -236,7 +236,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "freenet-macros" -version = "0.0.5" +version = "0.1.0-rc1" dependencies = [ "proc-macro2", "quote", @@ -245,7 +245,7 @@ dependencies = [ [[package]] name = "freenet-stdlib" -version = "0.0.8" +version = "0.1.0-rc1" dependencies = [ "bincode", "blake3", diff --git a/tests/test-delegate-1/Cargo.lock b/tests/test-delegate-1/Cargo.lock index 340a7c7f7..97b13a82e 100644 --- a/tests/test-delegate-1/Cargo.lock +++ b/tests/test-delegate-1/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -236,7 +236,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "freenet-macros" -version = "0.0.5" +version = "0.1.0-rc1" dependencies = [ "proc-macro2", "quote", @@ -245,7 +245,7 @@ dependencies = [ [[package]] name = "freenet-stdlib" -version = "0.0.8" +version = "0.1.0-rc1" dependencies = [ "bincode", "blake3", From 4315a4f9dc3ef3372e8bbd0d980a5c6cd3a6ff84 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Mon, 17 Feb 2025 10:34:15 -0600 Subject: [PATCH 105/121] update tokio-tungstenite to bring in line with freenet-stdlib dependency --- Cargo.lock | 4 ++-- apps/freenet-ping/Cargo.lock | 36 +++----------------------------- apps/freenet-ping/app/Cargo.toml | 4 ++-- crates/fdev/Cargo.toml | 2 +- 4 files changed, 8 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31f9a5737..066d85bd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1466,7 +1466,7 @@ dependencies = [ "tar", "thiserror 2.0.11", "tokio", - "tokio-tungstenite 0.24.0", + "tokio-tungstenite 0.26.1", "toml", "tracing", "tracing-subscriber", @@ -1649,7 +1649,7 @@ dependencies = [ "futures 0.3.31", "serde_json", "tokio", - "tokio-tungstenite 0.24.0", + "tokio-tungstenite 0.26.1", "tracing", "tracing-subscriber", ] diff --git a/apps/freenet-ping/Cargo.lock b/apps/freenet-ping/Cargo.lock index 23e7b4f8a..82aaf3015 100644 --- a/apps/freenet-ping/Cargo.lock +++ b/apps/freenet-ping/Cargo.lock @@ -411,7 +411,7 @@ dependencies = [ "futures", "serde_json", "tokio", - "tokio-tungstenite 0.24.0", + "tokio-tungstenite", "tracing", "tracing-subscriber", ] @@ -459,7 +459,7 @@ dependencies = [ "serde_with", "thiserror 1.0.69", "tokio", - "tokio-tungstenite 0.26.1", + "tokio-tungstenite", "tracing", "tracing-subscriber", "wasm-bindgen", @@ -1298,18 +1298,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tokio-tungstenite" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite 0.24.0", -] - [[package]] name = "tokio-tungstenite" version = "0.26.1" @@ -1319,7 +1307,7 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite 0.26.1", + "tungstenite", ] [[package]] @@ -1384,24 +1372,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "tungstenite" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand", - "sha1", - "thiserror 1.0.69", - "utf-8", -] - [[package]] name = "tungstenite" version = "0.26.1" diff --git a/apps/freenet-ping/app/Cargo.toml b/apps/freenet-ping/app/Cargo.toml index eaccd156c..9730102e9 100644 --- a/apps/freenet-ping/app/Cargo.toml +++ b/apps/freenet-ping/app/Cargo.toml @@ -5,9 +5,9 @@ edition = "2021" [dependencies] clap = { version = "4", features = ["derive"] } -futures = "0.3" +futures = "0.3.31" tokio = { version = "1", features = ["full"] } -tokio-tungstenite = "0.24" +tokio-tungstenite = "0.26.1" tracing = { version = "0.1", features = ["log"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } freenet-stdlib = { workspace = true, features = ["net"] } diff --git a/crates/fdev/Cargo.toml b/crates/fdev/Cargo.toml index cf2a50cf5..ecb671c6f 100644 --- a/crates/fdev/Cargo.toml +++ b/crates/fdev/Cargo.toml @@ -29,7 +29,7 @@ semver = { workspace = true } tar = "0.4" thiserror = "2" tokio = { version = "1", features = ["rt-multi-thread", "sync", "macros", "signal", "parking_lot", "process"] } -tokio-tungstenite = "0.24" +tokio-tungstenite = "0.26.1" toml = { version = "0.8", features = ["default", "preserve_order"] } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] } From f300f1e7ed1082451388a2cfa5ed8d0affdae02c Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 17 Feb 2025 15:21:08 -0600 Subject: [PATCH 106/121] feat: Add get-contract-id command to retrieve contract ID without publishing --- crates/fdev/src/config.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/fdev/src/config.rs b/crates/fdev/src/config.rs index 5933e17fc..7d40b6092 100644 --- a/crates/fdev/src/config.rs +++ b/crates/fdev/src/config.rs @@ -48,6 +48,8 @@ pub enum SubCommand { Execute(RunCliConfig), Test(crate::testing::TestConfig), NetworkMetricsServer(crate::network_metrics_server::ServerConfig), + /// Get the contract ID without publishing + GetContractId(crate::commands::GetContractIdConfig), } impl SubCommand { @@ -76,6 +78,7 @@ pub struct RunCliConfig { pub enum NodeCommand { Put(PutConfig), Update(UpdateConfig), + GetContractId(crate::commands::GetContractIdConfig), } /// Updates a contract in the network. From 91425c5229d189e55a0256e2c1fd5fe0b75cf6cb Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 17 Feb 2025 15:30:31 -0600 Subject: [PATCH 107/121] fix: Add support for GetContractId command in fdev CLI --- crates/fdev/src/main.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/fdev/src/main.rs b/crates/fdev/src/main.rs index aa8107c8c..14febe7eb 100644 --- a/crates/fdev/src/main.rs +++ b/crates/fdev/src/main.rs @@ -57,6 +57,9 @@ fn main() -> anyhow::Result<()> { config::NodeCommand::Update(update_config) => { update(update_config, config.additional).await } + config::NodeCommand::GetContractId(get_contract_id_config) => { + commands::get_contract_id(get_contract_id_config).await + } }, SubCommand::Test(test_config) => testing::test_framework(test_config).await, SubCommand::NetworkMetricsServer(server_config) => { @@ -71,6 +74,9 @@ fn main() -> anyhow::Result<()> { query::query(config.additional).await?; Ok(()) } + SubCommand::GetContractId(get_contract_id_config) => { + commands::get_contract_id(get_contract_id_config).await + } }; // todo: make all commands return concrete `thiserror` compatible errors so we can use anyhow r.map_err(|e| anyhow::format_err!(e)) From 8ecdd2ad35b69d409ef4ff154eb5e4e772b66c8c Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Mon, 17 Feb 2025 15:31:22 -0600 Subject: [PATCH 108/121] fix: Add missing contract ID retrieval implementation This commit adds the missing GetContractIdConfig struct and get_contract_id function to the fdev CLI tool, resolving compilation errors related to contract ID retrieval. The implementation allows generating a contract key from a WASM file and optional parameters. --- crates/fdev/src/commands.rs | 41 +++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 1ccd16c34..3d0b6f305 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -1,8 +1,7 @@ -use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc, io::Cursor}; -use tar::Builder; +use std::{fs::File, io::Read, net::SocketAddr, path::PathBuf, sync::Arc}; -use freenet::dev_tool::OperationMode; -use freenet::server::WebApp; +use freenet::{dev_tool::OperationMode, server::WebApp}; +use freenet_stdlib::prelude::{ContractCode, ContractContainer, Parameters, State, WrappedContract, ContractWasmAPIVersion}; use freenet_stdlib::{ client_api::{ClientRequest, ContractRequest, DelegateRequest, WebApi}, prelude::*, @@ -215,6 +214,40 @@ For additional hardening is recommended to use a different cipher and nonce to e execute_command(request, &mut client).await } +#[derive(clap::Parser, Clone, Debug)] +pub(crate) struct GetContractIdConfig { + /// Path to the contract code (WASM file) + #[arg(long)] + pub(crate) code: PathBuf, + + /// Path to the parameters file + #[arg(long)] + pub(crate) parameters: Option, +} + +pub async fn get_contract_id(config: GetContractIdConfig) -> anyhow::Result<()> { + let params = if let Some(params) = &config.parameters { + let mut buf = vec![]; + File::open(params)?.read_to_end(&mut buf)?; + Parameters::from(buf) + } else { + Parameters::from(&[] as &[u8]) + }; + + let contract = if let Ok(raw_code) = ContractCode::load_raw(&config.code) { + let code = ContractCode::from(raw_code.data().to_vec()); + let wrapped = WrappedContract::new(Arc::new(code), params); + let api_version = ContractWasmAPIVersion::V1(wrapped); + ContractContainer::from(api_version) + } else { + ContractContainer::try_from((config.code.as_path(), params))? + }; + + let key = contract.key(); + println!("{key}"); + Ok(()) +} + pub async fn update(config: UpdateConfig, other: BaseConfig) -> anyhow::Result<()> { if config.release { anyhow::bail!("Cannot publish contracts in the network yet"); From 9f522fa057e6684469f3bb9f7f729059edd6ed6d Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Tue, 18 Feb 2025 12:37:10 -0600 Subject: [PATCH 109/121] feat: Add debug logging to variable_content() for filesystem path diagnostics --- crates/core/src/server/path_handlers.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index d99e490b9..0319dc365 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -176,12 +176,18 @@ pub(super) async fn variable_content( error_cause: format!("{err}"), })?; let base_path = contract_web_path(&key); + debug!("variable_content: Base path resolved to: {:?}", base_path); + let req_uri = req_path .parse() .map_err(|err| WebSocketApiError::NodeError { error_cause: format!("{err}"), })?; + debug!("variable_content: Parsed request URI: {:?}", req_uri); + let file_path = base_path.join(get_file_path(req_uri)?); + debug!("variable_content: Full file path to serve: {:?}", file_path); + debug!("variable_content: Checking if file exists: {}", file_path.exists()); // serve the file let mut serve_file = tower_http::services::fs::ServeFile::new(&file_path); From 719d87f1ab76521e4b0b32c3aa7ae1a3dab08457 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Tue, 18 Feb 2025 13:35:44 -0600 Subject: [PATCH 110/121] refactor: Update webapp cache path and index.html location --- crates/core/src/server/path_handlers.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index 0319dc365..850494f28 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -207,7 +207,7 @@ pub(super) async fn variable_content( #[instrument(level = "debug")] async fn get_web_body(path: &Path) -> Result { debug!("get_web_body: Attempting to read index.html from path: {:?}", path); - let web_path = path.join("web").join("index.html"); + let web_path = path.join("index.html"); debug!("get_web_body: Full web path: {:?}", web_path); let mut key_file = File::open(&web_path) .await @@ -230,9 +230,8 @@ async fn get_web_body(path: &Path) -> Result PathBuf { std::env::temp_dir() .join("freenet") - .join("webs") + .join("webapp_cache") .join(key.encoded_contract_id()) - .join("web") } #[inline] From 2d4e46556512f5bb05016d2a8dc240a614a0b02f Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Wed, 19 Feb 2025 10:25:42 -0600 Subject: [PATCH 111/121] wip - river renders and no websocket error, but webapp not updating --- apps/freenet-email-app/web/src/api.rs | 2 +- crates/core/src/server/path_handlers/v1.rs | 6 +++--- stdlib | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/freenet-email-app/web/src/api.rs b/apps/freenet-email-app/web/src/api.rs index b54e6adda..2e1472caa 100644 --- a/apps/freenet-email-app/web/src/api.rs +++ b/apps/freenet-email-app/web/src/api.rs @@ -46,7 +46,7 @@ impl WebApi { fn new() -> Result { use futures::{SinkExt, StreamExt}; let conn = web_sys::WebSocket::new( - "ws://localhost:50509/contract/command?encodingProtocol=native", + "ws://localhost:50509/v1/contract/command?encodingProtocol=native", ) .unwrap(); let (send_host_responses, host_responses) = futures::channel::mpsc::unbounded(); diff --git a/crates/core/src/server/path_handlers/v1.rs b/crates/core/src/server/path_handlers/v1.rs index e8057e3fc..515510fcf 100644 --- a/crates/core/src/server/path_handlers/v1.rs +++ b/crates/core/src/server/path_handlers/v1.rs @@ -19,15 +19,15 @@ pub(super) fn get_file_path(uri: axum::http::Uri) -> Result Date: Wed, 19 Feb 2025 13:34:07 -0600 Subject: [PATCH 112/121] refactor: Add state hash checking for webapp cache updates --- crates/core/src/server/path_handlers.rs | 97 +++++++++++++++++-------- 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index 850494f28..35fde6762 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -90,39 +90,60 @@ pub(super) async fn contract_home( Some(contract) => { let key = contract.key(); let path = contract_web_path(&key); + let state_bytes = state.as_ref(); + let current_hash = hash_state(state_bytes); + let hash_path = state_hash_path(&key); + + let needs_update = match tokio::fs::read(&hash_path).await { + Ok(stored_hash_bytes) if stored_hash_bytes.len() == 8 => { + let stored_hash = u64::from_be_bytes(stored_hash_bytes.try_into().unwrap()); + stored_hash != current_hash + } + _ => true, + }; + + if needs_update { + debug!("State changed or not cached, unpacking webapp"); + let state = State::from(state_bytes); + + fn err( + err: WebContractError, + contract: &ContractContainer, + ) -> WebSocketApiError { + let key = contract.key(); + tracing::error!("{err}"); + WebSocketApiError::InvalidParam { + error_cause: format!("failed unpacking contract: {key}"), + } + } + + // Clear existing cache if any + let _ = tokio::fs::remove_dir_all(&path).await; + tokio::fs::create_dir_all(&path).await.map_err(|e| WebSocketApiError::NodeError { + error_cause: format!("Failed to create cache dir: {e}"), + })?; + + let mut web = WebApp::try_from(state.as_ref()) + .map_err(|e| err(e, &contract)) + .unwrap(); + web.unpack(path).map_err(|e| err(e, &contract)).unwrap(); + + // Store new hash + tokio::fs::write(&hash_path, current_hash.to_be_bytes()).await.map_err(|e| + WebSocketApiError::NodeError { + error_cause: format!("Failed to write state hash: {e}"), + } + )?; + } + let web_body = match get_web_body(&path).await { Ok(b) => b.into_response(), - Err(err) => match err { - WebSocketApiError::NodeError { - error_cause: _cause, - } => { - let state = State::from(state.as_ref()); - - fn err( - err: WebContractError, - contract: &ContractContainer, - ) -> WebSocketApiError { - let key = contract.key(); - tracing::error!("{err}"); - WebSocketApiError::InvalidParam { - error_cause: format!("failed unpacking contract: {key}"), - } - } - - let mut web = WebApp::try_from(state.as_ref()) - .map_err(|e| err(e, &contract)) - .unwrap(); - web.unpack(path).map_err(|e| err(e, &contract)).unwrap(); - let index = web - .get_file("index.html") - .map_err(|e| err(e, &contract)) - .unwrap(); - let index_body = String::from_utf8(index).map_err(|err| { - WebSocketApiError::NodeError { - error_cause: format!("{err}"), - } - })?; - Html(index_body).into_response() + Err(err) => { + tracing::error!("Failed to read webapp after unpacking: {err}"); + return Err(WebSocketApiError::NodeError { + error_cause: format!("Failed to read webapp: {err}"), + }); + } } other => { tracing::error!("{other}"); @@ -234,6 +255,20 @@ fn contract_web_path(key: &ContractKey) -> PathBuf { .join(key.encoded_contract_id()) } +fn hash_state(state: &[u8]) -> u64 { + use std::hash::Hasher; + let mut hasher = ahash::AHasher::default(); + hasher.write(state); + hasher.finish() +} + +fn state_hash_path(key: &ContractKey) -> PathBuf { + std::env::temp_dir() + .join("freenet") + .join("webapp_cache") + .join(format!("{}.hash", key.encoded_contract_id())) +} + #[inline] fn get_file_path(uri: axum::http::Uri) -> Result> { v1::get_file_path(uri) From 6f3dbb539e8094242eb1d43412a8fa458b3cc2a7 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 19 Feb 2025 14:05:37 -0600 Subject: [PATCH 113/121] fix: Improve error handling and remove unnecessary code in contract_home function --- crates/core/src/server/path_handlers.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index 35fde6762..1085c03f7 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -144,12 +144,6 @@ pub(super) async fn contract_home( error_cause: format!("Failed to read webapp: {err}"), }); } - } - other => { - tracing::error!("{other}"); - return Err(other); - } - }, }; web_body } @@ -170,7 +164,12 @@ pub(super) async fn contract_home( error_cause: format!("Contract not found: {key}"), }); } - other => unreachable!("received unexpected node response: {other:?}"), + other => { + tracing::error!("Unexpected node response: {other:?}"); + return Err(WebSocketApiError::NodeError { + error_cause: format!("Unexpected response from node: {other:?}"), + }); + } }; request_sender .send(ClientConnection::Request { From ff7c03358b9800eb1285224b6cdbcc800f892873 Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 19 Feb 2025 15:05:52 -0600 Subject: [PATCH 114/121] feat: Add ahash dependency and fix path borrowing in path_handlers --- crates/core/src/server/path_handlers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index 1085c03f7..d6aaa39d7 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -126,7 +126,7 @@ pub(super) async fn contract_home( let mut web = WebApp::try_from(state.as_ref()) .map_err(|e| err(e, &contract)) .unwrap(); - web.unpack(path).map_err(|e| err(e, &contract)).unwrap(); + web.unpack(&path).map_err(|e| err(e, &contract)).unwrap(); // Store new hash tokio::fs::write(&hash_path, current_hash.to_be_bytes()).await.map_err(|e| From 094f61504a80b950c21efb7d53938c390699d48e Mon Sep 17 00:00:00 2001 From: "Ian Clarke (aider)" Date: Wed, 19 Feb 2025 15:06:14 -0600 Subject: [PATCH 115/121] feat: Add ahash dependency to core Cargo.toml --- crates/core/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 7bcdf03c3..9fe37dca9 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -13,6 +13,7 @@ name = "freenet" path = "src/bin/freenet.rs" [dependencies] +ahash = "0.8" anyhow = "1" arc-swap = "1" asynchronous-codec = "0.7" From afd4303a2b31e39a1b4312e381d015a1563562e9 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Wed, 19 Feb 2025 19:44:11 -0600 Subject: [PATCH 116/121] clean up --- Cargo.lock | 2 ++ crates/core/src/server/path_handlers.rs | 12 ++++-------- crates/core/src/server/path_handlers/v1.rs | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 066d85bd8..09857067e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,6 +59,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -1557,6 +1558,7 @@ name = "freenet" version = "0.1.0-rc1" dependencies = [ "aes-gcm", + "ahash", "anyhow", "arbitrary", "arc-swap", diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index d6aaa39d7..cfd129fee 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -36,8 +36,7 @@ pub(super) async fn contract_home( WebSocketApiError::InvalidParam { error_cause: format!("{err}"), } - }) - .unwrap(); + })?; debug!("contract_home: Successfully parsed contract key"); let (response_sender, mut response_recv) = mpsc::unbounded_channel(); debug!("contract_home: Sending NewConnection request"); @@ -49,8 +48,7 @@ pub(super) async fn contract_home( .await .map_err(|err| WebSocketApiError::NodeError { error_cause: format!("{err}"), - }) - .unwrap(); + })?; let client_id = if let Some(HostCallbackResult::NewId { id }) = response_recv.recv().await { id } else { @@ -74,8 +72,7 @@ pub(super) async fn contract_home( .await .map_err(|err| WebSocketApiError::NodeError { error_cause: format!("{err}"), - }) - .unwrap(); + })?; debug!("contract_home: Waiting for GET response"); let response = match response_recv.recv().await { Some(HostCallbackResult::Result { @@ -180,8 +177,7 @@ pub(super) async fn contract_home( .await .map_err(|err| WebSocketApiError::NodeError { error_cause: format!("{err}"), - }) - .unwrap(); + })?; Ok(response) } diff --git a/crates/core/src/server/path_handlers/v1.rs b/crates/core/src/server/path_handlers/v1.rs index 515510fcf..30f38b9a9 100644 --- a/crates/core/src/server/path_handlers/v1.rs +++ b/crates/core/src/server/path_handlers/v1.rs @@ -21,7 +21,7 @@ pub(super) fn get_file_path(uri: axum::http::Uri) -> Result Date: Wed, 19 Feb 2025 19:45:03 -0600 Subject: [PATCH 117/121] replace more unwraps with ? --- crates/core/src/server/path_handlers.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index cfd129fee..121c99b6c 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -121,9 +121,8 @@ pub(super) async fn contract_home( })?; let mut web = WebApp::try_from(state.as_ref()) - .map_err(|e| err(e, &contract)) - .unwrap(); - web.unpack(&path).map_err(|e| err(e, &contract)).unwrap(); + .map_err(|e| err(e, &contract))?; + web.unpack(&path).map_err(|e| err(e, &contract))?; // Store new hash tokio::fs::write(&hash_path, current_hash.to_be_bytes()).await.map_err(|e| From 8354e9bc0f6f1b42f1552a0c600bae071b24dd5f Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Thu, 6 Mar 2025 13:06:54 -0600 Subject: [PATCH 118/121] wip --- stdlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib b/stdlib index f4b8b0136..036abd8e4 160000 --- a/stdlib +++ b/stdlib @@ -1 +1 @@ -Subproject commit f4b8b0136a8ced9963b78928795703d2b4eedb36 +Subproject commit 036abd8e49dc526d5c73269f6d2f54de3b764492 From 0c7641942bc273d1ada25c74e7e2320dc72922ef Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Thu, 6 Mar 2025 14:24:28 -0600 Subject: [PATCH 119/121] wip --- stdlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib b/stdlib index 036abd8e4..d6706b767 160000 --- a/stdlib +++ b/stdlib @@ -1 +1 @@ -Subproject commit 036abd8e49dc526d5c73269f6d2f54de3b764492 +Subproject commit d6706b767926f6e3ec048fe98502360c5dbfd49f From f57729a7c30c666505f0bb4441d5213ae12892ce Mon Sep 17 00:00:00 2001 From: hsantos Date: Sun, 9 Mar 2025 18:36:11 +0100 Subject: [PATCH 120/121] add and use subscribe flag to contract operations --- Cargo.lock | 2 +- apps/freenet-ping/app/src/main.rs | 2 + crates/core/src/client_events.rs | 8 +- crates/core/src/contract/executor.rs | 3 +- crates/core/src/contract/executor/runtime.rs | 3 + .../core/src/generated/topology_generated.rs | 319 ++++++++++------ crates/core/src/node.rs | 2 +- crates/core/src/operations.rs | 2 +- crates/core/src/operations/get.rs | 186 ++++++--- crates/core/src/operations/put.rs | 359 ++++++++++-------- crates/core/src/server/path_handlers.rs | 1 + crates/core/tests/test_utils/mod.rs | 2 + crates/fdev/src/commands.rs | 1 + crates/fdev/src/config.rs | 4 + crates/fdev/src/wasm_runtime/user_events.rs | 3 + stdlib | 2 +- 16 files changed, 561 insertions(+), 338 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f612d4cd..6de0a89aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1688,7 +1688,7 @@ dependencies = [ [[package]] name = "freenet-stdlib" -version = "0.1.2" +version = "0.1.3" dependencies = [ "arbitrary", "bincode", diff --git a/apps/freenet-ping/app/src/main.rs b/apps/freenet-ping/app/src/main.rs index fe2618191..c7447bd96 100644 --- a/apps/freenet-ping/app/src/main.rs +++ b/apps/freenet-ping/app/src/main.rs @@ -64,6 +64,7 @@ async fn main() -> Result<(), Box contract: container.ok_or("contract not found while putting")?, state: WrappedState::new(serialized), related_contracts: RelatedContracts::new(), + subscribe: false, })) .await?; } else { @@ -71,6 +72,7 @@ async fn main() -> Result<(), Box .send(ClientRequest::ContractOp(ContractRequest::Get { key: contract_key, return_contract_code: true, + subscribe: false, })) .await?; } diff --git a/crates/core/src/client_events.rs b/crates/core/src/client_events.rs index c18ec3646..3e3398152 100644 --- a/crates/core/src/client_events.rs +++ b/crates/core/src/client_events.rs @@ -301,6 +301,7 @@ async fn process_open_request( state, contract, related_contracts, + subscribe, } => { let Some(peer_id) = op_manager.ring.connection_manager.get_peer_key() else { @@ -318,6 +319,7 @@ async fn process_open_request( related_contracts, state, op_manager.ring.max_hops_to_live, + subscribe, ); let op_id = op.id; @@ -387,6 +389,7 @@ async fn process_open_request( ContractRequest::Get { key, return_contract_code, + subscribe, } => { let Some(peer_id) = op_manager.ring.connection_manager.get_peer_key() else { @@ -442,7 +445,7 @@ async fn process_open_request( "Contract not found, starting get op", ); - let op = get::start_op(key, return_contract_code); + let op = get::start_op(key, return_contract_code, subscribe); op_manager .ch_outbound @@ -892,6 +895,7 @@ pub(crate) mod test { contract: contract.clone(), state: WrappedState::new(self.random_byte_vec()), related_contracts: RelatedContracts::new(), + subscribe: true, }; state.existing_contracts.push(contract); if !for_this_peer { @@ -909,6 +913,7 @@ pub(crate) mod test { contract: contract.clone(), state: WrappedState::new(self.random_byte_vec()), related_contracts: RelatedContracts::new(), + subscribe: false, }; tracing::debug!("sending put to an existing contract"); @@ -925,6 +930,7 @@ pub(crate) mod test { let request = ContractRequest::Get { key, return_contract_code: true, + subscribe: false, }; return Some(request.into()); } diff --git a/crates/core/src/contract/executor.rs b/crates/core/src/contract/executor.rs index c1a1fe3af..dd74d85b1 100644 --- a/crates/core/src/contract/executor.rs +++ b/crates/core/src/contract/executor.rs @@ -367,7 +367,7 @@ struct GetContract { impl ComposeNetworkMessage for GetContract { fn initiate_op(self, _op_manager: &OpManager) -> operations::get::GetOp { - operations::get::start_op(self.key, self.return_contract_code) + operations::get::start_op(self.key, self.return_contract_code, false) } async fn resume_op(op: operations::get::GetOp, op_manager: &OpManager) -> Result<(), OpError> { @@ -412,6 +412,7 @@ impl ComposeNetworkMessage for PutContract { related_contracts, state, op_manager.ring.max_hops_to_live, + false, ) } diff --git a/crates/core/src/contract/executor/runtime.rs b/crates/core/src/contract/executor/runtime.rs index 83fe4b555..c742c6ddc 100644 --- a/crates/core/src/contract/executor/runtime.rs +++ b/crates/core/src/contract/executor/runtime.rs @@ -263,6 +263,7 @@ impl Executor { contract, state, related_contracts, + subscribe: false, }, cli_id, None, @@ -307,6 +308,7 @@ impl Executor { contract, state, related_contracts, + .. } => { self.perform_contract_put(contract, state, related_contracts) .await @@ -317,6 +319,7 @@ impl Executor { ContractRequest::Get { key, return_contract_code, + .. } => match self.perform_contract_get(return_contract_code, key).await { Ok((state, contract)) => Ok(ContractResponse::GetResponse { key, diff --git a/crates/core/src/generated/topology_generated.rs b/crates/core/src/generated/topology_generated.rs index 5ff457bb8..16739a06e 100644 --- a/crates/core/src/generated/topology_generated.rs +++ b/crates/core/src/generated/topology_generated.rs @@ -377,8 +377,13 @@ pub mod topology { AddedConnection { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args AddedConnectionArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = AddedConnectionBuilder::new(_fbb); @@ -509,11 +514,11 @@ pub mod topology { } } - pub struct AddedConnectionBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct AddedConnectionBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> AddedConnectionBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> AddedConnectionBuilder<'a, 'b, A> { #[inline] pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -543,8 +548,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> AddedConnectionBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> AddedConnectionBuilder<'a, 'b, A> { let start = _fbb.start_table(); AddedConnectionBuilder { fbb_: _fbb, @@ -597,8 +602,13 @@ pub mod topology { RemovedConnection { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args RemovedConnectionArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = RemovedConnectionBuilder::new(_fbb); @@ -677,11 +687,11 @@ pub mod topology { } } - pub struct RemovedConnectionBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct RemovedConnectionBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> RemovedConnectionBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> RemovedConnectionBuilder<'a, 'b, A> { #[inline] pub fn add_at(&mut self, at: flatbuffers::WIPOffset>) { self.fbb_ @@ -694,8 +704,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> RemovedConnectionBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> RemovedConnectionBuilder<'a, 'b, A> { let start = _fbb.start_table(); RemovedConnectionBuilder { fbb_: _fbb, @@ -744,8 +754,13 @@ pub mod topology { Error { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args ErrorArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = ErrorBuilder::new(_fbb); @@ -797,18 +812,18 @@ pub mod topology { } } - pub struct ErrorBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct ErrorBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> ErrorBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ErrorBuilder<'a, 'b, A> { #[inline] pub fn add_message(&mut self, message: flatbuffers::WIPOffset<&'b str>) { self.fbb_ .push_slot_always::>(Error::VT_MESSAGE, message); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> ErrorBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ErrorBuilder<'a, 'b, A> { let start = _fbb.start_table(); ErrorBuilder { fbb_: _fbb, @@ -857,8 +872,13 @@ pub mod topology { PeerChange { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args PeerChangeArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = PeerChangeBuilder::new(_fbb); @@ -997,11 +1017,11 @@ pub mod topology { } } - pub struct PeerChangeBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct PeerChangeBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> PeerChangeBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PeerChangeBuilder<'a, 'b, A> { #[inline] pub fn add_current_state( &mut self, @@ -1028,7 +1048,9 @@ pub mod topology { .push_slot_always::>(PeerChange::VT_CHANGE, change); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PeerChangeBuilder<'a, 'b> { + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> PeerChangeBuilder<'a, 'b, A> { let start = _fbb.start_table(); PeerChangeBuilder { fbb_: _fbb, @@ -1111,8 +1133,13 @@ pub mod topology { Ok { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args OkArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = OkBuilder::new(_fbb); @@ -1161,18 +1188,18 @@ pub mod topology { } } - pub struct OkBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct OkBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> OkBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> OkBuilder<'a, 'b, A> { #[inline] pub fn add_message(&mut self, message: flatbuffers::WIPOffset<&'b str>) { self.fbb_ .push_slot_always::>(Ok::VT_MESSAGE, message); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> OkBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> OkBuilder<'a, 'b, A> { let start = _fbb.start_table(); OkBuilder { fbb_: _fbb, @@ -1219,8 +1246,13 @@ pub mod topology { ControllerResponse { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args ControllerResponseArgs, ) -> flatbuffers::WIPOffset> { let mut builder = ControllerResponseBuilder::new(_fbb); @@ -1330,11 +1362,11 @@ pub mod topology { } } - pub struct ControllerResponseBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct ControllerResponseBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> ControllerResponseBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ControllerResponseBuilder<'a, 'b, A> { #[inline] pub fn add_response_type(&mut self, response_type: Response) { self.fbb_.push_slot::( @@ -1355,8 +1387,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> ControllerResponseBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> ControllerResponseBuilder<'a, 'b, A> { let start = _fbb.start_table(); ControllerResponseBuilder { fbb_: _fbb, @@ -1435,8 +1467,13 @@ pub mod topology { PutRequest { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args PutRequestArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = PutRequestBuilder::new(_fbb); @@ -1573,11 +1610,11 @@ pub mod topology { } } - pub struct PutRequestBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct PutRequestBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> PutRequestBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PutRequestBuilder<'a, 'b, A> { #[inline] pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -1611,7 +1648,9 @@ pub mod topology { .push_slot::(PutRequest::VT_CONTRACT_LOCATION, contract_location, 0.0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PutRequestBuilder<'a, 'b> { + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> PutRequestBuilder<'a, 'b, A> { let start = _fbb.start_table(); PutRequestBuilder { fbb_: _fbb, @@ -1670,8 +1709,13 @@ pub mod topology { UpdateRequest { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args UpdateRequestArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = UpdateRequestBuilder::new(_fbb); @@ -1778,11 +1822,11 @@ pub mod topology { } } - pub struct UpdateRequestBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct UpdateRequestBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> UpdateRequestBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> UpdateRequestBuilder<'a, 'b, A> { #[inline] pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -1809,8 +1853,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> UpdateRequestBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> UpdateRequestBuilder<'a, 'b, A> { let start = _fbb.start_table(); UpdateRequestBuilder { fbb_: _fbb, @@ -1870,8 +1914,13 @@ pub mod topology { PutSuccess { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args PutSuccessArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = PutSuccessBuilder::new(_fbb); @@ -2008,11 +2057,11 @@ pub mod topology { } } - pub struct PutSuccessBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct PutSuccessBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> PutSuccessBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PutSuccessBuilder<'a, 'b, A> { #[inline] pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -2046,7 +2095,9 @@ pub mod topology { .push_slot::(PutSuccess::VT_CONTRACT_LOCATION, contract_location, 0.0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PutSuccessBuilder<'a, 'b> { + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> PutSuccessBuilder<'a, 'b, A> { let start = _fbb.start_table(); PutSuccessBuilder { fbb_: _fbb, @@ -2106,8 +2157,13 @@ pub mod topology { PutFailure { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args PutFailureArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = PutFailureBuilder::new(_fbb); @@ -2229,11 +2285,11 @@ pub mod topology { } } - pub struct PutFailureBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct PutFailureBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> PutFailureBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PutFailureBuilder<'a, 'b, A> { #[inline] pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -2262,7 +2318,9 @@ pub mod topology { .push_slot::(PutFailure::VT_TIMESTAMP, timestamp, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PutFailureBuilder<'a, 'b> { + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> PutFailureBuilder<'a, 'b, A> { let start = _fbb.start_table(); PutFailureBuilder { fbb_: _fbb, @@ -2321,8 +2379,13 @@ pub mod topology { UpdateSuccess { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args UpdateSuccessArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = UpdateSuccessBuilder::new(_fbb); @@ -2444,11 +2507,11 @@ pub mod topology { } } - pub struct UpdateSuccessBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct UpdateSuccessBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> UpdateSuccessBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> UpdateSuccessBuilder<'a, 'b, A> { #[inline] pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -2480,8 +2543,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> UpdateSuccessBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> UpdateSuccessBuilder<'a, 'b, A> { let start = _fbb.start_table(); UpdateSuccessBuilder { fbb_: _fbb, @@ -2541,8 +2604,13 @@ pub mod topology { UpdateFailure { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args UpdateFailureArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = UpdateFailureBuilder::new(_fbb); @@ -2664,11 +2732,11 @@ pub mod topology { } } - pub struct UpdateFailureBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct UpdateFailureBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> UpdateFailureBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> UpdateFailureBuilder<'a, 'b, A> { #[inline] pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -2700,8 +2768,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> UpdateFailureBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> UpdateFailureBuilder<'a, 'b, A> { let start = _fbb.start_table(); UpdateFailureBuilder { fbb_: _fbb, @@ -2764,8 +2832,13 @@ pub mod topology { BroadcastEmitted { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args BroadcastEmittedArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = BroadcastEmittedBuilder::new(_fbb); @@ -2943,11 +3016,11 @@ pub mod topology { } } - pub struct BroadcastEmittedBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct BroadcastEmittedBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> BroadcastEmittedBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> BroadcastEmittedBuilder<'a, 'b, A> { #[inline] pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -3004,8 +3077,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> BroadcastEmittedBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> BroadcastEmittedBuilder<'a, 'b, A> { let start = _fbb.start_table(); BroadcastEmittedBuilder { fbb_: _fbb, @@ -3069,8 +3142,13 @@ pub mod topology { BroadcastReceived { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args BroadcastReceivedArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = BroadcastReceivedBuilder::new(_fbb); @@ -3213,11 +3291,11 @@ pub mod topology { } } - pub struct BroadcastReceivedBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct BroadcastReceivedBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> BroadcastReceivedBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> BroadcastReceivedBuilder<'a, 'b, A> { #[inline] pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -3259,8 +3337,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> BroadcastReceivedBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> BroadcastReceivedBuilder<'a, 'b, A> { let start = _fbb.start_table(); BroadcastReceivedBuilder { fbb_: _fbb, @@ -3323,8 +3401,13 @@ pub mod topology { GetContract { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args GetContractArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = GetContractBuilder::new(_fbb); @@ -3461,11 +3544,11 @@ pub mod topology { } } - pub struct GetContractBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct GetContractBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> GetContractBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> GetContractBuilder<'a, 'b, A> { #[inline] pub fn add_requester(&mut self, requester: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -3501,7 +3584,9 @@ pub mod topology { .push_slot::(GetContract::VT_TIMESTAMP, timestamp, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> GetContractBuilder<'a, 'b> { + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> GetContractBuilder<'a, 'b, A> { let start = _fbb.start_table(); GetContractBuilder { fbb_: _fbb, @@ -3564,8 +3649,13 @@ pub mod topology { SubscribedToContract { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args SubscribedToContractArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = SubscribedToContractBuilder::new(_fbb); @@ -3730,11 +3820,11 @@ pub mod topology { } } - pub struct SubscribedToContractBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct SubscribedToContractBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> SubscribedToContractBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SubscribedToContractBuilder<'a, 'b, A> { #[inline] pub fn add_requester(&mut self, requester: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -3784,8 +3874,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> SubscribedToContractBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> SubscribedToContractBuilder<'a, 'b, A> { let start = _fbb.start_table(); SubscribedToContractBuilder { fbb_: _fbb, @@ -3846,8 +3936,13 @@ pub mod topology { ContractChange { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create< + 'bldr: 'args, + 'args: 'mut_bldr, + 'mut_bldr, + A: flatbuffers::Allocator + 'bldr, + >( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args ContractChangeArgs<'args>, ) -> flatbuffers::WIPOffset> { let mut builder = ContractChangeBuilder::new(_fbb); @@ -4094,11 +4189,11 @@ pub mod topology { } } - pub struct ContractChangeBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + pub struct ContractChangeBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } - impl<'a: 'b, 'b> ContractChangeBuilder<'a, 'b> { + impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ContractChangeBuilder<'a, 'b, A> { #[inline] pub fn add_contract_id(&mut self, contract_id: flatbuffers::WIPOffset<&'b str>) { self.fbb_.push_slot_always::>( @@ -4121,8 +4216,8 @@ pub mod topology { } #[inline] pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, - ) -> ContractChangeBuilder<'a, 'b> { + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + ) -> ContractChangeBuilder<'a, 'b, A> { let start = _fbb.start_table(); ContractChangeBuilder { fbb_: _fbb, diff --git a/crates/core/src/node.rs b/crates/core/src/node.rs index 9371b3c9c..cc89feb54 100644 --- a/crates/core/src/node.rs +++ b/crates/core/src/node.rs @@ -651,7 +651,7 @@ pub async fn subscribe( match subscribe::request_subscribe(&op_manager, op).await { Err(OpError::ContractError(ContractError::ContractNotFound(key))) => { tracing::info!(%key, "Trying to subscribe to a contract not present, requesting it first"); - let get_op = get::start_op(key, true); + let get_op = get::start_op(key, true, false); if let Err(error) = get::request_get(&op_manager, get_op, HashSet::new()).await { tracing::error!(%key, %error, "Failed getting the contract while previously trying to subscribe; bailing"); return Err(error); diff --git a/crates/core/src/operations.rs b/crates/core/src/operations.rs index a4bce8798..fe72195c2 100644 --- a/crates/core/src/operations.rs +++ b/crates/core/src/operations.rs @@ -320,7 +320,7 @@ async fn start_subscription_request( } if let OpError::ContractError(ContractError::ContractNotFound(key)) = &error { tracing::debug!(%key, "Contract not found, trying to get it first"); - let get_op = get::start_op(*key, true); + let get_op = get::start_op(*key, true, false); if let Err(error) = get::request_get(op_manager, get_op, skip_list).await { tracing::warn!(%error, "Error getting contract"); } diff --git a/crates/core/src/operations/get.rs b/crates/core/src/operations/get.rs index 30e7066cf..7a2c6592a 100644 --- a/crates/core/src/operations/get.rs +++ b/crates/core/src/operations/get.rs @@ -21,7 +21,7 @@ pub(crate) use self::messages::GetMsg; /// Maximum number of retries to get values. const MAX_RETRIES: usize = 10; -pub(crate) fn start_op(key: ContractKey, fetch_contract: bool) -> GetOp { +pub(crate) fn start_op(key: ContractKey, fetch_contract: bool, subscribe: bool) -> GetOp { let contract_location = Location::from(&key); let id = Transaction::new::(); tracing::debug!(tx = %id, "Requesting get contract {key} @ loc({contract_location})"); @@ -29,6 +29,7 @@ pub(crate) fn start_op(key: ContractKey, fetch_contract: bool) -> GetOp { key, id, fetch_contract, + subscribe, }); GetOp { id, @@ -76,13 +77,14 @@ pub(crate) async fn request_get( fetch_contract, key, id, - .. + subscribe, }) => { let new_state = Some(GetState::AwaitingResponse { retries: 0, fetch_contract, requester: None, current_hop: op_manager.ring.max_hops_to_live, + subscribe, }); let msg = GetMsg::RequestGet { @@ -121,6 +123,7 @@ enum GetState { key: ContractKey, id: Transaction, fetch_contract: bool, + subscribe: bool, }, /// Awaiting response from petition. AwaitingResponse { @@ -129,6 +132,7 @@ enum GetState { fetch_contract: bool, retries: usize, current_hop: usize, + subscribe: bool, }, /// Operation completed successfully Finished { key: ContractKey }, @@ -142,11 +146,12 @@ impl Display for GetState { key, id, fetch_contract, + subscribe, } => { write!( f, - "PrepareRequest(key: {}, id: {}, fetch_contract: {})", - key, id, fetch_contract + "PrepareRequest(key: {}, id: {}, fetch_contract: {}, subscribe: {})", + key, id, fetch_contract, subscribe ) } GetState::AwaitingResponse { @@ -154,8 +159,9 @@ impl Display for GetState { fetch_contract, retries, current_hop, + subscribe, } => { - write!(f, "AwaitingResponse(requester: {:?}, fetch_contract: {}, retries: {}, current_hop: {})", requester, fetch_contract, retries, current_hop) + write!(f, "AwaitingResponse(requester: {:?}, fetch_contract: {}, retries: {}, current_hop: {}, subscribe: {})", requester, fetch_contract, retries, current_hop, subscribe) } GetState::Finished { key, .. } => write!(f, "Finished(key: {})", key), } @@ -322,16 +328,24 @@ impl Operation for GetOp { Some(GetState::AwaitingResponse { .. }) )); tracing::info!(tx = %id, %key, target = %target.peer, "Seek contract"); - new_state = self.state; + + // Initialize stats for tracking the operation stats = Some(Box::new(GetStats { contract_location: Location::from(key), next_peer: None, transfer_time: None, first_response_time: None, })); + + // Keep current state + new_state = self.state; + + // Prepare skip list with own peer ID let own_loc = op_manager.ring.connection_manager.own_location(); let mut new_skip_list = skip_list.clone(); new_skip_list.insert(own_loc.peer.clone()); + + // Create seek node message return_msg = Some(GetMsg::SeekNode { key: *key, id: *id, @@ -357,13 +371,16 @@ impl Operation for GetOp { let fetch_contract = *fetch_contract; let this_peer = target.clone(); + // Update stats with next peer if let Some(s) = stats.as_mut() { s.next_peer = Some(this_peer.clone()); } + // Update skip list with current peer let mut new_skip_list = skip_list.clone(); new_skip_list.insert(this_peer.clone().peer); + // Try to get contract from local storage let get_result = op_manager .notify_contract_handler(ContractHandlerEvent::GetQuery { key, @@ -371,7 +388,8 @@ impl Operation for GetOp { }) .await; - let (returned_key, contract, state) = match get_result { + // Process get result + match get_result { Ok(ContractHandlerEvent::GetResponse { key, response: @@ -379,8 +397,57 @@ impl Operation for GetOp { state: Some(state), contract, }), - }) => (key, contract, state), + }) => { + tracing::debug!(tx = %id, "Contract {key} found @ peer {}", target.peer); + + match self.state { + Some(GetState::AwaitingResponse { requester, .. }) => { + if let Some(requester) = requester { + // Forward contract to requester + new_state = None; + tracing::debug!(tx = %id, "Returning contract {} to {}", key, sender.peer); + return_msg = Some(GetMsg::ReturnGet { + id, + key, + value: StoreResponse { + state: Some(state), + contract, + }, + sender: target.clone(), + target: requester, + skip_list: skip_list.clone(), + }); + } else { + // Operation completed for original requester + tracing::debug!( + tx = %id, + "Completed operation, get response received for contract {key}" + ); + new_state = None; + return_msg = None; + } + } + Some(GetState::ReceivedRequest) => { + // Return contract to sender + new_state = None; + tracing::debug!(tx = %id, "Returning contract {} to {}", key, sender.peer); + return_msg = Some(GetMsg::ReturnGet { + id, + key, + value: StoreResponse { + state: Some(state), + contract, + }, + sender: target.clone(), + target: sender.clone(), + skip_list: skip_list.clone(), + }); + } + _ => return Err(OpError::invalid_transition(self.id)), + } + } _ => { + // Contract not found locally, try forwarding to other peers tracing::debug!( tx = %id, %key, @@ -399,52 +466,6 @@ impl Operation for GetOp { ) .await; } - }; - - tracing::debug!(tx = %id, "Contract {returned_key} found @ peer {}", target.peer); - - match self.state { - Some(GetState::AwaitingResponse { requester, .. }) => { - if let Some(requester) = requester { - new_state = None; - tracing::debug!(tx = %id, "Returning contract {} to {}", key, sender.peer); - return_msg = Some(GetMsg::ReturnGet { - id, - key, - value: StoreResponse { - state: Some(state), - contract, - }, - sender: target.clone(), - target: requester, - skip_list: skip_list.clone(), - }); - } else { - tracing::debug!( - tx = %id, - "Completed operation, get response received for contract {key}" - ); - // Completed op - new_state = None; - return_msg = None; - } - } - Some(GetState::ReceivedRequest) => { - new_state = None; - tracing::debug!(tx = %id, "Returning contract {} to {}", key, sender.peer); - return_msg = Some(GetMsg::ReturnGet { - id, - key, - value: StoreResponse { - state: Some(state), - contract, - }, - sender: target.clone(), - target: sender.clone(), - skip_list: skip_list.clone(), - }); - } - _ => return Err(OpError::invalid_transition(self.id)), } } GetMsg::ReturnGet { @@ -455,6 +476,7 @@ impl Operation for GetOp { target, skip_list, } => { + // Handle case where neither contract nor state was found let this_peer = target; tracing::warn!( tx = %id, @@ -471,18 +493,23 @@ impl Operation for GetOp { retries, requester, current_hop, + subscribe, }) => { // todo: register in the stats for the outcome of the op that failed to get a response from this peer if retries < MAX_RETRIES { // no response received from this peer, so skip it in the next iteration + // Update skip list with current peer let mut new_skip_list = skip_list.clone(); new_skip_list.insert(target.peer.clone()); + + // Try to find another peer to query if let Some(target) = op_manager .ring .closest_potentially_caching(key, &new_skip_list) .into_iter() .next() { + // Try with another peer return_msg = Some(GetMsg::SeekNode { id: *id, key: *key, @@ -493,6 +520,7 @@ impl Operation for GetOp { skip_list: new_skip_list.clone(), }); } else if let Some(requester_peer) = requester.clone() { + // No more peers to try, return failure to requester tracing::warn!( tx = %id, %key, @@ -512,6 +540,7 @@ impl Operation for GetOp { skip_list: new_skip_list.clone(), }); } else { + // Original requester, operation failed tracing::error!( tx = %id, "Failed getting a value for contract {}, reached max retries", @@ -524,19 +553,25 @@ impl Operation for GetOp { contract: None, }); } + + // Update state with incremented retries new_state = Some(GetState::AwaitingResponse { retries: retries + 1, fetch_contract, requester, current_hop, + subscribe, }); } else { + // Max retries reached tracing::error!( tx = %id, "Failed getting a value for contract {}, reached max retries", key ); + if let Some(requester_peer) = requester.clone() { + // Return failure to requester tracing::warn!( tx = %id, %key, @@ -557,6 +592,7 @@ impl Operation for GetOp { }); new_state = None; } else { + // Original requester, operation failed tracing::error!( tx = %id, "Failed getting a value for contract {}, reached max retries", @@ -568,6 +604,7 @@ impl Operation for GetOp { fetch_contract, requester, current_hop, + subscribe, }); result = Some(GetResult { key: *key, @@ -578,6 +615,7 @@ impl Operation for GetOp { } } Some(GetState::ReceivedRequest) => { + // Return failure to sender tracing::debug!(tx = %id, "Returning contract {} to {}", key, sender.peer); new_state = None; return_msg = Some(GetMsg::ReturnGet { @@ -611,6 +649,8 @@ impl Operation for GetOp { let key = *key; tracing::info!(tx = %id, %key, "Received get response with state: {:?}", self.state.as_ref().unwrap()); + + // Check if contract is required let require_contract = matches!( self.state, Some(GetState::AwaitingResponse { @@ -619,6 +659,7 @@ impl Operation for GetOp { }) ); + // Get requester from current state let requester = if let Some(GetState::AwaitingResponse { requester, .. }) = self.state.as_ref() { @@ -627,7 +668,7 @@ impl Operation for GetOp { return Err(OpError::UnexpectedOpState); }; - // received a response with a contract value + // Handle case where contract is required but not provided if require_contract && contract.is_none() && requester.is_some() { // no contract, consider this like an error ignoring the incoming update value tracing::warn!( @@ -649,6 +690,7 @@ impl Operation for GetOp { "Contract not received while required, returning response to requester", ); + // Forward error to requester op_manager .notify_op_change( NetMessage::from(GetMsg::ReturnGet { @@ -673,6 +715,7 @@ impl Operation for GetOp { return Err(OpError::StatePushed); } + // Check if this is the original requester let is_original_requester = matches!( self.state, Some(GetState::AwaitingResponse { @@ -680,12 +723,25 @@ impl Operation for GetOp { .. }) ); - let should_subscribe = op_manager.ring.should_seed(&key); - // TODO: In case of original requester, we should check if is possible to cache the contract - let should_put = is_original_requester || should_subscribe; + // Check if subscription was requested + let subscribe_requested = + if let Some(GetState::AwaitingResponse { subscribe, .. }) = &self.state { + *subscribe + } else { + false + }; + + // Determine if we should put the contract locally + let should_put = if is_original_requester && subscribe_requested { + true + } else { + op_manager.ring.should_seed(&key) + }; + + // Put contract locally if needed if should_put { - tracing::debug!(tx = %id, %key, %is_original_requester, %should_subscribe, "Putting contract at executor"); + tracing::debug!(tx = %id, %key, %is_original_requester, %subscribe_requested, "Putting contract at executor"); let res = op_manager .notify_contract_handler(ContractHandlerEvent::PutQuery { key, @@ -694,12 +750,15 @@ impl Operation for GetOp { contract: contract.clone(), }) .await?; + match res { ContractHandlerEvent::PutResponse { new_value: Ok(_) } => { tracing::debug!(tx = %id, %key, "Contract put at executor"); let is_subscribed_contract = op_manager.ring.is_seeding_contract(&key); - if !is_subscribed_contract && should_subscribe { + + // Start subscription if not already seeding + if !is_subscribed_contract { tracing::debug!(tx = %id, %key, peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), "Contract not cached @ peer, caching"); op_manager.ring.seed_contract(key); let mut new_skip_list = skip_list.clone(); @@ -717,9 +776,11 @@ impl Operation for GetOp { new_value: Err(err), } => { if is_original_requester { + // Original requester, return error tracing::debug!(tx = %id, error = %err, "Failed put at executor"); return Err(OpError::ExecutorError(err)); } else { + // Forward error to requester let mut new_skip_list = skip_list.clone(); new_skip_list.insert(sender.peer.clone()); @@ -761,10 +822,12 @@ impl Operation for GetOp { } } + // Process based on current state match self.state { Some(GetState::AwaitingResponse { requester: None, .. }) => { + // Original requester, operation completed successfully tracing::info!(tx = %id, %key, "Get response received for contract at original requester"); new_state = Some(GetState::Finished { key }); return_msg = None; @@ -778,6 +841,7 @@ impl Operation for GetOp { requester: Some(requester), .. }) => { + // Forward response to requester tracing::info!(tx = %id, %key, "Get response received for contract at hop peer"); new_state = None; return_msg = Some(GetMsg::ReturnGet { @@ -799,6 +863,7 @@ impl Operation for GetOp { }); } Some(GetState::ReceivedRequest) => { + // Return response to sender tracing::info!(tx = %id, "Returning contract {} to {}", key, sender.peer); new_state = None; return_msg = Some(GetMsg::ReturnGet { @@ -907,6 +972,7 @@ async fn try_forward_or_return( retries: 0, fetch_contract, current_hop: new_htl, + subscribe: false, }), Some(GetMsg::SeekNode { id, diff --git a/crates/core/src/operations/put.rs b/crates/core/src/operations/put.rs index 6888fc7ae..c0247526e 100644 --- a/crates/core/src/operations/put.rs +++ b/crates/core/src/operations/put.rs @@ -143,9 +143,10 @@ impl Operation for PutOp { htl, target, } => { + // Get the contract key and own location + let key = contract.key(); let sender = op_manager.ring.connection_manager.own_location(); - let key = contract.key(); tracing::info!( "Requesting put for contract {} from {} to {}", key, @@ -153,6 +154,7 @@ impl Operation for PutOp { target.peer ); + // Create a SeekNode message to find the target node // fixme: this node should filter out incoming redundant puts since is the one initiating the request return_msg = Some(PutMsg::SeekNode { id: *id, @@ -164,7 +166,7 @@ impl Operation for PutOp { htl: *htl, }); - // no changes to state yet, still in AwaitResponse state + // No changes to state yet, still in AwaitResponse state new_state = self.state; } PutMsg::SeekNode { @@ -176,23 +178,49 @@ impl Operation for PutOp { target, sender, } => { + // Get the contract key and check if we should handle it let key = contract.key(); - let mut is_subscribed_contract = op_manager.ring.is_seeding_contract(&key); + let is_subscribed_contract = op_manager.ring.is_seeding_contract(&key); let should_seed = op_manager.ring.should_seed(&key); + let should_handle_locally = !is_subscribed_contract && should_seed; tracing::debug!( tx = %id, %key, target = %target.peer, sender = %sender.peer, - "Puttting contract at target peer", + "Putting contract at target peer", ); - let mut already_put = false; + // Determine if this is the last hop or if we should forward + let last_hop = if let Some(new_htl) = htl.checked_sub(1) { + // Forward changes to nodes closer to the contract location + forward_put( + op_manager, + conn_manager, + contract, + value.clone(), + *id, + new_htl, + HashSet::from([sender.peer.clone()]), + ) + .await + } else { + // Last hop, no more forwarding + true + }; + + // Handle local storage and subscription if needed + if should_handle_locally { + // Store contract locally + tracing::debug!( + tx = %id, + %key, + peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), + "Caching contract locally as it's not already seeded" + ); - if should_seed { tracing::debug!(tx = %id, "Attempting contract value put"); - put_contract( op_manager, key, @@ -209,67 +237,25 @@ impl Operation for PutOp { target.location ); - already_put = true; - } - - if !is_subscribed_contract { + // Start subscription let mut skip_list = HashSet::new(); skip_list.insert(sender.peer.clone()); - skip_list.insert(target.peer.clone()); + + // Add target to skip list if not the last hop + if !last_hop { + skip_list.insert(target.peer.clone()); + } + super::start_subscription_request(op_manager, key, false, skip_list).await; - // FIXME: we start subscription request, but that does not mean we are already seeding op_manager.ring.seed_contract(key); - is_subscribed_contract = true; - } - let last_hop = if let Some(new_htl) = htl.checked_sub(1) { - // forward changes in the contract to nodes closer to the contract location, if possible - forward_put( - op_manager, - conn_manager, - contract, - value.clone(), - *id, - new_htl, - HashSet::from([sender.peer.clone()]), - ) - .await - } else { - // should put in this location, no hops left true + } else { + false }; - if last_hop && !is_subscribed_contract { - tracing::debug!( - tx = %id, - %key, - peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), - "Caching contract locally as it's not already seeded" - ); - - if should_seed && !is_subscribed_contract { - let mut skip_list = HashSet::new(); - skip_list.insert(sender.peer.clone()); - super::start_subscription_request(op_manager, key, false, skip_list) - .await; - // FIXME: we start subscription request, but that does not mean we are already seeding - op_manager.ring.seed_contract(key); - } - - if !already_put { - put_contract( - op_manager, - key, - value.clone(), - related_contracts.clone(), - contract, - ) - .await?; - } - } - + // Broadcast changes to subscribers let broadcast_to = op_manager.get_broadcast_targets(&key, &sender.peer); - match try_to_broadcast( *id, last_hop, @@ -296,10 +282,12 @@ impl Operation for PutOp { sender, .. } => { + // Get own location let target = op_manager.ring.connection_manager.own_location(); - tracing::debug!("Attempting contract value update"); - let new_value = put_contract( + // Update the contract locally + tracing::debug!(tx = %id, %key, "Attempting contract value update"); + let updated_value = put_contract( op_manager, *key, new_value.clone(), @@ -307,15 +295,18 @@ impl Operation for PutOp { contract, ) .await?; - tracing::debug!("Contract successfully updated"); + tracing::debug!(tx = %id, %key, "Contract successfully updated"); + // Broadcast changes to subscribers let broadcast_to = op_manager.get_broadcast_targets(key, &sender.peer); tracing::debug!( - "Successfully updated a value for contract {} @ {:?}", - key, - target.location + tx = %id, + %key, + location = ?target.location, + "Successfully updated contract value" ); + // Try to broadcast the changes match try_to_broadcast( *id, false, @@ -323,7 +314,7 @@ impl Operation for PutOp { self.state, (broadcast_to, sender.clone()), *key, - (contract.clone(), new_value), + (contract.clone(), updated_value), ) .await { @@ -336,17 +327,19 @@ impl Operation for PutOp { } PutMsg::Broadcasting { id, - broadcast_to, broadcasted_to, + broadcast_to, key, new_value, contract, upstream, .. } => { + // Get own location and initialize counter let sender = op_manager.ring.connection_manager.own_location(); let mut broadcasted_to = *broadcasted_to; + // Broadcast to all peers in parallel let mut broadcasting = Vec::with_capacity(broadcast_to.len()); for peer in broadcast_to.iter() { let msg = PutMsg::BroadcastTo { @@ -360,6 +353,8 @@ impl Operation for PutOp { let f = conn_manager.send(&peer.peer, msg.into()); broadcasting.push(f); } + + // Collect errors from broadcasting let error_futures = futures::future::join_all(broadcasting) .await .into_iter() @@ -372,9 +367,10 @@ impl Operation for PutOp { } }); + // Handle failed broadcasts let mut incorrect_results = 0; for (peer_num, err) in error_futures { - // remove the failed peers in reverse order + // Remove the failed peers in reverse order let peer = broadcast_to.get(peer_num).unwrap(); tracing::warn!( "failed broadcasting put change to {} with error {}; dropping connection", @@ -386,6 +382,7 @@ impl Operation for PutOp { incorrect_results += 1; } + // Update broadcast count and log success broadcasted_to += broadcast_to.len() - incorrect_results; tracing::debug!( "Successfully broadcasted put into contract {key} to {broadcasted_to} peers" @@ -407,38 +404,58 @@ impl Operation for PutOp { upstream, contract, state, + subscribe, }) => { - tracing::debug!(tx = %id, %key, peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), "Contract not cached @ peer, caching after successful put"); - // Always seed the contract locally after a successful put - op_manager.ring.seed_contract(key); + // Check if already subscribed before any operations + let is_subscribed_contract = op_manager.ring.is_seeding_contract(&key); - tracing::debug!(tx = %id, %key, peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), "Storing contract locally"); - op_manager - .notify_contract_handler(ContractHandlerEvent::PutQuery { - key, - state, - related_contracts: RelatedContracts::default(), - contract: Some(contract.clone()), - }) - .await - .map_err(|err| { - tracing::error!(tx = %id, %key, error = %err, "Failed to store contract locally"); - OpError::from(err) - })?; + tracing::debug!( + tx = %id, + %key, + peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), + "Storing contract locally after successful put" + ); - let is_subscribed_contract = op_manager.ring.is_seeding_contract(&key); + // Store the contract locally + put_contract( + op_manager, + key, + state.clone(), + RelatedContracts::default(), + &contract.clone(), + ) + .await?; + + // Handle seeding and subscription in one block if !is_subscribed_contract { - tracing::debug!(tx = %id, %key, peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), "Peer not subscribed to contract, starting subscription request"); - // TODO: Make put operation atomic by linking it to the completion of this subscription request. - // Currently we can't link one transaction to another transaction's result, which would be needed - // to make this fully atomic. This should be addressed in a future refactoring. - super::start_subscription_request( - op_manager, - key, - false, - HashSet::new(), - ) - .await; + // Always seed the contract locally after a successful put + tracing::debug!( + tx = %id, + %key, + peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), + "Adding contract to local seed list" + ); + op_manager.ring.seed_contract(key); + + // Start subscription if requested + if subscribe { + tracing::debug!( + tx = %id, + %key, + peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), + "Starting subscription request" + ); + // TODO: Make put operation atomic by linking it to the completion of this subscription request. + // Currently we can't link one transaction to another transaction's result, which would be needed + // to make this fully atomic. This should be addressed in a future refactoring. + super::start_subscription_request( + op_manager, + key, + false, + HashSet::new(), + ) + .await; + } } tracing::info!( @@ -447,8 +464,11 @@ impl Operation for PutOp { this_peer = %op_manager.ring.connection_manager.get_peer_key().unwrap(), "Peer completed contract value put", ); + + // Mark operation as finished new_state = Some(PutState::Finished { key }); + // Forward success message upstream if needed if let Some(upstream) = upstream { return_msg = Some(PutMsg::SuccessfulPut { id: *id, @@ -472,20 +492,23 @@ impl Operation for PutOp { skip_list, .. } => { + // Get contract key and own location let key = contract.key(); let peer_loc = op_manager.ring.connection_manager.own_location(); + let is_seeding_contract = op_manager.ring.is_seeding_contract(&key); + let should_seed = op_manager.ring.should_seed(&key); + let should_handle_locally = should_seed && !is_seeding_contract; tracing::debug!( + tx = %id, %key, - this_peer = % peer_loc.peer, - "Forwarding changes, trying put the contract" + this_peer = %peer_loc.peer, + "Forwarding changes, trying to put the contract" ); - let should_seed = op_manager.ring.should_seed(&key); - let mut already_put = false; - if should_seed { - tracing::debug!(%key, "Seeding contracting"); - // after the contract has been cached, push the update query + // Put the contract locally if needed + let already_put = if should_handle_locally { + tracing::debug!(tx = %id, %key, "Seeding contract locally"); put_contract( op_manager, key, @@ -494,14 +517,18 @@ impl Operation for PutOp { contract, ) .await?; - already_put = true; - } + true + } else { + false + }; - // if successful, forward to the next closest peers (if any) - let last_hop = if let Some(new_htl) = htl.checked_sub(1) { + // Determine if this is the last hop and handle forwarding + let (last_hop, new_skip_list) = if let Some(new_htl) = htl.checked_sub(1) { + // Create updated skip list let mut new_skip_list = skip_list.clone(); new_skip_list.insert(sender.peer.clone()); - // only hop forward if there are closer peers + + // Forward to closer peers let put_here = forward_put( op_manager, conn_manager, @@ -512,52 +539,60 @@ impl Operation for PutOp { new_skip_list.clone(), ) .await; - let is_seeding_contract = op_manager.ring.is_seeding_contract(&key); - if put_here && !is_seeding_contract && should_seed { - if !already_put { - // if already subscribed the value was already put and merging succeeded - put_contract( - op_manager, - key, - new_value.clone(), - RelatedContracts::default(), - contract, - ) - .await?; - } - let (dropped_contract, old_subscribers) = { - super::start_subscription_request( - op_manager, - key, - true, - new_skip_list, - ) - .await; - // FIXME: we start subscription request, but that does not mean we are already seeding - op_manager.ring.seed_contract(key) - }; - if let Some(key) = dropped_contract { - for subscriber in old_subscribers { - conn_manager - .send( - &subscriber.peer, - NetMessage::V1(NetMessageV1::Unsubscribed { - transaction: Transaction::new::(), - key, - from: op_manager - .ring - .connection_manager - .get_peer_key() - .unwrap(), - }), - ) - .await?; - } + + (put_here, new_skip_list) + } else { + // Last hop, no more forwarding + (true, skip_list.clone()) + }; + + // Handle subscription and local storage if this is the last hop + if last_hop && should_handle_locally { + // Put the contract if not already done + if !already_put { + put_contract( + op_manager, + key, + new_value.clone(), + RelatedContracts::default(), + contract, + ) + .await?; + } + + // Start subscription and handle dropped contracts + let (dropped_contract, old_subscribers) = { + super::start_subscription_request( + op_manager, + key, + true, + new_skip_list.clone(), + ) + .await; + op_manager.ring.seed_contract(key) + }; + + // Notify subscribers of dropped contracts + if let Some(dropped_key) = dropped_contract { + for subscriber in old_subscribers { + conn_manager + .send( + &subscriber.peer, + NetMessage::V1(NetMessageV1::Unsubscribed { + transaction: Transaction::new::(), + key: dropped_key, + from: op_manager + .ring + .connection_manager + .get_peer_key() + .unwrap(), + }), + ) + .await?; } } - put_here - } else if !already_put { - // should put in this location, no hops left + } else if last_hop && !already_put { + // Last hop but not handling locally, still need to put put_contract( op_manager, key, @@ -566,11 +601,9 @@ impl Operation for PutOp { contract, ) .await?; - true - } else { - true - }; + } + // Broadcast changes to subscribers let broadcast_to = op_manager.get_broadcast_targets(&key, &sender.peer); match try_to_broadcast( *id, @@ -658,6 +691,7 @@ async fn try_to_broadcast( upstream: Some(upstream), contract: contract.clone(), // No longer optional state: new_value.clone(), + subscribe: false, }); return_msg = None; } else if !broadcast_to.is_empty() { @@ -704,6 +738,7 @@ pub(crate) fn start_op( related_contracts: RelatedContracts<'static>, value: WrappedState, htl: usize, + subscribe: bool, ) -> PutOp { let key = contract.key(); let contract_location = Location::from(&key); @@ -716,6 +751,7 @@ pub(crate) fn start_op( related_contracts, value, htl, + subscribe, }); PutOp { @@ -733,6 +769,7 @@ pub enum PutState { related_contracts: RelatedContracts<'static>, value: WrappedState, htl: usize, + subscribe: bool, }, /// Awaiting response from petition. AwaitingResponse { @@ -740,6 +777,7 @@ pub enum PutState { upstream: Option, contract: ContractContainer, state: WrappedState, + subscribe: bool, }, /// Broadcasting changes to subscribers. BroadcastOngoing, @@ -777,16 +815,17 @@ pub(crate) async fn request_put(op_manager: &OpManager, mut put_op: PutOp) -> Re match put_op.state { Some(PutState::PrepareRequest { contract, + related_contracts, value, htl, - related_contracts, + subscribe, }) => { - let key = contract.key(); let new_state = Some(PutState::AwaitingResponse { key, upstream: None, contract: contract.clone(), state: value.clone(), + subscribe, }); let msg = PutMsg::RequestPut { id, @@ -798,8 +837,8 @@ pub(crate) async fn request_put(op_manager: &OpManager, mut put_op: PutOp) -> Re }; let op = PutOp { - state: new_state, id, + state: new_state, stats: put_op.stats, }; @@ -808,7 +847,7 @@ pub(crate) async fn request_put(op_manager: &OpManager, mut put_op: PutOp) -> Re .await?; } _ => return Err(OpError::invalid_transition(put_op.id)), - }; + } Ok(()) } diff --git a/crates/core/src/server/path_handlers.rs b/crates/core/src/server/path_handlers.rs index f8f94d83e..774d57532 100644 --- a/crates/core/src/server/path_handlers.rs +++ b/crates/core/src/server/path_handlers.rs @@ -57,6 +57,7 @@ pub(super) async fn contract_home( ContractRequest::Get { key, return_contract_code: true, + subscribe: false, } .into(), ), diff --git a/crates/core/tests/test_utils/mod.rs b/crates/core/tests/test_utils/mod.rs index 26cee7683..f18b98dce 100644 --- a/crates/core/tests/test_utils/mod.rs +++ b/crates/core/tests/test_utils/mod.rs @@ -26,6 +26,7 @@ pub async fn make_put( contract: contract.clone(), state: state.clone(), related_contracts: RelatedContracts::default(), + subscribe: false, })) .await?; Ok(()) @@ -54,6 +55,7 @@ pub async fn make_get( .send(ClientRequest::ContractOp(ContractRequest::Get { key, return_contract_code, + subscribe: false, })) .await?; Ok(()) diff --git a/crates/fdev/src/commands.rs b/crates/fdev/src/commands.rs index 9b8133d49..9aab211ee 100644 --- a/crates/fdev/src/commands.rs +++ b/crates/fdev/src/commands.rs @@ -81,6 +81,7 @@ async fn put_contract( contract, state, related_contracts, + subscribe: config.subscribe, } .into(); let mut client = start_api_client(other).await?; diff --git a/crates/fdev/src/config.rs b/crates/fdev/src/config.rs index 5933e17fc..0a345aa38 100644 --- a/crates/fdev/src/config.rs +++ b/crates/fdev/src/config.rs @@ -114,6 +114,10 @@ pub struct PutConfig { /// Type of put to perform. #[clap(subcommand)] pub(crate) package_type: PutType, + + /// Flag that indicates if the node should subscribe to the contract. + #[arg(long)] + pub(crate) subscribe: bool, } /// Builds and packages a contract or delegate. diff --git a/crates/fdev/src/wasm_runtime/user_events.rs b/crates/fdev/src/wasm_runtime/user_events.rs index 6b15dc36c..73628f726 100644 --- a/crates/fdev/src/wasm_runtime/user_events.rs +++ b/crates/fdev/src/wasm_runtime/user_events.rs @@ -218,6 +218,7 @@ impl From for OpenRequest<'static> { Command::Get => ContractRequest::Get { key, return_contract_code: false, + subscribe: false, } .into(), Command::Put => { @@ -226,6 +227,7 @@ impl From for OpenRequest<'static> { contract: cmd.contract, state: WrappedState::new(state.into_bytes()), related_contracts: Default::default(), + subscribe: false, } .into() } @@ -306,6 +308,7 @@ impl ClientEventsProxy for StdInput { node.send(ClientRequest::ContractOp(ContractRequest::Get { key, return_contract_code: true, + subscribe: false, })) .await .map_err(|e| { diff --git a/stdlib b/stdlib index 1c4d61629..2415cf550 160000 --- a/stdlib +++ b/stdlib @@ -1 +1 @@ -Subproject commit 1c4d61629622ffb6389e78ac966ad0b76ec4cb17 +Subproject commit 2415cf550cdd0888495798436c170ed73036a8bc From e954ab804bfd8bf2c7c4196cde1c25b21d6e6477 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Mon, 10 Mar 2025 18:14:50 -0500 Subject: [PATCH 121/121] handle new subscribe flag --- crates/core/src/client_events/websocket.rs | 2 +- stdlib | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/src/client_events/websocket.rs b/crates/core/src/client_events/websocket.rs index a9cafdea3..80dd77ca7 100644 --- a/crates/core/src/client_events/websocket.rs +++ b/crates/core/src/client_events/websocket.rs @@ -445,7 +445,7 @@ async fn process_client_request( "received PUT contract request" ); } - ContractRequest::Get { key, return_contract_code } => { + ContractRequest::Get { key, return_contract_code, .. } => { tracing::debug!( contract_key = %key, return_code = return_contract_code, diff --git a/stdlib b/stdlib index 843eb087d..e61305455 160000 --- a/stdlib +++ b/stdlib @@ -1 +1 @@ -Subproject commit 843eb087d43c328b1c9f070e11bb477f4ba1937b +Subproject commit e613054558cbf97256ae000782e53d2d8d7c6c92