-
Notifications
You must be signed in to change notification settings - Fork 81
MAID-1839 feature/routing: resource_proof #1261
Conversation
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> { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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>)>, |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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![]))); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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
There was a problem hiding this 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)> { |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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 {:?}.", |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
05d0a20
to
58ae4af
Compare
resource_proof; resolve clippy failures
…en adding prefixes
|
||
self.get_approval_timer_token = None; | ||
|
||
self.peer_mgr.add_prefixes(sections.keys().into_iter().map(|&prefix| prefix).collect_vec()); |
There was a problem hiding this comment.
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(…)
.
There was a problem hiding this comment.
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 Prefix
es, 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 { |
There was a problem hiding this comment.
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.
…e of it after plit
# Conflicts: # src/peer_manager.rs # src/routing_table/mod.rs # src/states/node.rs
Merge master
…s out GetNodeNameResponse till receives AcceptAsCandidate
refactor/all: adds 'CandidateIdentify' message and handling
…ng candidate approval
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
Included in #1319 |
No description provided.