Skip to content

Commit a0d1f7b

Browse files
authored
feat: add additional features to enable specific features (#417)
1 parent 48822a1 commit a0d1f7b

File tree

14 files changed

+405
-196
lines changed

14 files changed

+405
-196
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- chore: use async-rt in place of rt utils. [PR 362](https://github.com/dariusc93/rust-ipfs/pull/362)
88
- feat: Implement configuration for connecting to IPFS Private Network. [PR 398](https://github.com/dariusc93/rust-ipfs/pull/398)
99
- refactor: use CommunicationTask to handle sending message to IpfsTask. [PR 404](https://github.com/dariusc93/rust-ipfs/pull/404)
10+
- feat: add additional features to enable different features. [PR 417](https://github.com/dariusc93/rust-ipfs/pull/417)
1011
- feat: Use RepoType in Repo and impl DefaultStorage. [PR 414](https://github.com/dariusc93/rust-ipfs/pull/414)
1112

1213
# 0.14.1

Cargo.toml

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,27 @@ description = "IPFS node implementation"
1010
version = "0.15.0"
1111

1212
[features]
13-
default = []
13+
default = ["rsa", "dns", "ed25519", "secp256k1", "ecdsa", "tls", "noise", "tcp", "quic", "pnet", "websocket"]
1414

15-
experimental_stream = ["dep:libp2p-stream"]
15+
rsa = ["libp2p/rsa", "rust-ipns/rsa"]
16+
ed25519 = ["libp2p/ed25519", "rust-ipns/ed25519"]
17+
secp256k1 = ["libp2p/secp256k1", "rust-ipns/secp256k1"]
18+
ecdsa = ["libp2p/ecdsa", "rust-ipns/ecdsa"]
1619

17-
webrtc_transport = ["dep:libp2p-webrtc"]
20+
stream = ["dep:libp2p-stream"]
21+
22+
x509_dep = ["dep:simple_x509", "rcgen", "pem", "p256", "rand_chacha", "hkdf", "sec1"]
23+
24+
dns = ["libp2p/dns"]
25+
tls = ["libp2p/tls"]
26+
noise = ["libp2p/noise"]
27+
tcp = ["libp2p/tcp"]
28+
quic = ["libp2p/quic"]
29+
pnet = ["libp2p/pnet"]
30+
31+
webrtc = ["dep:libp2p-webrtc", "dep:libp2p-webrtc-websys", "x509_dep"]
32+
websocket = ["libp2p/websocket", "libp2p/websocket-websys", "x509_dep"]
33+
webtransport = ["libp2p/webtransport-websys"]
1834

1935
test_go_interop = []
2036
test_js_interop = []
@@ -64,7 +80,7 @@ rand = "0.8.5"
6480
rand_chacha = "0.3.1"
6581
rcgen = { version = "0.13.2", features = ["pem", "x509-parser"] }
6682
rlimit = "0.10.2"
67-
rust-ipns = { version = "0.7.0", path = "packages/rust-ipns" }
83+
rust-ipns = { version = "0.7.0", path = "packages/rust-ipns", default-features = false }
6884
rust-unixfs = { version = "0.5.0", path = "unixfs" }
6985
sec1 = { version = "0.7.3", features = ["pem", "pkcs8"] }
7086
send_wrapper = "0.6.0"
@@ -100,7 +116,7 @@ chrono.workspace = true
100116
either.workspace = true
101117
futures-timeout.workspace = true
102118
futures.workspace = true
103-
hkdf.workspace = true
119+
hkdf = { workspace = true, optional = true }
104120
indexmap.workspace = true
105121
ipld-core.workspace = true
106122
ipld-dagpb.workspace = true
@@ -112,17 +128,17 @@ multibase.workspace = true
112128
multihash.workspace = true
113129
multihash-codetable.workspace = true
114130
multihash-derive.workspace = true
115-
p256.workspace = true
131+
p256 = { workspace = true, optional = true }
116132
parking_lot.workspace = true
117-
pem.workspace = true
133+
pem = { workspace = true, optional = true }
118134
pollable-map.workspace = true
119135
quick-protobuf-codec.workspace = true
120136
quick-protobuf.workspace = true
121137
rand.workspace = true
122-
rand_chacha.workspace = true
123-
rust-ipns = { workspace = true }
138+
rand_chacha = { workspace = true, optional = true }
139+
rust-ipns = { workspace = true, features = ["libp2p"] }
124140
rust-unixfs = { workspace = true }
125-
sec1.workspace = true
141+
sec1 = { workspace = true, optional = true }
126142
serde = { features = ["derive"], workspace = true }
127143
serde_ipld_dagcbor.workspace = true
128144
serde_ipld_dagjson.workspace = true
@@ -139,11 +155,11 @@ zeroize.workspace = true
139155
futures-timer.workspace = true
140156
fs2.workspace = true
141157
hickory-resolver.workspace = true
142-
libp2p = { features = ["gossipsub", "autonat", "relay", "dcutr", "identify", "kad", "websocket", "tcp", "macros", "tokio", "noise", "tls", "ping", "yamux", "dns", "mdns", "ed25519", "secp256k1", "ecdsa", "rsa", "serde", "request-response", "json", "cbor", "rendezvous", "upnp", "quic", "pnet"], workspace = true }
158+
libp2p = { features = ["gossipsub", "autonat", "relay", "dcutr", "identify", "kad", "macros", "tokio", "ping", "yamux", "mdns", "serde", "request-response", "json", "cbor", "rendezvous", "upnp"], workspace = true }
143159
libp2p-webrtc = { workspace = true, features = ["tokio", ], optional = true }
144-
rcgen.workspace = true
160+
rcgen = { workspace = true, optional = true }
145161
rlimit.workspace = true
146-
simple_x509.workspace = true
162+
simple_x509 = { workspace = true, optional = true }
147163
tokio = { features = ["full"], workspace = true }
148164
tokio-stream = { workspace = true, features = ["fs"] }
149165
tokio-util = { workspace = true, features = ["full"] }
@@ -152,8 +168,8 @@ tokio-util = { workspace = true, features = ["full"] }
152168
futures-timer = { workspace = true, features = ["wasm-bindgen"] }
153169
getrandom = { workspace = true, features = ["js"] }
154170
idb.workspace = true
155-
libp2p = { features = ["gossipsub", "autonat", "relay", "dcutr", "identify", "kad", "websocket-websys", "webtransport-websys", "macros", "noise", "ping", "yamux", "dns", "ed25519", "secp256k1", "ecdsa", "serde", "request-response", "json", "cbor", "rendezvous", "wasm-bindgen", ], workspace = true }
156-
libp2p-webrtc-websys = { workspace = true }
171+
libp2p = { features = ["gossipsub", "autonat", "relay", "identify", "kad", "noise", "macros", "ping", "yamux", "serde", "request-response", "json", "cbor", "rendezvous", "wasm-bindgen"], workspace = true }
172+
libp2p-webrtc-websys = { workspace = true, optional = true }
157173
send_wrapper.workspace = true
158174
serde-wasm-bindgen.workspace = true
159175
tokio = { default-features = false, features = ["sync", "macros"], workspace = true }

examples/echo-stream.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// echo example based on libp2p-stream example
2-
#[cfg(feature = "experimental_stream")]
2+
#[cfg(feature = "stream")]
33
#[tokio::main]
44
async fn main() -> anyhow::Result<()> {
55
use std::time::Duration;
@@ -130,7 +130,7 @@ async fn main() -> anyhow::Result<()> {
130130
Ok(())
131131
}
132132

133-
#[cfg(not(feature = "experimental_stream"))]
133+
#[cfg(not(feature = "stream"))]
134134
fn main() {
135-
unimplemented!("\"experimental_stream\" not enabled")
135+
unimplemented!("\"stream\" not enabled")
136136
}

packages/rust-ipns/Cargo.toml

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,7 @@ serde = { workspace = true, features = ["derive"] }
2020
multihash.workspace = true
2121
chrono.workspace = true
2222

23-
libp2p-identity = { version = "0.2.10", optional = true, features = [
24-
"ecdsa",
25-
"ed25519",
26-
"peerid",
27-
"rand",
28-
"rsa",
29-
"secp256k1",
30-
] }
23+
libp2p-identity = { version = "0.2.10", optional = true, features = ["peerid", "rand"] }
3124
derive_more = { version = "2.0.1", features = ["full"] }
3225

3326
[target.'cfg(target_arch = "wasm32")'.dependencies]
@@ -37,5 +30,11 @@ getrandom = { workspace = true, features = ["js"] }
3730
clap = { workspace = true, features = ["derive"] }
3831

3932
[features]
40-
default = ["libp2p"]
4133
libp2p = ["dep:libp2p-identity"]
34+
35+
default = ["libp2p", "rsa", "ed25519", "secp256k1", "ecdsa"]
36+
37+
rsa = ["libp2p-identity?/rsa"]
38+
ed25519 = ["libp2p-identity?/ed25519"]
39+
secp256k1 = ["libp2p-identity?/secp256k1"]
40+
ecdsa = ["libp2p-identity?/ecdsa"]

src/ipns/dnslink.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::error::Error;
2+
#[cfg(feature = "dns")]
23
use crate::p2p::DnsResolver;
34
use crate::path::IpfsPath;
45

src/ipns/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@
33
use futures_timeout::TimeoutExt;
44
use std::borrow::Borrow;
55

6+
#[cfg(feature = "dns")]
67
use crate::p2p::DnsResolver;
78
use crate::path::{IpfsPath, PathRoot};
89
use crate::repo::DataStore;
910
use crate::Ipfs;
1011

12+
#[cfg(feature = "dns")]
1113
mod dnslink;
1214

1315
/// IPNS facade around [`Ipns`].
1416
#[derive(Clone, Debug)]
1517
pub struct Ipns {
1618
ipfs: Ipfs,
19+
#[cfg(feature = "dns")]
1720
resolver: DnsResolver,
1821
}
1922

@@ -28,11 +31,13 @@ impl Ipns {
2831
pub fn new(ipfs: Ipfs) -> Self {
2932
Ipns {
3033
ipfs,
34+
#[cfg(feature = "dns")]
3135
resolver: DnsResolver::default(),
3236
}
3337
}
3438

3539
/// Set dns resolver
40+
#[cfg(feature = "dns")]
3641
pub fn set_resolver(&mut self, resolver: DnsResolver) {
3742
self.resolver = resolver;
3843
}
@@ -128,6 +133,7 @@ impl Ipns {
128133
Ok(internal_path)
129134
})
130135
}
136+
#[cfg(feature = "dns")]
131137
PathRoot::Dns(domain) => {
132138
let path_iter = path.iter();
133139
dnslink::resolve(self.resolver, domain, path_iter)

src/keystore.rs

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ use zeroize::Zeroize;
1111

1212
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
1313
pub enum KeyType {
14+
#[cfg(feature = "ed25519")]
1415
Ed25519,
16+
#[cfg(feature = "ecdsa")]
1517
Ecdsa,
18+
#[cfg(feature = "secp256k1")]
1619
Secp256k1,
1720
}
1821

@@ -97,18 +100,21 @@ impl Keystore {
97100

98101
/// Generate a Ed25519 Keypair
99102
/// If `name` is not supplied, the [`crate::PeerId`] will be the used as the name by default
103+
#[cfg(feature = "ed25519")]
100104
pub async fn generate_ed25519(&self, name: Option<&str>) -> Result<PublicKey, Error> {
101105
self.generate_key(name, KeyType::Ed25519).await
102106
}
103107

104108
/// Generate a Ecdsa Keypair
105109
/// If `name` is not supplied, the [`crate::PeerId`] will be the used as the name by default
110+
#[cfg(feature = "ecdsa")]
106111
pub async fn generate_ecdsa(&self, name: Option<&str>) -> Result<PublicKey, Error> {
107112
self.generate_key(name, KeyType::Ecdsa).await
108113
}
109114

110115
/// Generate a Secp256k1 Keypair
111116
/// If `name` is not supplied, the [`crate::PeerId`] will be the used as the name by default
117+
#[cfg(feature = "secp256k1")]
112118
pub async fn generate_secp256k1(&self, name: Option<&str>) -> Result<PublicKey, Error> {
113119
self.generate_key(name, KeyType::Secp256k1).await
114120
}
@@ -120,25 +126,39 @@ impl Keystore {
120126
name: Option<&str>,
121127
key_type: KeyType,
122128
) -> Result<PublicKey, Error> {
123-
let keypair = match key_type {
124-
KeyType::Ed25519 => Keypair::generate_ed25519(),
125-
KeyType::Ecdsa => Keypair::generate_ecdsa(),
126-
KeyType::Secp256k1 => Keypair::generate_secp256k1(),
127-
};
128-
let public_key = keypair.public();
129+
#[cfg(not(all(feature = "ed25519", feature = "ecdsa", feature = "secp256k1")))]
130+
{
131+
let _ = name;
132+
let _ = key_type;
133+
return Err(anyhow::anyhow!("No key type selected"));
134+
}
129135

130-
let peer_id = public_key.to_peer_id().to_string();
136+
#[cfg(any(feature = "ed25519", feature = "ecdsa", feature = "secp256k1"))]
137+
{
138+
let keypair: Keypair = match key_type {
139+
#[cfg(feature = "ed25519")]
140+
KeyType::Ed25519 => Keypair::generate_ed25519(),
141+
#[cfg(feature = "ecdsa")]
142+
KeyType::Ecdsa => Keypair::generate_ecdsa(),
143+
#[cfg(feature = "secp256k1")]
144+
KeyType::Secp256k1 => Keypair::generate_secp256k1(),
145+
};
131146

132-
let peer_id_str = peer_id.as_str();
147+
let public_key = keypair.public();
133148

134-
// We could probably wrap this in `Zeroizing` instead until `KeyStore` is refactored to accept `Key`
135-
let bytes = Key::from(keypair.to_protobuf_encoding()?);
149+
let peer_id = public_key.to_peer_id().to_string();
136150

137-
let name = name.unwrap_or(peer_id_str);
151+
let peer_id_str = peer_id.as_str();
138152

139-
self.storage.set(name, bytes.as_ref()).await?;
153+
// We could probably wrap this in `Zeroizing` instead until `KeyStore` is refactored to accept `Key`
154+
let bytes = Key::from(keypair.to_protobuf_encoding()?);
140155

141-
Ok(public_key)
156+
let name = name.unwrap_or(peer_id_str);
157+
158+
self.storage.set(name, bytes.as_ref()).await?;
159+
160+
Ok(public_key)
161+
}
142162
}
143163

144164
/// Get a [`Keypair`] from the [`Keystore`]
@@ -244,6 +264,7 @@ impl KeyStorage for MemoryKeyStorage {
244264
mod test {
245265
use crate::keystore::Keystore;
246266

267+
#[cfg(feature = "ed25519")]
247268
#[tokio::test]
248269
async fn keystore_with_peerid() -> anyhow::Result<()> {
249270
let keystore = Keystore::in_memory();
@@ -257,6 +278,7 @@ mod test {
257278
Ok(())
258279
}
259280

281+
#[cfg(feature = "ed25519")]
260282
#[tokio::test]
261283
async fn keystore_with_name() -> anyhow::Result<()> {
262284
let keystore = Keystore::in_memory();
@@ -268,6 +290,7 @@ mod test {
268290
Ok(())
269291
}
270292

293+
#[cfg(feature = "ed25519")]
271294
#[tokio::test]
272295
async fn keystore_replace_existing() -> anyhow::Result<()> {
273296
let keystore = Keystore::in_memory();
@@ -277,6 +300,7 @@ mod test {
277300
Ok(())
278301
}
279302

303+
#[cfg(feature = "ed25519")]
280304
#[tokio::test]
281305
async fn keystore_multiple_keys() -> anyhow::Result<()> {
282306
let keystore = Keystore::in_memory();
@@ -293,6 +317,7 @@ mod test {
293317
Ok(())
294318
}
295319

320+
#[cfg(feature = "ed25519")]
296321
#[tokio::test]
297322
async fn keystore_rename() -> anyhow::Result<()> {
298323
let keystore = Keystore::in_memory();

0 commit comments

Comments
 (0)