Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Initial Whisper implementation #6009

Merged
merged 39 commits into from
Jul 14, 2017
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b7708b5
whisper skeleton
rphmeier Jun 26, 2017
0ff28fe
basic message store
rphmeier Jun 26, 2017
5c8a374
rallying and message logic
rphmeier Jun 26, 2017
125389e
pass host info to network protocol handlers
rphmeier Jun 26, 2017
61acfc6
choose who starts rally based on node key
rphmeier Jun 26, 2017
7ecbb7f
module reshuffling
rphmeier Jun 26, 2017
8122805
mining messages
rphmeier Jun 27, 2017
1161a76
prune messages by low PoW until below size target
rphmeier Jun 27, 2017
67a51d2
Merge branch 'master' into whisper
rphmeier Jun 27, 2017
32575c6
associated error type for ethkey generators and `OsRng` generator
rphmeier Jun 27, 2017
8bff980
beginnings of RPC
rphmeier Jun 28, 2017
fdb8cbc
generic message handler for whisper
rphmeier Jun 28, 2017
435d494
reshuffle code order
rphmeier Jun 28, 2017
4332566
standard payload encoding and decoding
rphmeier Jun 28, 2017
79f6bfe
basic crypto
rphmeier Jun 29, 2017
953ad99
minor restructuring of net code
rphmeier Jun 29, 2017
9d09a67
implement shh_post
rphmeier Jun 29, 2017
a2af2e5
merge?
rphmeier Jun 29, 2017
601f6cd
Merge branch 'master' into whisper
rphmeier Jun 29, 2017
6837950
implement filters
rphmeier Jun 29, 2017
975fb81
rand trait for hash types
rphmeier Jun 30, 2017
03a839c
filter RPCs for whisper
rphmeier Jun 30, 2017
034db4e
symmetric encryption of payload
rphmeier Jun 30, 2017
2041439
pub-sub
rphmeier Jun 30, 2017
6b8cd61
filter tests
rphmeier Jun 30, 2017
7261b0c
use only secure random IDs
rphmeier Jul 1, 2017
e504198
attach arbitrary protocols to network
rphmeier Jul 1, 2017
6acf0b5
basic integration of whisper into Parity
rphmeier Jul 1, 2017
2cf05a7
eagerly prune low PoW entries
rphmeier Jul 3, 2017
1e31280
broadcast messages with salted topics
rphmeier Jul 4, 2017
860a68f
node info RPC
rphmeier Jul 5, 2017
fcf8b01
Merge branch 'master' into whisper
rphmeier Jul 6, 2017
ca8f8eb
Merge github.com:paritytech/parity into whisper
rphmeier Jul 6, 2017
921f0d3
fix import
rphmeier Jul 6, 2017
a7bb56a
fix leading zeros calculation
rphmeier Jul 11, 2017
79f03ea
Merge branch 'master' into whisper
rphmeier Jul 11, 2017
7431461
Merge branch 'master' into whisper
rphmeier Jul 13, 2017
9f0741f
Merge branch 'master' into whisper
rphmeier Jul 13, 2017
69b2c7c
address minor grumbles
rphmeier Jul 14, 2017
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
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ parity-reactor = { path = "util/reactor" }
parity-rpc = { path = "rpc" }
parity-rpc-client = { path = "rpc_client" }
parity-updater = { path = "updater" }
parity-whisper = { path = "whisper" }
path = { path = "util/path" }

parity-dapps = { path = "dapps", optional = true }
Expand Down Expand Up @@ -106,4 +107,4 @@ lto = false
panic = "abort"

[workspace]
members = ["ethstore/cli", "ethkey/cli", "evmbin"]
members = ["ethstore/cli", "ethkey/cli", "evmbin", "whisper"]
4 changes: 2 additions & 2 deletions ethcore/light/src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
use ethcore::transaction::UnverifiedTransaction;

use io::TimerToken;
use network::{NetworkProtocolHandler, NetworkContext, PeerId};
use network::{HostInfo, NetworkProtocolHandler, NetworkContext, PeerId};
use rlp::{RlpStream, UntrustedRlp};
use util::hash::H256;
use util::{DBValue, Mutex, RwLock, U256};
Expand Down Expand Up @@ -1074,7 +1074,7 @@ fn punish(peer: PeerId, io: &IoContext, e: Error) {
}

impl NetworkProtocolHandler for LightProtocol {
fn initialize(&self, io: &NetworkContext) {
fn initialize(&self, io: &NetworkContext, _host_info: &HostInfo) {
io.register_timer(TIMEOUT, TIMEOUT_INTERVAL_MS)
.expect("Error registering sync timer.");
io.register_timer(TICK_TIMEOUT, TICK_TIMEOUT_INTERVAL_MS)
Expand Down
49 changes: 49 additions & 0 deletions ethcore/src/engines/epoch_verifier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

// Epoch verifiers.

use error::Error;
use header::Header;

/// Verifier for all blocks within an epoch with self-contained state.
///
/// See docs on `Engine` relating to proving functions for more details.
pub trait EpochVerifier: Send + Sync {
/// Get the epoch number.
fn epoch_number(&self) -> u64;

/// Lightly verify the next block header.
/// This may not be a header belonging to a different epoch.
fn verify_light(&self, header: &Header) -> Result<(), Error>;

/// Perform potentially heavier checks on the next block header.
fn verify_heavy(&self, header: &Header) -> Result<(), Error> {
self.verify_light(header)
}

/// Check if the header is the end of an epoch.
fn is_epoch_end(&self, header: &Header, Ancestry) -> EpochChange;

}

/// Special "no-op" verifier for stateless, epoch-less engines.
pub struct NoOp;

impl EpochVerifier for NoOp {
fn epoch_number(&self) -> u64 { 0 }
fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) }
}
15 changes: 8 additions & 7 deletions ethkey/src/brain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use keccak::Keccak256;
use super::{KeyPair, Error, Generator, Secret};
use super::{KeyPair, Generator, Secret};

/// Simple brainwallet.
pub struct Brain(String);
Expand All @@ -27,7 +27,9 @@ impl Brain {
}

impl Generator for Brain {
fn generate(self) -> Result<KeyPair, Error> {
type Error = ::Void;

fn generate(self) -> Result<KeyPair, Self::Error> {
let seed = self.0;
let mut secret = seed.into_bytes().keccak256();

Expand All @@ -38,11 +40,10 @@ impl Generator for Brain {
match i > 16384 {
false => i += 1,
true => {
if let Ok(secret) = Secret::from_unsafe_slice(&secret) {
let result = KeyPair::from_secret(secret);
if result.as_ref().ok().map_or(false, |r| r.address()[0] == 0) {
return result;
}
if let Ok(pair) = Secret::from_unsafe_slice(&secret)
.and_then(KeyPair::from_secret)
{
if pair.address()[0] == 0 { return Ok(pair) }
}
},
}
Expand Down
32 changes: 20 additions & 12 deletions ethkey/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

extern crate rand;
#[macro_use]
extern crate lazy_static;
extern crate tiny_keccak;
extern crate secp256k1;
extern crate rustc_hex;
extern crate ethcore_bigint as bigint;
extern crate crypto as rcrypto;
extern crate byteorder;

#[macro_use]
extern crate lazy_static;

mod brain;
mod error;
mod keypair;
Expand All @@ -34,21 +35,12 @@ mod signature;
mod secret;
mod extended;

lazy_static! {
pub static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new();
}

/// Generates new keypair.
pub trait Generator {
/// Should be called to generate new keypair.
fn generate(self) -> Result<KeyPair, Error>;
}

pub mod math;

pub use self::brain::Brain;
pub use self::error::Error;
pub use self::keypair::{KeyPair, public_to_address};
pub use self::math::public_is_valid;
pub use self::prefix::Prefix;
pub use self::random::Random;
pub use self::signature::{sign, verify_public, verify_address, recover, Signature};
Expand All @@ -57,6 +49,22 @@ pub use self::extended::{ExtendedPublic, ExtendedSecret, ExtendedKeyPair, Deriva

use bigint::hash::{H160, H256, H512};

lazy_static! {
pub static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new();
}

/// Uninstantiatable error type for infallible generators.
#[derive(Debug)]
pub enum Void {}

/// Generates new keypair.
pub trait Generator {
type Error;

/// Should be called to generate new keypair.
fn generate(self) -> Result<KeyPair, Self::Error>;
}

pub type Address = H160;
pub type Message = H256;
pub type Public = H512;
6 changes: 6 additions & 0 deletions ethkey/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ use secp256k1::constants::{GENERATOR_X, GENERATOR_Y, CURVE_ORDER};
use bigint::prelude::U256;
use bigint::hash::H256;

/// Whether the public key is valid.
pub fn public_is_valid(public: &Public) -> bool {
to_secp256k1_public(public).ok()
.map_or(false, |p| p.is_valid())
}

/// Inplace multiply public key by secret key (EC point * scalar)
pub fn public_mul_secret(public: &mut Public, secret: &Secret) -> Result<(), Error> {
let key_secret = secret.to_secp256k1_secret()?;
Expand Down
2 changes: 2 additions & 0 deletions ethkey/src/prefix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ impl Prefix {
}

impl Generator for Prefix {
type Error = Error;

fn generate(self) -> Result<KeyPair, Error> {
for _ in 0..self.iterations {
let keypair = Random.generate()?;
Expand Down
24 changes: 18 additions & 6 deletions ethkey/src/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,30 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use rand::os::OsRng;
use super::{Generator, KeyPair, Error, SECP256K1};
use super::{Generator, KeyPair, SECP256K1};

/// Randomly generates new keypair.
/// Randomly generates new keypair, instantiating the RNG each time.
pub struct Random;

impl Generator for Random {
fn generate(self) -> Result<KeyPair, Error> {
let context = &SECP256K1;
type Error = ::std::io::Error;

fn generate(self) -> Result<KeyPair, Self::Error> {
let mut rng = OsRng::new()?;
let (sec, publ) = context.generate_keypair(&mut rng)?;
match rng.generate() {
Ok(pair) => Ok(pair),
Err(void) => match void {}, // LLVM unreachable
}
}
}

impl<'a> Generator for &'a mut OsRng {
type Error = ::Void;

fn generate(self) -> Result<KeyPair, Self::Error> {
let (sec, publ) = SECP256K1.generate_keypair(self)
.expect("context always created with full capabilities; qed");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is invalid capabilities the only possible source of failure here? Why not just pass the error as it was before the change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's the only source of failure, yeah. @debris and I discussed making this function infallible before, and I figured this was a good time for it.


Ok(KeyPair::from_keypair(sec, publ))
}
}

4 changes: 4 additions & 0 deletions parity/cli/config.full.toml
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,7 @@ jit = false
logging = "own_tx=trace"
log_file = "/var/log/parity.log"
color = true

[whisper]
enabled = false
pool_size = 20
4 changes: 4 additions & 0 deletions parity/cli/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ log_file = "/var/log/parity.log"
color = true
ports_shift = 0
unsafe_expose = false

[whisper]
enabled = true
pool_size = 50
29 changes: 25 additions & 4 deletions parity/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ usage! {
or |c: &Config| otry!(c.rpc).interface.clone(),
flag_jsonrpc_cors: Option<String> = None,
or |c: &Config| otry!(c.rpc).cors.clone().map(Some),
flag_jsonrpc_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc,secretstore",
flag_jsonrpc_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc,secretstore,shh,shh_pubsub",
or |c: &Config| otry!(c.rpc).apis.as_ref().map(|vec| vec.join(",")),
flag_jsonrpc_hosts: String = "none",
or |c: &Config| otry!(c.rpc).hosts.as_ref().map(|vec| vec.join(",")),
Expand All @@ -192,7 +192,7 @@ usage! {
or |c: &Config| otry!(c.websockets).port.clone(),
flag_ws_interface: String = "local",
or |c: &Config| otry!(c.websockets).interface.clone(),
flag_ws_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc,secretstore",
flag_ws_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc,secretstore,shh,shh_pubsub",
or |c: &Config| otry!(c.websockets).apis.as_ref().map(|vec| vec.join(",")),
flag_ws_origins: String = "chrome-extension://*",
or |c: &Config| otry!(c.websockets).origins.as_ref().map(|vec| vec.join(",")),
Expand All @@ -204,7 +204,7 @@ usage! {
or |c: &Config| otry!(c.ipc).disable.clone(),
flag_ipc_path: String = if cfg!(windows) { r"\\.\pipe\jsonrpc.ipc" } else { "$BASE/jsonrpc.ipc" },
or |c: &Config| otry!(c.ipc).path.clone(),
flag_ipc_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,traces,rpc,secretstore",
flag_ipc_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,traces,rpc,secretstore,shh,shh_pubsub",
or |c: &Config| otry!(c.ipc).apis.as_ref().map(|vec| vec.join(",")),

// DAPPS
Expand Down Expand Up @@ -365,6 +365,12 @@ usage! {
flag_no_color: bool = false,
or |c: &Config| otry!(c.misc).color.map(|c| !c).clone(),

// -- Whisper options
flag_whisper: bool = false,
or |c: &Config| otry!(c.whisper).enabled,
flag_whisper_pool_size: usize = 10usize,
or |c: &Config| otry!(c.whisper).pool_size.clone(),

// -- Legacy Options supported in configs
flag_dapps_port: Option<u16> = None,
or |c: &Config| otry!(c.dapps).port.clone().map(Some),
Expand Down Expand Up @@ -407,6 +413,7 @@ struct Config {
vm: Option<VM>,
misc: Option<Misc>,
stratum: Option<Stratum>,
whisper: Option<Whisper>,
}

#[derive(Default, Debug, PartialEq, Deserialize)]
Expand Down Expand Up @@ -603,12 +610,18 @@ struct Misc {
unsafe_expose: Option<bool>,
}

#[derive(Default, Debug, PartialEq, Deserialize)]
struct Whisper {
enabled: Option<bool>,
pool_size: Option<usize>,
}

#[cfg(test)]
mod tests {
use super::{
Args, ArgsError,
Config, Operating, Account, Ui, Network, Ws, Rpc, Ipc, Dapps, Ipfs, Mining, Footprint,
Snapshots, VM, Misc, SecretStore,
Snapshots, VM, Misc, Whisper, SecretStore,
};
use toml;

Expand Down Expand Up @@ -860,6 +873,10 @@ mod tests {
// -- Virtual Machine Options
flag_jitvm: false,

// -- Whisper options.
flag_whisper: false,
flag_whisper_pool_size: 20,

// -- Legacy Options
flag_geth: false,
flag_testnet: false,
Expand Down Expand Up @@ -1082,6 +1099,10 @@ mod tests {
ports_shift: Some(0),
unsafe_expose: Some(false),
}),
whisper: Some(Whisper {
enabled: Some(true),
pool_size: Some(50),
}),
stratum: None,
});
}
Expand Down
5 changes: 5 additions & 0 deletions parity/cli/usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,11 @@ Snapshot Options:
Virtual Machine Options:
--jitvm Enable the JIT VM. (default: {flag_jitvm})

Whisper Options:
--whisper Enable the Whisper network. (default: {flag_whisper})
--whisper-pool-size MB Target size of the whisper message pool in megabytes.
(default: {flag_whisper_pool_size})

Legacy Options:
--geth Run in Geth-compatibility mode. Sets the IPC path
to be the same as Geth's. Overrides the --ipc-path
Expand Down
11 changes: 11 additions & 0 deletions parity/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,8 @@ impl Configuration {
_ => (self.gas_pricer_config()?, self.miner_options(self.args.flag_reseal_min_period)?),
};

let whisper_config = self.whisper_config();

let run_cmd = RunCmd {
cache_config: cache_config,
dirs: dirs,
Expand Down Expand Up @@ -383,6 +385,7 @@ impl Configuration {
serve_light: !self.args.flag_no_serve_light,
light: self.args.flag_light,
no_persistent_txqueue: self.args.flag_no_persistent_txqueue,
whisper: whisper_config,
};
Cmd::Run(run_cmd)
};
Expand Down Expand Up @@ -1068,6 +1071,13 @@ impl Configuration {

settings
}

fn whisper_config(&self) -> ::whisper::Config {
::whisper::Config {
enabled: self.args.flag_whisper,
target_message_pool_size: self.args.flag_whisper_pool_size * 1024 * 1024,
}
}
}

#[cfg(test)]
Expand Down Expand Up @@ -1326,6 +1336,7 @@ mod tests {
serve_light: true,
light: false,
no_persistent_txqueue: false,
whisper: Default::default(),
};
expected.secretstore_conf.enabled = cfg!(feature = "secretstore");
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Run(expected));
Expand Down
Loading