Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gossipsub message signing #1583

Merged
merged 43 commits into from
Aug 3, 2020
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
aeba523
Gossipsub message signing
AgeManning May 19, 2020
573e4b6
Update ipfs-private example
AgeManning May 19, 2020
d2babd4
Add optimisation to prevent key calculation each message
AgeManning May 22, 2020
ac3c977
Handle forwarding of signed messages and reviewers comments
AgeManning May 25, 2020
e9afd95
Merge branch 'master' into gossipsub-signing
AgeManning May 27, 2020
3d1a025
protocols/gossipsub/src/protocol: Use quickcheck to test signing (#31)
mxinden Jun 1, 2020
31b6849
Shift signing into behaviour
AgeManning Jun 1, 2020
a8cec0b
Merge latest master
AgeManning Jul 1, 2020
2b38112
Address reviewers suggestions
AgeManning Jul 1, 2020
7d678f5
Send subscriptions to all peers
AgeManning Jul 1, 2020
dc050dd
Update examples
AgeManning Jul 1, 2020
5bf1cfc
Shift signing option into the behaviour
AgeManning Jul 1, 2020
4ffe728
Revert changes to core/
AgeManning Jul 9, 2020
24b738c
Reviewers suggestion
AgeManning Jul 9, 2020
a2e4bf0
Merge remote-tracking branch 'origin/master' into gossipsub-signing
AgeManning Jul 9, 2020
2f20571
Merge latest master
AgeManning Jul 23, 2020
2c50ba2
Revert changes to core/
AgeManning Jul 23, 2020
4de878e
Switch gossipsub state to use sets instead of vectors
rklaehn Jul 23, 2020
e43f0a0
Make tests pass
rklaehn Jul 23, 2020
57f07aa
Some clippy
rklaehn Jul 23, 2020
b6eeb3c
Prevent duplicate finding during JOIN
AgeManning Jul 24, 2020
0d5bde4
Merge #1675
AgeManning Jul 24, 2020
aec51e0
Update tests, improve logging
AgeManning Jul 24, 2020
759a5ad
Update the default d_lo constant
AgeManning Jul 24, 2020
495ffe4
Handle errors correctly
AgeManning Jul 24, 2020
1ea2dd9
Add privacy and validation options in the config
AgeManning Jul 24, 2020
1f73ded
A few improvements (#32)
rklaehn Jul 24, 2020
7b76c8f
Improve signing validation logic
AgeManning Jul 24, 2020
f5d32b2
Change the gossipsub rpc protocol to use bytes for message ids (#34)
rklaehn Jul 25, 2020
c3a7757
Add optional privacy and validation settings
AgeManning Jul 26, 2020
0c43ed4
Correct doc link
AgeManning Jul 27, 2020
efa40e3
Prevent invalid messages from being gossiped
AgeManning Jul 27, 2020
a514c60
Remove unvalidated messages from gossip. Reintroduce duplicate cache
AgeManning Jul 27, 2020
b257025
Send grafts when subscriptions are added to the mesh
AgeManning Jul 28, 2020
b20771b
Merge latest master
AgeManning Jul 28, 2020
2f4a50a
Only add messages to memcache if not duplicates
AgeManning Jul 28, 2020
be7c9e2
Add mesh maintenance tests and remove excess peers from mesh
AgeManning Jul 29, 2020
e049ff7
Apply reviewers suggestions
AgeManning Jul 29, 2020
74d2779
Merge latest master
AgeManning Jul 29, 2020
6bac865
Wrap comments
AgeManning Jul 29, 2020
94469cf
Ensure sequence number is sent
AgeManning Aug 2, 2020
60f8a1e
Merge latest master
AgeManning Aug 2, 2020
fef66dd
Maintain the debug trait
AgeManning Aug 2, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 22 additions & 24 deletions core/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub mod secp256k1;
pub mod error;

use self::error::*;
use crate::{PeerId, keys_proto};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am guessing that the changes in identity.rs and core/src/identity/error.rs were done by rustfmt. Would you mind reverting them in this pull-request as they seem unrelated? If you feel like the suggestions would improve code readability please open a separate pull request.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, editor has it in by default. I usually catch these, seems I missed one.

use crate::{keys_proto, PeerId};

/// Identity keypair of a node.
///
Expand Down Expand Up @@ -57,7 +57,7 @@ pub enum Keypair {
Rsa(rsa::Keypair),
/// A Secp256k1 keypair.
#[cfg(feature = "secp256k1")]
Secp256k1(secp256k1::Keypair)
Secp256k1(secp256k1::Keypair),
}

impl Keypair {
Expand Down Expand Up @@ -100,7 +100,7 @@ impl Keypair {
#[cfg(not(target_arch = "wasm32"))]
Rsa(ref pair) => pair.sign(msg),
#[cfg(feature = "secp256k1")]
Secp256k1(ref pair) => pair.secret().sign(msg)
Secp256k1(ref pair) => pair.secret().sign(msg),
}
}

Expand All @@ -127,7 +127,7 @@ pub enum PublicKey {
Rsa(rsa::PublicKey),
#[cfg(feature = "secp256k1")]
/// A public Secp256k1 key.
Secp256k1(secp256k1::PublicKey)
Secp256k1(secp256k1::PublicKey),
}

impl PublicKey {
Expand All @@ -142,7 +142,7 @@ impl PublicKey {
#[cfg(not(target_arch = "wasm32"))]
Rsa(pk) => pk.verify(msg, sig),
#[cfg(feature = "secp256k1")]
Secp256k1(pk) => pk.verify(msg, sig)
Secp256k1(pk) => pk.verify(msg, sig),
}
}

Expand All @@ -152,27 +152,26 @@ impl PublicKey {
use prost::Message;

let public_key = match self {
PublicKey::Ed25519(key) =>
keys_proto::PublicKey {
r#type: keys_proto::KeyType::Ed25519 as i32,
data: key.encode().to_vec()
},
PublicKey::Ed25519(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Ed25519 as i32,
data: key.encode().to_vec(),
},
#[cfg(not(target_arch = "wasm32"))]
PublicKey::Rsa(key) =>
keys_proto::PublicKey {
r#type: keys_proto::KeyType::Rsa as i32,
data: key.encode_x509()
},
PublicKey::Rsa(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Rsa as i32,
data: key.encode_x509(),
},
#[cfg(feature = "secp256k1")]
PublicKey::Secp256k1(key) =>
keys_proto::PublicKey {
r#type: keys_proto::KeyType::Secp256k1 as i32,
data: key.encode().to_vec()
}
PublicKey::Secp256k1(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Secp256k1 as i32,
data: key.encode().to_vec(),
},
};

let mut buf = Vec::with_capacity(public_key.encoded_len());
public_key.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
public_key
.encode(&mut buf)
.expect("Vec<u8> provides capacity as needed");
buf
}

Expand All @@ -191,7 +190,7 @@ impl PublicKey {
match key_type {
keys_proto::KeyType::Ed25519 => {
ed25519::PublicKey::decode(&pubkey.data).map(PublicKey::Ed25519)
},
}
#[cfg(not(target_arch = "wasm32"))]
keys_proto::KeyType::Rsa => {
rsa::PublicKey::decode_x509(&pubkey.data).map(PublicKey::Rsa)
Expand All @@ -200,7 +199,7 @@ impl PublicKey {
keys_proto::KeyType::Rsa => {
log::debug!("support for RSA was disabled at compile-time");
Err(DecodingError::new("Unsupported"))
},
}
#[cfg(feature = "secp256k1")]
keys_proto::KeyType::Secp256k1 => {
secp256k1::PublicKey::decode(&pubkey.data).map(PublicKey::Secp256k1)
Expand All @@ -218,4 +217,3 @@ impl PublicKey {
self.into()
}
}

25 changes: 18 additions & 7 deletions core/src/identity/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,22 @@ use std::fmt;
#[derive(Debug)]
pub struct DecodingError {
msg: String,
source: Option<Box<dyn Error + Send + Sync>>
source: Option<Box<dyn Error + Send + Sync>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AgeManning can you revert these formatting changes as well?

}

impl DecodingError {
pub(crate) fn new<S: ToString>(msg: S) -> Self {
Self { msg: msg.to_string(), source: None }
Self {
msg: msg.to_string(),
source: None,
}
}

pub(crate) fn source(self, source: impl Error + Send + Sync + 'static) -> Self {
Self { source: Some(Box::new(source)), .. self }
Self {
source: Some(Box::new(source)),
..self
}
}
}

Expand All @@ -56,17 +62,23 @@ impl Error for DecodingError {
#[derive(Debug)]
pub struct SigningError {
msg: String,
source: Option<Box<dyn Error + Send + Sync>>
source: Option<Box<dyn Error + Send + Sync>>,
}

/// An error during encoding of key material.
impl SigningError {
pub(crate) fn new<S: ToString>(msg: S) -> Self {
Self { msg: msg.to_string(), source: None }
Self {
msg: msg.to_string(),
source: None,
}
}

pub(crate) fn source(self, source: impl Error + Send + Sync + 'static) -> Self {
Self { source: Some(Box::new(source)), .. self }
Self {
source: Some(Box::new(source)),
..self
}
}
}

Expand All @@ -81,4 +93,3 @@ impl Error for SigningError {
self.source.as_ref().map(|s| &**s as &dyn Error)
}
}

23 changes: 13 additions & 10 deletions examples/gossipsub-chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ use async_std::{io, task};
use env_logger::{Builder, Env};
use futures::prelude::*;
use libp2p::gossipsub::protocol::MessageId;
use libp2p::gossipsub::{GossipsubEvent, GossipsubMessage, Topic};
use libp2p::{
gossipsub, identity,
PeerId,
};
use libp2p::gossipsub::{GossipsubEvent, GossipsubMessage, Signing, Topic};
use libp2p::{gossipsub, identity, PeerId};
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::time::Duration;
use std::{error::Error, task::{Context, Poll}};
use std::{
error::Error,
task::{Context, Poll},
};

fn main() -> Result<(), Box<dyn Error>> {
Builder::from_env(Env::default().default_filter_or("info")).init();
Expand All @@ -69,7 +69,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Local peer id: {:?}", local_peer_id);

// Set up an encrypted TCP Transport over the Mplex and Yamux protocols
let transport = libp2p::build_development_transport(local_key)?;
let transport = libp2p::build_development_transport(local_key.clone())?;

// Create a Gossipsub topic
let topic = Topic::new("test-net".into());
Expand All @@ -93,7 +93,8 @@ fn main() -> Result<(), Box<dyn Error>> {
//same content will be propagated.
.build();
// build a gossipsub network behaviour
let mut gossipsub = gossipsub::Gossipsub::new(local_peer_id.clone(), gossipsub_config);
let mut gossipsub =
gossipsub::Gossipsub::new(Signing::Enabled(local_key), gossipsub_config);
gossipsub.subscribe(topic.clone());
libp2p::Swarm::new(transport, gossipsub, local_peer_id)
};
Expand All @@ -120,11 +121,13 @@ fn main() -> Result<(), Box<dyn Error>> {
let mut listening = false;
task::block_on(future::poll_fn(move |cx: &mut Context| {
loop {
match stdin.try_poll_next_unpin(cx)? {
if let Err(e) = match stdin.try_poll_next_unpin(cx)? {
Poll::Ready(Some(line)) => swarm.publish(&topic, line.as_bytes()),
Poll::Ready(None) => panic!("Stdin closed"),
Poll::Pending => break,
};
} {
println!("Publish error: {:?}", e);
}
}

loop {
Expand Down
24 changes: 10 additions & 14 deletions examples/ipfs-private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use async_std::{io, task};
use futures::{future, prelude::*};
use libp2p::{
core::{either::EitherTransport, transport::upgrade::Version, StreamMuxer},
gossipsub::{self, Gossipsub, GossipsubConfigBuilder, GossipsubEvent},
gossipsub::{self, Gossipsub, GossipsubConfigBuilder, GossipsubEvent, Signing},
identify::{Identify, IdentifyEvent},
identity,
multiaddr::Protocol,
Expand Down Expand Up @@ -178,18 +178,14 @@ fn main() -> Result<(), Box<dyn Error>> {
ping: Ping,
}

impl NetworkBehaviourEventProcess<IdentifyEvent>
for MyBehaviour
{
impl NetworkBehaviourEventProcess<IdentifyEvent> for MyBehaviour {
// Called when `identify` produces an event.
fn inject_event(&mut self, event: IdentifyEvent) {
println!("identify: {:?}", event);
}
}

impl NetworkBehaviourEventProcess<GossipsubEvent>
for MyBehaviour
{
impl NetworkBehaviourEventProcess<GossipsubEvent> for MyBehaviour {
// Called when `gossipsub` produces an event.
fn inject_event(&mut self, event: GossipsubEvent) {
match event {
Expand All @@ -204,9 +200,7 @@ fn main() -> Result<(), Box<dyn Error>> {
}
}

impl NetworkBehaviourEventProcess<PingEvent>
for MyBehaviour
{
impl NetworkBehaviourEventProcess<PingEvent> for MyBehaviour {
// Called when `ping` produces an event.
fn inject_event(&mut self, event: PingEvent) {
use ping::handler::{PingFailure, PingSuccess};
Expand Down Expand Up @@ -245,11 +239,11 @@ fn main() -> Result<(), Box<dyn Error>> {

// Create a Swarm to manage peers and events
let mut swarm = {
let gossipsub_config = GossipsubConfigBuilder::default()
let gossipsub_config = GossipsubConfigBuilder::new()
.max_transmit_size(262144)
.build();
let mut behaviour = MyBehaviour {
gossipsub: Gossipsub::new(local_peer_id.clone(), gossipsub_config),
gossipsub: Gossipsub::new(Signing::Enabled(local_key.clone()), gossipsub_config),
identify: Identify::new(
"/ipfs/0.1.0".into(),
"rust-ipfs-example".into(),
Expand Down Expand Up @@ -280,12 +274,14 @@ fn main() -> Result<(), Box<dyn Error>> {
let mut listening = false;
task::block_on(future::poll_fn(move |cx: &mut Context| {
loop {
match stdin.try_poll_next_unpin(cx)? {
if let Err(e) = match stdin.try_poll_next_unpin(cx)? {
Poll::Ready(Some(line)) => {
swarm.gossipsub.publish(&gossipsub_topic, line.as_bytes());
swarm.gossipsub.publish(&gossipsub_topic, line.as_bytes())
}
Poll::Ready(None) => panic!("Stdin closed"),
Poll::Pending => break,
} {
println!("Publish error: {:?}", e);
}
}
loop {
Expand Down
1 change: 1 addition & 0 deletions protocols/gossipsub/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ env_logger = "0.7.1"
libp2p-plaintext = { path = "../plaintext" }
libp2p-yamux = { path = "../../muxers/yamux" }
quickcheck = "0.9.2"
hex = "0.4.2"

[build-dependencies]
prost-build = "0.6"
Loading