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

MAID-1839 feature/routing: resource_proof #1261

Closed
wants to merge 68 commits into from

Conversation

maqi
Copy link
Member

@maqi maqi commented Dec 6, 2016

No description provided.

@maidsafe-highfive
Copy link

r? @afck

(maidsafe_highfive has picked a reviewer for you, use r? to override)

(&mut self,
expected_name: &XorName,
our_public_id: &PublicId)
-> Result<(bool, (Prefix<XorName>, Vec<PublicId>)), RoutingTableError> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Better to use a named struct instead of a tuple of a tuple? Or at least update the function's documentation to explain what gets returned.

Copy link
Member Author

Choose a reason for hiding this comment

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

updated function documentation to explain what gets returned.


let (prefix, names) = self.routing_table.expect_join_our_group(expected_name)?;

if names.len() > 8 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't hard-code 8 here. I think you want routing_table.min_group_size().

@@ -258,6 +269,8 @@ pub struct PeerManager {
proxy_peer_id: Option<PeerId>,
routing_table: RoutingTable<XorName>,
our_public_id: PublicId,
node_candidate: Option<(XorName, Instant, Vec<u8>)>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Please document these fields (within the struct with comments)

if let Some((name, now, _)) = self.node_candidate {
if name == *expected_name ||
now.elapsed() < Duration::from_secs(RESOURCE_PROOF_APPROVE_TIMEOUT_SECS) {
return Err(RoutingTableError::AlreadyExists);
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if AlreadyExists is the right error (especially considering there are two different causes), but it will do for now (better in my opinion to either return or log a more specific message).

let (prefix, names) = self.routing_table.expect_join_our_group(expected_name)?;

if names.len() > 8 {
self.node_candidate = None;
Copy link
Contributor

Choose a reason for hiding this comment

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

Useless line since it's changed again just below?

let seed = rng.gen_iter().take(10).collect();
self.node_candidate = Some((*expected_name, Instant::now(), seed));
} else {
return Ok((false, (prefix, vec![])));
Copy link
Contributor

Choose a reason for hiding this comment

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

What are we returning? Would love a comment, unless you switch to a struct with named method describing what this is.

Copy link
Member Author

Choose a reason for hiding this comment

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

updated function documentation to explain what gets returned.

None
}

pub fn handle_node_approval_vote(&mut self,
Copy link
Contributor

Choose a reason for hiding this comment

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

Also document the return value please

Copy link
Contributor

@dhardy dhardy left a comment

Choose a reason for hiding this comment

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

I didn't review the complete algorithm. Code doesn't look bad other than a couple of names and missing doc. Could you also update the message flow documentation (messages.rs:438 onwards)?

(false, None)
}

pub fn handle_node_approval(&mut self) -> Vec<(PublicId, PeerId)> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you think of a better name (collect_peer_ids?), and add a line of documentation please?

result
}

pub fn is_node_candidate(&mut self,
Copy link
Contributor

Choose a reason for hiding this comment

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

I would assume a method named is_... would just check whether some property is true, but this also updates the peer state. Could you at least add documentation of this, if not also find a better name?

Ok(None)
}

pub fn is_peer_candidate(&mut self, pub_id: &PublicId, peer_id: &PeerId) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above

Some(PeerState::AwaitingNodeIdentify(true)) => true,
Some(PeerState::Routing(_tunnel)) => {
error!("PeerCandidate {:?} already in state Routing.", peer_id);
return true;
Copy link
Contributor

Choose a reason for hiding this comment

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

If the function returns here the peer gets removed from the peer_map without replacement. I don't think this was intended?

Some(PeerState::AwaitingNodeIdentify(true)) => true,
Some(PeerState::Routing(_tunnel)) => {
error!("NodeCandidate {:?} already in state Routing.", peer_id);
return Err(RoutingTableError::AlreadyExists);
Copy link
Contributor

Choose a reason for hiding this comment

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

If the function returns here the peer gets removed from the peer_map without replacement. I don't think this was intended?

/// Returns the collection of groups to which a peer joining our group should connect.
///
/// This will generally be all the groups in our routing table. However, if the addition of the
/// new node will cause our group to split, only the groups which will remain neighbours after
/// the split are returned. Returns `Err(Error::PeerNameUnsuitable)` if `name` is not within
/// our group, or `Err(Error::AlreadyExists)` if `name` is already in our table.
pub fn expect_add_to_our_group(&self, name: &T) -> Result<Groups<T>, Error> {
pub fn get_groups(&self, name: &T) -> Result<Groups<T>, Error> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we call this get_sections_to_join? The problem is that it calculates what to do if the join would cause a split... I'd love to remove this logic later but for now lets just acknowledge it in the name?

}

/// Wraps the routing table function of the same name and maps `XorName`s to `PublicId`s.
pub fn get_groups(&self,
Copy link
Contributor

Choose a reason for hiding this comment

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

If RoutingTable::get_groups is renamed this one might need to be too

if tunnel {
/// if connection is in tunnel, vote NO directly, don't carry out profiling
/// limitation: joining node ONLY carries out QUORAM valid connection/evaluations
info!("{:?} Sending CandidateApproval false to group rejeting {:?}.",
Copy link
Contributor

Choose a reason for hiding this comment

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

/rejeting/rejecting/

/// answer that request (resolving a hashing challenge) with `ResourceProofResponse`. Member of Y
/// will sends out `CandidateApproval` to vote for the approval in group. Once approved, member of Y
/// add A into its routing_table and send `NodeApproval` to A. On receiving first `NodeApproval`, A
/// adds members of Y into its routing_table.
Copy link
Contributor

@dhardy dhardy Dec 12, 2016

Choose a reason for hiding this comment

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

When nodes Z of section Y receive NodeIdentify from A, they respond with a ResourceProof request. Node A needs to answer these requests (resolving a hashing challenge) with ResourceProofResponse. Members of Y will send out CandidateApproval messages to vote for the approval in their section. Once the vote succeeds, the members of Y add A to their routing table and send NodeApproval to A. When A receives the first NodeApproval message, it adds the members of Y to its routing table.


Don't mind the corrections; your English is pretty good, but I still think this is a little easier to understand ;). Copy the source version to get the back-ticks.

groups: Vec<(Prefix<XorName>, Vec<PublicId>)>,
dst: Authority<XorName>) {
if !self.peer_mgr.routing_table().is_empty() {
warn!("{:?} Received duplicate GetNodeName response.", self);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is GetNodeName right here?

a node may receive CandidateApproval before connection established
PeerSate::Candidate needs to be considered in
peer_manager::connection_info_received
@maqi maqi force-pushed the resource_proof branch 2 times, most recently from 05d0a20 to 58ae4af Compare December 15, 2016 14:08

self.get_approval_timer_token = None;

self.peer_mgr.add_prefixes(sections.keys().into_iter().map(|&prefix| prefix).collect_vec());
Copy link
Contributor

Choose a reason for hiding this comment

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

You can use cloned() instead of map(…).

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, since this modifies the RT's Prefixes, we should add the following:

trace!("{:?} Node approved. Prefixes: {:?}", self, self.peer_mgr.routing_table().prefixes());

if validity {
let sections = self.peer_mgr.pub_ids_by_section();
info!("{:?} Sending NodeApproval to {:?}.", self, candidate_name);
let _ = self.send_routing_message(RoutingMessage {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's not ignore the result here.

maqi and others added 20 commits January 17, 2017 18:16
# Conflicts:
#	src/peer_manager.rs
#	src/routing_table/mod.rs
#	src/states/node.rs
…s out GetNodeNameResponse till receives AcceptAsCandidate
refactor/all: adds 'CandidateIdentify' message and handling
use accumulation timeout to calculate timeout for sending candidate approval
…nto routing table when send out NodeApproval
refactor/all: update resource proof functions
fix/peer_manager: fix incorrect filter closures
@afck
Copy link
Contributor

afck commented Jan 20, 2017

Included in #1319

@afck afck closed this Jan 20, 2017
@maqi maqi deleted the resource_proof branch March 11, 2017 14:02
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants