Skip to content

Commit

Permalink
docs: update docs and add ci for docs (#499)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ma233 authored Dec 4, 2023
1 parent cb609f8 commit d5a1660
Show file tree
Hide file tree
Showing 16 changed files with 94 additions and 47 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/qaci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ jobs:
- name: Build
run: cargo build --all --verbose

- name: Run doc tests
run: cargo test --doc

- name: Run dummy tests
run: cargo test -p rings-core --features dummy --verbose

Expand Down Expand Up @@ -142,6 +145,11 @@ jobs:
- name: Check formating
run: cargo +nightly fmt --all -- --check

- name: Check docs
env:
RUSTDOCFLAGS: -Dwarnings
run: cargo doc --all --no-deps

- name: Install taplo
run: cargo install taplo-cli --locked

Expand Down
2 changes: 1 addition & 1 deletion core/src/ecc/signers/secp256r1.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Sign and verify message with curve secp256r1 and ECDSA
//! This module support WebCrypto API
//! ref: https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
//! ref: <https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API>
//! To use this signature, message should be wrapped with prefix
//!
//! ```js
Expand Down
2 changes: 1 addition & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! - [Chord](crate::dht::PeerRing) is a structured p2p network based on Chord protocol and expanded with secp256k1 based Did support.
//! - [ElGamal](crate::ecc::elgamal) provides End2End encryption based on Chord Did.
//! - [Swarm](crate::swarm) is a module for managing all transports.
//! - [Transport](crate::transports::Transport) is used for connection handshaking, which supports all platforms, including browser (wasm) and native runtime.
//! - [Connection](rings_transport::core::transport::ConnectionInterface) is used for connection handshaking, which supports all platforms, including browser (wasm) and native runtime.

//! # Connection
//!
Expand Down
1 change: 1 addition & 0 deletions core/src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ pub use handlers::MessageHandlerEvent;

mod protocols;
pub use protocols::MessageRelay;
pub use protocols::MessageVerification;
pub use protocols::MessageVerificationExt;
5 changes: 5 additions & 0 deletions core/src/message/protocols/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ use crate::utils::get_epoch_ms;
/// it also included ttl time and created ts.
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
pub struct MessageVerification {
/// The [Session] of the [SessionSk]. Used to identify a sender and verify the signature.
pub session: Session,
/// The time to live of the message in milliseconds.
pub ttl_ms: u64,
/// The timestamp of the message in milliseconds.
pub ts_ms: u128,
/// The signature of the message. Signed by [SessionSk]. Can be verified by [Session].
pub sig: Vec<u8>,
}

Expand All @@ -35,6 +39,7 @@ fn pack_msg(data: &[u8], ts_ms: u128, ttl_ms: u64) -> Vec<u8> {
}

impl MessageVerification {
/// Create a new MessageVerification. Should provide the data and the [SessionSk].
pub fn new(data: &[u8], session_sk: &SessionSk) -> Result<Self> {
let ts_ms = get_epoch_ms();
let ttl_ms = DEFAULT_TTL_MS;
Expand Down
4 changes: 2 additions & 2 deletions core/src/message/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub enum QueryFor {
Stabilization,
}

/// MessageType for handle [RemoteAction::Queryforsuccessorlist]
/// MessageType for handle [crate::dht::PeerRingRemoteAction::QueryForSuccessorList]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct QueryForTopoInfoSend {
/// The did for query target
Expand All @@ -87,7 +87,7 @@ pub struct QueryForTopoInfoSend {
pub then: QueryFor,
}

/// MessageType for handle [RemoteAction::Queryforsuccessorlist]
/// MessageType for handle [crate::dht::PeerRingRemoteAction::QueryForSuccessorList]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct QueryForTopoInfoReport {
/// The did for query target
Expand Down
60 changes: 46 additions & 14 deletions core/src/session.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,57 @@
#![warn(missing_docs)]
//! Understanding Abstract Account and Session keypair in Rings Network
//!
//! The Rings network offers a unique mechanism to bolster security and abstract the user's keypair through a feature known as session keypair.
//! Rings network offers a unique mechanism to bolster security and abstract the user's keypair through a feature known as session keypair.
//! The fundamental concept behind session keypair is signing a generated keypair with a time period {ts, ttl} by user without access its private key in this program.
//! This can be conceptualized as a contract stating, "I delegate to a keypair for the time period {ts, ttl}".
//!
//! The fundamental concept behind keypair session involves creating an association between a user's keypair and a randomly generated keypair. In our terminology:
//! In our terminology:
//! - `I` is [Account].
//! - `keypair` is [SessionSk].
//! - The time period {ts, ttl} is in `SessionSk.session` field.
//!
//! The user's original keypair (private key, public key) is referred to as the "account" (sk, pk).
//! The randomly generated keypair by the Rings network is known as the "session" (sk, pk).
//! The following is an example to build a [SessionSk] in Rust and use it to sign a message.
//! It is not necessary to construct a secret_key in Rust.
//! User may manually set account_type, account_entity, and session_sig, instead of provide secret key.
//! ```
//! use rings_core::dht::Did;
//! use rings_core::session::SessionSkBuilder;
//!
//! // We are generate an ethereum account for example.
//! // It's convenient because secp256k1 is also used in session_sk.
//! let user_secret_key = rings_core::ecc::SecretKey::random();
//! let user_secret_key_did: Did = user_secret_key.address().into();
//!
//! * Here's how the process works:
//! // The account type is "secp256k1".
//! // The account entity is its address, also known as Did in rings network.
//! let account_type = "secp256k1".to_string();
//! let account_entity = user_secret_key_did.to_string();
//!
//! 1. A random delegate private key (sk) is generated, along with its corresponding public key (pk).
//! let mut builder = SessionSkBuilder::new(account_entity, account_type);
//! let unsigned_proof = builder.unsigned_proof();
//!
//! 2. A session is formed based on the session's public key and the account's public key. This can be conceptualized as a contract stating, "I delegate to {pk} for the time period {ts, ttl}".
//! // Sign the unsigned proof with user's secret key.
//! let session_sig = user_secret_key.sign(&unsigned_proof).to_vec();
//! let builder = builder.set_session_sig(session_sig);
//!
//! 3. The account must sign the session, now termed "Session", using its private key.
//! let session_sk = builder.build().unwrap();
//!
//! 4. When sending and receiving messages, the Rings network will handle message signing and verification using the session's keypair (sk, pk).
//! // Check session_sk is valid. (The verify_self is already called in build().)
//! assert_eq!(session_sk.account_did(), user_secret_key_did);
//! assert!(session_sk.session().verify_self().is_ok());
//!
//! // Sign a message with session_sk.
//! let msg = "hello world".as_bytes();
//! let msg_sig = session_sk.sign(msg).unwrap();
//! let msg_session = session_sk.session();
//!
//! // Verify the message with session.
//! assert_eq!(msg_session.account_did(), user_secret_key_did);
//! assert!(msg_session.verify(msg, msg_sig).is_ok());
//! ```
//!
//! SessionSkBuilder, SessionSk was exported to wasm envirement, so in browser/wasm envirement it can be done with nodejs code:
//! [SessionSkBuilder], [SessionSk] is exported to wasm envirement.
//! To build a [SessionSk] in javascript:
//! ```js
//! // prepare auth & send to metamask for sign
//! let sessionBuilder = SessionSkBuilder.new(account, 'eip191')
Expand Down Expand Up @@ -61,7 +93,7 @@ fn pack_session(session_id: Did, ts_ms: u128, ttl_ms: u64) -> String {

/// SessionSkBuilder is used to build a [SessionSk].
///
/// Firstly, you need to provide the account's entity and type to `new` method.
/// Firstly, you need to provide the account's entity and type to [SessionSkBuilder::new] method.
/// Then you can call `pack_session` to get the session dump for signing.
/// After signing, you can call `sig` to set the signature back to builder.
/// Finally, you can call `build` to get the [SessionSk].
Expand Down Expand Up @@ -126,7 +158,7 @@ pub enum Account {
Secp256k1(Did),
/// ref: <https://eips.ethereum.org/EIPS/eip-191>
Secp256r1(PublicKey),
/// ref: ref: https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
/// ref: <https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API>
EIP191(Did),
/// bitcoin bip137 ref: <https://github.com/bitcoin/bips/blob/master/bip-0137.mediawiki>
BIP137(Did),
Expand Down Expand Up @@ -302,8 +334,8 @@ impl Session {
}

impl SessionSk {
/// Generate Session with private key.
/// Only use it for unittest.
/// Generate Session with private key. Only use it for unittest.
/// To protect your private key, please use [SessionSkBuilder] to generate session.
pub fn new_with_seckey(key: &SecretKey) -> Result<Self> {
let account_entity = Did::from(key.address()).to_string();
let account_type = "secp256k1".to_string();
Expand Down
4 changes: 3 additions & 1 deletion core/src/swarm/callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ pub trait SwarmCallback {
}
}

pub(crate) struct InnerSwarmCallback {
/// [InnerSwarmCallback] wraps [SharedSwarmCallback] with inner handling for a specific connection.
pub struct InnerSwarmCallback {
did: Did,
transport_event_sender: TransportEventSender,
callback: SharedSwarmCallback,
}

impl InnerSwarmCallback {
/// Create a new [InnerSwarmCallback] with the provided did, transport_event_sender and callback.
pub fn new(
did: Did,
transport_event_sender: TransportEventSender,
Expand Down
4 changes: 2 additions & 2 deletions core/src/swarm/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ use crate::measure::BehaviourJudgement;
use crate::swarm::Swarm;
use crate::types::Connection;

/// Type of Measure, see [Measure].
/// Type of Measure, see [crate::measure::Measure].
#[cfg(not(feature = "wasm"))]
pub type MeasureImpl = Box<dyn BehaviourJudgement + Send + Sync>;

/// Type of Measure, see [Measure].
/// Type of Measure, see [crate::measure::Measure].
#[cfg(feature = "wasm")]
pub type MeasureImpl = Box<dyn BehaviourJudgement>;

Expand Down
4 changes: 2 additions & 2 deletions transport/src/connection_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use crate::core::transport::WebrtcConnectionState;
use crate::error::Error;
use crate::error::Result;

/// The[ConnectionRef] is a weak reference to a connection and implements the `ConnectionInterface` trait.
/// [ConnectionRef] is a weak reference to a connection and implements the `ConnectionInterface` trait.
/// When the connection is dropped, it returns an error called [Error::ConnectionReleased].
/// It serves as the return value for the `get_connection` method of [Transport](crate::Transport).
/// It serves as the return value for the `connection` method of [TransportInterface](crate::core::transport::TransportInterface).
pub struct ConnectionRef<C> {
cid: String,
conn: Weak<C>,
Expand Down
6 changes: 3 additions & 3 deletions transport/src/connections/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Default using [WebrtcConnection] for native environment.
//! Plus a [WebSysWebrtcConnection] for wasm environment.
//! Also provide a [DummyConnection] for testing.
//! Default using `WebrtcConnection` for native environment.
//! Plus a `WebSysWebrtcConnection` for wasm environment.
//! Also provide a `DummyConnection` for testing.

#[cfg(feature = "dummy")]
mod dummy;
Expand Down
14 changes: 7 additions & 7 deletions transport/src/core/callback.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! The main entity of this module is the [Callback] trait, which defines
//! The main entity of this module is the [TransportCallback] trait, which defines
//! a series of methods that receive connection events.
//!
//! The `new_connection` method of
//! [ConnectionCreation](super::transport::ConnectionCreation) trait will
//! accept boxed [Callback] trait object.
//! [TransportInterface](super::transport::TransportInterface) trait will
//! accept boxed [TransportCallback] trait object.

use async_trait::async_trait;

Expand Down Expand Up @@ -31,13 +31,13 @@ pub trait TransportCallback {
}

/// The `new_connection` method of
/// [ConnectionCreation](super::transport::ConnectionCreation) trait will
/// accept boxed [Callback] trait object.
/// [TransportInterface](super::transport::TransportInterface) trait will
/// accept boxed [TransportCallback] trait object.
#[cfg(not(feature = "web-sys-webrtc"))]
pub type BoxedTransportCallback = Box<dyn TransportCallback + Send + Sync>;

/// The `new_connection` method of
/// [ConnectionCreation](super::transport::ConnectionCreation) trait will
/// accept boxed [Callback] trait object.
/// [TransportInterface](super::transport::TransportInterface) trait will
/// accept boxed [TransportCallback] trait object.
#[cfg(feature = "web-sys-webrtc")]
pub type BoxedTransportCallback = Box<dyn TransportCallback>;
6 changes: 3 additions & 3 deletions transport/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
//! make webrtc ice handshake with a remote peer and then send data channel message to it.
//! See the [transport] module.
//!
//! The [ConnectionCreation](transport::ConnectionCreation) trait should be
//! implemented for each Transport<Connection>. See the [transport] module.
//! The [TransportInterface](transport::TransportInterface) trait should be
//! implemented for each Transport of Connection implementation. See the [transport] module.
//!
//! The [Callback](callback::Callback) trait is used to let user handle
//! The [TransportCallback](callback::TransportCallback) trait is used to let user handle
//! the events of a connection, including connection state change,
//! coming data channel message and etc. See the [callback] module.

Expand Down
15 changes: 7 additions & 8 deletions transport/src/core/transport.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! The main entity of this module is the [ConnectionInterface] trait, which provides an
//! interface for establishing connections with other nodes, send data channel message to it.
//!
//! There is also a [ConnectionCreation] trait, which is used to specifies the creation of a
//! [ConnectionInterface] object for [Transport](crate::Transport).
//! There is also a [TransportInterface] trait, which is used to specify the management of all
//! [ConnectionInterface] objects.

use async_trait::async_trait;
use serde::de::DeserializeOwned;
Expand Down Expand Up @@ -58,7 +58,7 @@ pub enum WebrtcConnectionState {
Closed,
}

/// The [ConnectionInterface](transport::ConnectionInterface) trait defines how to
/// The [ConnectionInterface] trait defines how to
/// make webrtc ice handshake with a remote peer and then send data channel message to it.
#[cfg_attr(feature = "web-sys-webrtc", async_trait(?Send))]
#[cfg_attr(not(feature = "web-sys-webrtc"), async_trait)]
Expand Down Expand Up @@ -113,7 +113,7 @@ pub trait ConnectionInterface {
}
}

/// This trait specifies the creation of a [ConnectionInterface] object for [Transport](crate::Transport).
/// This trait specifies how to management [ConnectionInterface] objects.
/// Each platform must implement this trait for its own connection implementation.
/// See [connections](crate::connections) module for examples.
#[cfg_attr(feature = "web-sys-webrtc", async_trait(?Send))]
Expand All @@ -125,11 +125,11 @@ pub trait TransportInterface {
/// The error type that is returned by transport.
type Error: std::error::Error;

/// Used to create a new connection and register it in [Transport](crate::Transport).
/// Used to create a new connection and register it in the transport.
///
/// To avoid memory leak, this function will not return a connection object.
/// Instead, use should use `get_connection` method of [Transport](crate::Transport)
/// to get a [ConnectionRef](crate::connection_ref::ConnectionRef) after creation.
/// Instead, user should use `connection` method of to get a [ConnectionRef](crate::connection_ref::ConnectionRef)
/// after creation.
///
/// See [connections](crate::connections) module for examples.
async fn new_connection(
Expand All @@ -140,7 +140,6 @@ pub trait TransportInterface {

/// This method closes and releases the connection from transport.
/// All references to this cid, created by `get_connection`, will be released.
/// The [ConnectionInterface] methods of them will return [Error::ConnectionReleased].
async fn close_connection(&self, cid: &str) -> Result<(), Self::Error>;

/// Get a reference of the connection by its id.
Expand Down
2 changes: 1 addition & 1 deletion transport/src/ice_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub struct IceServer {
}

impl IceServer {
/// Convert String to Vec<IceServer>. Will split the string by `;` and parse each part.
/// Convert String to `Vec<IceServer>`. Will split the string by `;` and parse each part.
pub fn vec_from_str(s: &str) -> Result<Vec<Self>, IceServerError> {
s.split(';').map(IceServer::from_str).collect()
}
Expand Down
4 changes: 2 additions & 2 deletions transport/src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ where
/// The `safely_insert` method is used to insert a connection into the pool.
/// It ensures that the connection is not inserted twice in concurrent scenarios.
///
/// The implementation of match statement refers to Entry::insert in dashmap.
/// The implementation of match statement refers to `Entry::insert` in dashmap.
/// An extra check is added to see if the connection is already connected.
/// See also: https://docs.rs/dashmap/latest/dashmap/mapref/entry/enum.Entry.html#method.insert
/// See also: <https://docs.rs/dashmap/latest/dashmap/mapref/entry/enum.Entry.html#method.insert>
pub fn safely_insert(&self, cid: &str, conn: C) -> Result<()> {
let Some(entry) = self.connections.try_entry(cid.to_string()) else {
return Err(Error::ConnectionAlreadyExists(cid.to_string()));
Expand Down

0 comments on commit d5a1660

Please sign in to comment.