diff --git a/CHANGELOG.md b/CHANGELOG.md index 348e54a8e8..2210b86c84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 See issue [#1464](https://github.com/o1-labs/mina-rust/issues/1464). Fixed in [#1546](https://github.com/o1-labs/mina-rust/pull/1546/) ([#1546](https://github.com/o1-labs/mina-rust/pull/1546)) +- **CI**: ensure that `cargo test --doc` works in each crate, fix + [#1555](https://github.com/o1-labs/mina-rust/issues/1555), see + [#1556](https://github.com/o1-labs/mina-rust/pull/1556) ## v0.17.0 diff --git a/Cargo.lock b/Cargo.lock index db58a2c60b..cd683f1c26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5339,6 +5339,7 @@ dependencies = [ "mina-core", "proc-macro2 1.0.95", "quote 1.0.35", + "redux", "rust-format", "syn 2.0.96", "tracing", diff --git a/Makefile b/Makefile index a1c240c093..fdb5c62ffa 100644 --- a/Makefile +++ b/Makefile @@ -291,6 +291,10 @@ setup-wasm: ## Setup the WebAssembly toolchain, using nightly test: ## Run tests cargo test +.PHONY: test-doc +test-doc: ## Run documentation tests only + @cargo test --doc + .PHONY: test-ledger test-ledger: build-ledger ## Run ledger tests in release mode, requires nightly Rust @cd ledger && cargo +$(NIGHTLY_RUST_VERSION) test --release -- -Z unstable-options --report-time @@ -553,7 +557,7 @@ docs-serve-only: docs-install ## Serve the documentation website locally without @cd website && npm start -- --port $(DOCS_PORT) .PHONY: docs-rust -docs-rust: ## Generate Rust API documentation +docs-rust: test-doc ## Generate Rust API documentation @echo "Generating Rust API documentation..." # Using nightly with --enable-index-page to generate workspace index # See: https://github.com/rust-lang/cargo/issues/8229 diff --git a/cli/src/commands/node/mod.rs b/cli/src/commands/node/mod.rs index ea3d2bf3da..a09dfa2903 100644 --- a/cli/src/commands/node/mod.rs +++ b/cli/src/commands/node/mod.rs @@ -122,17 +122,17 @@ pub struct Node { /// Multiaddresses follow the format: `/protocol/address/protocol/port/protocol/peer_id` /// /// **IPv4 Example:** - /// ``` + /// ```ignore /// /ip4/192.168.1.100/tcp/8302/p2p/12D3KooWABCDEF1234567890abcdef... /// ``` /// /// **IPv6 Example:** - /// ``` + /// ```ignore /// /ip6/2001:db8::1/tcp/8302/p2p/12D3KooWABCDEF1234567890abcdef... /// ``` /// /// **DNS Example:** - /// ``` + /// ```ignore /// /dns4/node.example.com/tcp/8302/p2p/12D3KooWABCDEF1234567890abcdef... /// ``` /// @@ -149,7 +149,7 @@ pub struct Node { /// Each line should contain a peer's multiaddr following the format described above. /// /// **Example file content:** - /// ``` + /// ```ignore /// /ip4/192.168.1.100/tcp/8302/p2p/12D3KooWABCDEF1234567890abcdef... /// /ip4/10.0.0.50/tcp/8302/p2p/12D3KooWXYZ9876543210fedcba... /// /dns4/bootstrap.example.com/tcp/8302/p2p/12D3KooW123ABC... @@ -166,7 +166,7 @@ pub struct Node { /// Useful for dynamic peer discovery from a central bootstrap service. /// /// **Example URL response:** - /// ``` + /// ```ignore /// /ip4/bootstrap1.example.com/tcp/8302/p2p/12D3KooW... /// /ip4/bootstrap2.example.com/tcp/8302/p2p/12D3KooX... /// ``` diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 7054f9d0a9..1984cf9308 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -15,6 +15,7 @@ syn = { workspace = true } [dev-dependencies] mina-core = { path = "../core" } +redux = { workspace = true } tracing = { workspace = true } rust-format = { workspace = true, features = ["token_stream"] } anyhow = { workspace = true } diff --git a/macros/src/action_event.md b/macros/src/action_event.md index e679299205..782e7ef8f1 100644 --- a/macros/src/action_event.md +++ b/macros/src/action_event.md @@ -6,6 +6,21 @@ For action containers, it simply delegates to inner actions. ```rust # use mina_core::ActionEvent; +# extern crate redux; +# struct DummyContext { +# time: String, +# node_id: String, +# } +# impl mina_core::log::EventContext for DummyContext { +# fn timestamp(&self) -> redux::Timestamp { mina_core::log::system_time() } +# fn time(&self) -> &dyn tracing::Value { &self.time } +# fn node_id(&self) -> &dyn tracing::Value { &self.node_id } +# fn log_node_id(&self) -> bool { false } +# } +# let context = DummyContext { +# time: "0".to_string(), +# node_id: "test".to_string(), +# }; # #[derive(ActionEvent)] enum ActionContainer { @@ -17,10 +32,10 @@ enum Action1 { Done, } -ActionContainer::SubAction1(Action1::Init).action_event(context); +ActionContainer::SubAction1(Action1::Init).action_event(&context); ``` -```rust +```rust,ignore impl ActionEvent for ActionContainer { fn action_event(&self, context: &T) where T: ActionContext @@ -61,7 +76,7 @@ pub enum Action { } ``` -```rust +```rust,ignore impl mina_core::ActionEvent for Action { fn action_event(&self, context: &T) where @@ -97,7 +112,7 @@ pub enum Action { } ``` -```rust +```rust,ignore impl mina_core::ActionEvent for Action { fn action_event(&self, context: &T) where @@ -132,7 +147,7 @@ pub enum Action { } ``` -```rust +```rust,ignore impl mina_core::ActionEvent for Action { fn action_event(&self, context: &T) where @@ -156,6 +171,8 @@ a field's enum variant), logging can be delegated to a function implementing that logic. ```rust +# fn foo(_context: &T) {} +# fn bar(_context: &T, _f1: &bool) {} #[derive(mina_core::ActionEvent)] pub enum Action { #[action_event(expr(foo(context)))] @@ -165,7 +182,7 @@ pub enum Action { } ``` -```rust +```rust,ignore impl mina_core::ActionEvent for Action { fn action_event(&self, context: &T) where diff --git a/node/testing/src/cluster/mod.rs b/node/testing/src/cluster/mod.rs index 143ef27907..9b0606b6da 100644 --- a/node/testing/src/cluster/mod.rs +++ b/node/testing/src/cluster/mod.rs @@ -21,10 +21,13 @@ //! # Example //! //! ```rust,no_run -//! let mut cluster = Cluster::new(ClusterConfig::default()); +//! # use mina_node_testing::cluster::{Cluster, ClusterConfig}; +//! # use mina_node_testing::node::{RustNodeTestingConfig, OcamlNodeTestingConfig}; +//! let cluster_config = ClusterConfig::new(None).unwrap(); +//! let mut cluster = Cluster::new(cluster_config); //! //! // Add Rust node with custom configuration -//! let rust_node = cluster.add_rust_node(RustNodeTestingConfig::default()); +//! let rust_node = cluster.add_rust_node(RustNodeTestingConfig::devnet_default()); //! //! // Add OCaml node for cross-implementation testing //! let ocaml_node = cluster.add_ocaml_node(OcamlNodeTestingConfig::default()); diff --git a/node/testing/src/node/ocaml/config.rs b/node/testing/src/node/ocaml/config.rs index 3348957dbe..8218f143d2 100644 --- a/node/testing/src/node/ocaml/config.rs +++ b/node/testing/src/node/ocaml/config.rs @@ -98,8 +98,11 @@ pub enum OcamlNodeExecutable { /// * `String` - Path to the mina executable /// /// # Example - /// ``` + /// ```no_run + /// # use mina_node_testing::node::OcamlNodeExecutable; + /// # let _ = /// OcamlNodeExecutable::Installed("/usr/local/bin/mina".to_string()) + /// # ; /// ``` Installed(String), @@ -109,8 +112,11 @@ pub enum OcamlNodeExecutable { /// * `String` - Docker image tag /// /// # Example - /// ``` + /// ```no_run + /// # use mina_node_testing::node::OcamlNodeExecutable; + /// # let _ = /// OcamlNodeExecutable::Docker("minaprotocol/mina-daemon:3.0.0".to_string()) + /// # ; /// ``` Docker(String), diff --git a/node/testing/src/scenarios/driver.rs b/node/testing/src/scenarios/driver.rs index 5b81cf83f9..82c0793490 100644 --- a/node/testing/src/scenarios/driver.rs +++ b/node/testing/src/scenarios/driver.rs @@ -206,9 +206,15 @@ impl<'cluster> Driver<'cluster> { /// # Example /// /// ```no_run + /// # use std::time::Duration; + /// # use mina_node_testing::scenarios::Driver; + /// # use node::event_source::Event; + /// # async fn example(driver: &mut Driver<'_>) -> anyhow::Result<()> { /// driver.wait_for(Duration::from_secs(5), |node_id, event, state| { - /// matches!(event, Event::BlockReceived { .. }) + /// matches!(event, Event::P2p(_)) /// }).await?; + /// # Ok(()) + /// # } /// ``` pub async fn wait_for( &mut self, diff --git a/p2p/src/webrtc/connection_auth.rs b/p2p/src/webrtc/connection_auth.rs index a6765e2480..0597bed608 100644 --- a/p2p/src/webrtc/connection_auth.rs +++ b/p2p/src/webrtc/connection_auth.rs @@ -88,10 +88,17 @@ use super::{Answer, Offer}; /// ## Usage /// /// ```rust -/// use mina_p2p::webrtc::{ConnectionAuth, Offer, Answer}; -/// +/// # use p2p::webrtc::{ConnectionAuth, Offer, Answer}; +/// # use p2p::identity::{SecretKey, PublicKey}; +/// # use rand::thread_rng; +/// # fn example(offer: &Offer, answer: &Answer, +/// # my_secret_key: &SecretKey, peer_public_key: &PublicKey) +/// # -> Option<()> { +/// # let mut rng = thread_rng(); /// let connection_auth = ConnectionAuth::new(&offer, &answer); -/// let encrypted_auth = connection_auth.encrypt(&my_secret_key, &peer_public_key, rng)?; +/// let encrypted_auth = connection_auth.encrypt(&my_secret_key, &peer_public_key, &mut rng)?; +/// # Some(()) +/// # } /// ``` #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct ConnectionAuth(Vec); @@ -124,9 +131,16 @@ pub struct ConnectionAuth(Vec); /// ## Example /// /// ```rust +/// # use p2p::webrtc::ConnectionAuthEncrypted; +/// # use p2p::identity::{SecretKey, PublicKey}; +/// # fn example(encrypted_auth: &ConnectionAuthEncrypted, +/// # my_secret_key: &SecretKey, peer_public_key: &PublicKey) +/// # -> Option<()> { /// // After receiving encrypted authentication data /// let decrypted_auth = encrypted_auth.decrypt(&my_secret_key, &peer_public_key)?; /// // Verify that the decrypted data matches expected values +/// # Some(()) +/// # } /// ``` #[derive(Debug, Clone)] pub struct ConnectionAuthEncrypted(Box<[u8; 92]>); @@ -158,10 +172,11 @@ impl ConnectionAuth { /// # Example /// /// ```rust - /// use mina_p2p::webrtc::ConnectionAuth; - /// + /// # use p2p::webrtc::{ConnectionAuth, Offer, Answer}; + /// # fn example(offer: &Offer, answer: &Answer) { /// let auth = ConnectionAuth::new(&offer, &answer); /// // Use auth for connection verification + /// # } /// ``` pub fn new(offer: &Offer, answer: &Answer) -> Self { Self([offer.sdp_hash(), answer.sdp_hash()].concat()) @@ -196,14 +211,18 @@ impl ConnectionAuth { /// # Example /// /// ```rust - /// use rand::thread_rng; - /// + /// # use p2p::webrtc::ConnectionAuth; + /// # use p2p::identity::{SecretKey, PublicKey}; + /// # use rand::thread_rng; + /// # fn example(connection_auth: &ConnectionAuth, + /// # my_secret_key: &SecretKey, peer_public_key: &PublicKey) { /// let mut rng = thread_rng(); /// let encrypted_auth = connection_auth.encrypt(&my_secret_key, &peer_public_key, &mut rng); /// /// if let Some(encrypted) = encrypted_auth { /// // Send encrypted authentication data to peer /// } + /// # } /// ``` pub fn encrypt( &self, @@ -254,6 +273,10 @@ impl ConnectionAuthEncrypted { /// # Example /// /// ```rust + /// # use p2p::webrtc::ConnectionAuthEncrypted; + /// # use p2p::identity::{SecretKey, PublicKey}; + /// # fn example(encrypted_auth: &ConnectionAuthEncrypted, + /// # my_secret_key: &SecretKey, peer_public_key: &PublicKey) { /// // After receiving encrypted authentication data from peer /// if let Some(decrypted_auth) = encrypted_auth.decrypt(&my_secret_key, &peer_public_key) { /// // Authentication successful, proceed with connection @@ -262,6 +285,7 @@ impl ConnectionAuthEncrypted { /// // Authentication failed, reject connection /// println!("Peer authentication failed"); /// } + /// # } /// ``` pub fn decrypt(&self, sec_key: &SecretKey, other_pk: &PublicKey) -> Option { sec_key diff --git a/p2p/src/webrtc/signaling_method/http.rs b/p2p/src/webrtc/signaling_method/http.rs index 65fa14f83a..67e9df8ab5 100644 --- a/p2p/src/webrtc/signaling_method/http.rs +++ b/p2p/src/webrtc/signaling_method/http.rs @@ -59,9 +59,8 @@ use super::SignalingMethodParseError; /// # Examples /// /// ``` -/// use mina::webrtc::Host; -/// use mina::signaling_method::HttpSignalingInfo; -/// +/// # use p2p::webrtc::{Host, HttpSignalingInfo}; +/// # fn example() -> Result<(), Box> { /// // IPv4 signaling server /// let info = HttpSignalingInfo { /// host: Host::Ipv4("192.168.1.100".parse()?), @@ -73,6 +72,8 @@ use super::SignalingMethodParseError; /// host: Host::Domain("signal.example.com".into()), /// port: 443, /// }; +/// # Ok(()) +/// # } /// ``` #[derive(BinProtWrite, BinProtRead, Eq, PartialEq, Ord, PartialOrd, Debug, Clone)] pub struct HttpSignalingInfo { @@ -119,6 +120,7 @@ impl From<([u8; 4], u16)> for HttpSignalingInfo { /// # Example /// /// ``` + /// # use p2p::webrtc::HttpSignalingInfo; /// let info = HttpSignalingInfo::from(([192, 168, 1, 100], 8080)); /// assert_eq!(info.port, 8080); /// ``` @@ -148,8 +150,8 @@ impl FromStr for HttpSignalingInfo { /// # Examples /// /// ``` - /// use mina::signaling_method::HttpSignalingInfo; - /// + /// # use p2p::webrtc::HttpSignalingInfo; + /// # fn example() -> Result<(), Box> { /// // Domain and port /// let info: HttpSignalingInfo = "signal.example.com/443".parse()?; /// @@ -158,6 +160,8 @@ impl FromStr for HttpSignalingInfo { /// /// // With leading slash /// let info: HttpSignalingInfo = "/localhost/8080".parse()?; + /// # Ok(()) + /// # } /// ``` /// /// # Errors diff --git a/p2p/src/webrtc/signaling_method/mod.rs b/p2p/src/webrtc/signaling_method/mod.rs index 32f1656e4d..e65d7fc430 100644 --- a/p2p/src/webrtc/signaling_method/mod.rs +++ b/p2p/src/webrtc/signaling_method/mod.rs @@ -80,11 +80,16 @@ use crate::PeerId; /// # Example /// /// ``` +/// # use p2p::webrtc::SignalingMethod; +/// # use p2p::PeerId; +/// # fn example(peer_id: PeerId) -> Result<(), Box> { /// // Direct HTTPS signaling /// let method = "/https/signal.example.com/443".parse::()?; /// /// // P2P relay through an existing peer /// let method = SignalingMethod::P2p { relay_peer_id: peer_id }; +/// # Ok(()) +/// # } /// ``` #[derive(BinProtWrite, BinProtRead, Eq, PartialEq, Ord, PartialOrd, Debug, Clone)] pub enum SignalingMethod { @@ -158,8 +163,15 @@ impl SignalingMethod { /// # Example /// /// ``` + /// # use p2p::webrtc::{SignalingMethod, HttpSignalingInfo, Host}; + /// # fn example() { + /// # let info = HttpSignalingInfo { + /// # host: Host::Domain("signal.example.com".into()), + /// # port: 443, + /// # }; /// let method = SignalingMethod::Https(info); /// let url = method.http_url(); // Some("https://signal.example.com:443/mina/webrtc/signal") + /// # } /// ``` pub fn http_url(&self) -> Option { let (http, info) = match self { @@ -305,8 +317,8 @@ impl FromStr for SignalingMethod { /// # Examples /// /// ``` - /// use mina::signaling_method::SignalingMethod; - /// + /// # use p2p::webrtc::SignalingMethod; + /// # fn example() -> Result<(), Box> { /// // HTTP signaling /// let method: SignalingMethod = "/http/localhost/8080".parse()?; /// @@ -315,6 +327,8 @@ impl FromStr for SignalingMethod { /// /// // HTTPS proxy with cluster ID /// let method: SignalingMethod = "/https_proxy/123/proxy.example.com/443".parse()?; + /// # Ok(()) + /// # } /// ``` /// /// # Errors diff --git a/p2p/testing/src/cluster.rs b/p2p/testing/src/cluster.rs index b17266b427..b24ca2eb99 100644 --- a/p2p/testing/src/cluster.rs +++ b/p2p/testing/src/cluster.rs @@ -230,17 +230,16 @@ impl Default for Ports { /// Declares a shared storage for ports. /// -/// ``` +/// ```ignore /// ports_store!(GLOBAL_PORTS); /// /// #[tokio::test] -/// fn test1() { +/// async fn test1() { /// let cluster = ClusterBuilder::default() /// .ports(GLOBAL_PORTS.take(20).await.expect("enough ports")) /// .start() /// .await; /// } -/// /// ``` #[macro_export] macro_rules! ports_store { diff --git a/snark/src/lib.rs b/snark/src/lib.rs index bf1e55c2c8..dd863f69d9 100644 --- a/snark/src/lib.rs +++ b/snark/src/lib.rs @@ -58,7 +58,7 @@ //! //! ## Example Usage //! -//! ```rust,no_run +//! ```rust,ignore //! use snark::{SnarkConfig, SnarkState}; //! //! // Initialize SNARK state with configuration