Skip to content
This repository has been archived by the owner on Jun 25, 2021. It is now read-only.

Commit

Permalink
chore: address review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
maqi committed Dec 3, 2020
1 parent cf937e4 commit f67ae6c
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 111 deletions.
2 changes: 1 addition & 1 deletion src/messages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mod variant;
pub use self::{hash::MessageHash, src_authority::SrcAuthority};
pub(crate) use self::{
plain_message::PlainMessage,
variant::{BootstrapResponse, JoinRequest, Variant},
variant::{BootstrapResponse, JoinRequest, Proof, Variant},
};
use crate::{
crypto::{self, name, Verifier},
Expand Down
39 changes: 28 additions & 11 deletions src/messages/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use super::{Message, MessageHash, VerifyStatus};
use crate::{
consensus::{DkgKey, ProofShare, Proven, Vote},
crypto::Signature,
error::{Error, Result},
network::Network,
relocation::{RelocateDetails, RelocatePayload, RelocatePromise},
Expand Down Expand Up @@ -102,6 +103,13 @@ pub(crate) enum Variant {
content: Vote,
proof_share: ProofShare,
},
/// Challenge sent from existing elder nodes to the joining peer for resource proofing.
Challenge {
data_size: usize,
difficulty: u8,
nonce: [u8; 32],
signature: Signature,
},
}

impl Variant {
Expand Down Expand Up @@ -200,6 +208,15 @@ impl Debug for Variant {
.field("content", content)
.field("proof_share", proof_share)
.finish(),
Self::Challenge {
data_size,
difficulty,
..
} => f
.debug_struct("Challenge")
.field("data_size", data_size)
.field("difficulty", difficulty)
.finish(),
}
}
}
Expand All @@ -216,12 +233,15 @@ pub enum BootstrapResponse {
/// The new peer should retry bootstrapping with another section. The set of connection infos
/// of the members of that section is provided.
Rebootstrap(Vec<SocketAddr>),
/// Expecting the new peer to carry out a resouce proofing.
ResourceProof {
data_size: usize,
difficulty: u8,
nonce: [u8; 32],
},
}

/// Joining peer's proof of resolvement of given resource proofing challenge.
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
pub(crate) struct Proof {
pub(crate) solution: u64,
pub(crate) data: VecDeque<u8>,
pub(crate) nonce: [u8; 32],
pub(crate) signature: Signature,
}

/// Request to join a section
Expand All @@ -232,7 +252,7 @@ pub(crate) struct JoinRequest {
/// If the peer is being relocated, contains `RelocatePayload`. Otherwise contains `None`.
pub relocate_payload: Option<RelocatePayload>,
/// Proof of the resouce proofing
pub resource_proof: Option<(u64, VecDeque<u8>)>,
pub proof: Option<Proof>,
}

impl Debug for JoinRequest {
Expand All @@ -247,10 +267,7 @@ impl Debug for JoinRequest {
.as_ref()
.map(|payload| payload.relocate_details()),
)
.field(
"resouce_proof",
&self.resource_proof.as_ref().map(|(solution, _)| solution),
)
.field("proof", &self.proof.as_ref().map(|proof| proof.solution))
.finish()
}
}
67 changes: 41 additions & 26 deletions src/routing/approved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ use crate::{
AccumulationError, DkgCommands, DkgKey, DkgVoter, Proof, ProofShare, Proven, Vote,
VoteAccumulator,
},
delivery_group,
crypto, delivery_group,
error::{Error, Result},
event::Event,
location::{DstLocation, SrcLocation},
message_filter::MessageFilter,
messages::{
BootstrapResponse, JoinRequest, Message, MessageHash, MessageStatus, PlainMessage, Variant,
VerifyStatus, PING,
BootstrapResponse, JoinRequest, Message, MessageHash, MessageStatus, PlainMessage,
Proof as ResourceProofingProof, Variant, VerifyStatus, PING,
},
network::Network,
node::Node,
Expand All @@ -36,16 +36,15 @@ use crate::{
};
use bls_dkg::key_gen::{message::Message as DkgMessage, outcome::Outcome as DkgOutcome};
use bytes::Bytes;
use ed25519_dalek::Verifier;
use itertools::Itertools;
use lru_time_cache::LruCache;
use resource_proof::ResourceProof;
use std::{cmp, net::SocketAddr, slice};
use tokio::sync::mpsc;
use xor_name::{Prefix, XorName};

pub(crate) const RESOURCE_PROOF_DATA_SIZE: usize = 256;
pub(crate) const RESOURCE_PROOF_DIFF: u8 = 8;
const RESOURCE_PROOF_ENTRIES: usize = 100;
pub(crate) const RESOURCE_PROOF_DATA_SIZE: usize = 128;
pub(crate) const RESOURCE_PROOF_DIFFICULTY: u8 = 4;

// The approved stage - node is a full member of a section and is performing its duties according
// to its persona (adult or elder).
Expand All @@ -63,7 +62,6 @@ pub(crate) struct Approved {
pub(super) event_tx: mpsc::UnboundedSender<Event>,
joins_allowed: bool,
resource_proof: ResourceProof,
nonces: LruCache<XorName, [u8; 32]>,
}

impl Approved {
Expand Down Expand Up @@ -94,8 +92,7 @@ impl Approved {
msg_filter: MessageFilter::new(),
event_tx,
joins_allowed: true,
resource_proof: ResourceProof::new(RESOURCE_PROOF_DATA_SIZE, RESOURCE_PROOF_DIFF),
nonces: LruCache::with_capacity(RESOURCE_PROOF_ENTRIES),
resource_proof: ResourceProof::new(RESOURCE_PROOF_DATA_SIZE, RESOURCE_PROOF_DIFFICULTY),
}
}

Expand Down Expand Up @@ -481,6 +478,10 @@ impl Approved {
}
}
}
Variant::Challenge { .. } => {
// Already approved, no need to resolve challenge.
return Ok(MessageStatus::Useless);
}
Variant::Sync { .. }
| Variant::Relocate(_)
| Variant::BootstrapRequest(_)
Expand Down Expand Up @@ -590,6 +591,10 @@ impl Approved {

Ok(vec![])
}
Variant::Challenge { .. } => {
trace!("Already got approved to join, no need to resolve challenge");
Ok(vec![])
}
}
}

Expand Down Expand Up @@ -1023,29 +1028,39 @@ impl Approved {
(MIN_AGE + 1, None, None)
};

if let Some((solution, data)) = join_request.resource_proof {
if let Some(nonce) = self.nonces.get(peer.name()) {
if self.resource_proof.validate_all(nonce, &data, solution) {
return self.vote(Vote::Online {
member_info: MemberInfo::joined(peer.with_age(age)),
previous_name,
their_knowledge,
});
}
if let Some(ResourceProofingProof {
solution,
data,
nonce,
signature,
}) = join_request.proof
{
let serialized = bincode::serialize(&(*peer.name(), nonce))?;
if self
.node
.keypair
.public
.verify(&serialized, &signature)
.is_ok()
&& self.resource_proof.validate_all(&nonce, &data, solution)
{
return self.vote(Vote::Online {
member_info: MemberInfo::joined(peer.with_age(age)),
previous_name,
their_knowledge,
});
}
}

let nonce: [u8; 32] = rand::random();
let _ = self.nonces.insert(*peer.name(), nonce);
let response = BootstrapResponse::ResourceProof {
let serialized = bincode::serialize(&(*peer.name(), nonce))?;
let response = Variant::Challenge {
data_size: RESOURCE_PROOF_DATA_SIZE,
difficulty: RESOURCE_PROOF_DIFF,
difficulty: RESOURCE_PROOF_DIFFICULTY,
nonce,
signature: crypto::sign(&serialized, &self.node.keypair),
};
Ok(vec![self.send_direct_message(
peer.addr(),
Variant::BootstrapResponse(response),
)?])
Ok(vec![self.send_direct_message(peer.addr(), response)?])
}

fn handle_dkg_start(
Expand Down
41 changes: 22 additions & 19 deletions src/routing/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
use super::{comm::ConnectionEvent, Comm};
use crate::{
consensus::Proven,
crypto,
crypto::{self, Signature},
error::{Error, Result},
location::DstLocation,
messages::{BootstrapResponse, JoinRequest, Message, Variant, VerifyStatus},
messages::{BootstrapResponse, JoinRequest, Message, Proof, Variant, VerifyStatus},
node::Node,
peer::Peer,
relocation::{RelocatePayload, SignedRelocateDetails},
Expand All @@ -33,7 +33,7 @@ const BACKLOG_CAPACITY: usize = 100;
/// NOTE: It's not guaranteed this function ever returns. This can happen due to messages being
/// lost in transit or other reasons. It's the responsibility of the caller to handle this case,
/// for example by using a timeout.
pub(crate) async fn adult(
pub(crate) async fn initial(
node: Node,
comm: &Comm,
incoming_conns: &mut mpsc::Receiver<ConnectionEvent>,
Expand Down Expand Up @@ -155,12 +155,6 @@ impl<'a> State<'a> {
);
bootstrap_addrs = new_bootstrap_addrs.to_vec();
}
BootstrapResponse::ResourceProof { .. } => {
error!(
"{} Received an unexpected ResourceProof request from {:?}",
self.node, sender,
);
}
}
}
}
Expand Down Expand Up @@ -236,7 +230,7 @@ impl<'a> State<'a> {

// Send `JoinRequest` and wait for the response. If the response is `Rejoin`, repeat with the
// new info. If it is `Approval`, returns the initial `Section` value to use by this node,
// completing the bootstrap. If it is `ResourceProff`, carries out a resource proof calculation.
// completing the bootstrap. If it is `Challenge`, carries out a resource proof calculation.
async fn join(
mut self,
elders_info: EldersInfo,
Expand All @@ -246,7 +240,7 @@ impl<'a> State<'a> {
let mut join_request = JoinRequest {
section_key,
relocate_payload: relocate_payload.clone(),
resource_proof: None,
proof: None,
};
let mut recipients: Vec<_> = elders_info
.elders
Expand Down Expand Up @@ -291,7 +285,7 @@ impl<'a> State<'a> {
join_request = JoinRequest {
section_key,
relocate_payload: relocate_payload.clone(),
resource_proof: None,
proof: None,
};
recipients = elders_info
.elders
Expand All @@ -306,19 +300,25 @@ impl<'a> State<'a> {
);
}
}
JoinResponse::ResourceProof {
JoinResponse::Challenge {
data_size,
difficulty,
nonce,
signature,
} => {
let rp = ResourceProof::new(data_size, difficulty);
let data = rp.create_proof_data(&nonce);
let mut prover = rp.create_prover(data.clone());
let proof = prover.solve();
let solution = prover.solve();
join_request = JoinRequest {
section_key,
relocate_payload: relocate_payload.clone(),
resource_proof: Some((proof, data)),
proof: Some(Proof {
solution,
data,
nonce,
signature,
}),
};
recipients.push(sender);
}
Expand Down Expand Up @@ -369,20 +369,22 @@ impl<'a> State<'a> {
sender,
));
}
Variant::BootstrapResponse(BootstrapResponse::ResourceProof {
Variant::Challenge {
data_size,
difficulty,
nonce,
}) => {
signature,
} => {
if !self.verify_message(&message, None) {
continue;
}

return Ok((
JoinResponse::ResourceProof {
JoinResponse::Challenge {
data_size: *data_size,
difficulty: *difficulty,
nonce: *nonce,
signature: *signature,
},
sender,
));
Expand Down Expand Up @@ -465,10 +467,11 @@ enum JoinResponse {
elders_info: EldersInfo,
section_key: bls::PublicKey,
},
ResourceProof {
Challenge {
data_size: usize,
difficulty: u8,
nonce: [u8; 32],
signature: Signature,
},
}

Expand Down
2 changes: 1 addition & 1 deletion src/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl Routing {
Comm::bootstrap(config.transport_config, connection_event_tx).await?;
let node = Node::new(keypair, comm.our_connection_info().await?);
let (node, section, backlog) =
bootstrap::adult(node, &comm, &mut connection_event_rx, bootstrap_addr).await?;
bootstrap::initial(node, &comm, &mut connection_event_rx, bootstrap_addr).await?;
let state = Approved::new(node, section, None, event_tx);

(state, comm, backlog)
Expand Down
Loading

0 comments on commit f67ae6c

Please sign in to comment.