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

Update their_keys on consensus about a section info #1716

Merged
merged 3 commits into from Jul 25, 2019

Conversation

fizyk20
Copy link
Contributor

@fizyk20 fizyk20 commented Jul 23, 2019

Closes #1671

Copy link
Contributor

@jeanphilippeD jeanphilippeD left a comment

Choose a reason for hiding this comment

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

Looks mostly reasonable, but I'm not clear how the edge cases will behave.

src/chain/shared_state.rs Outdated Show resolved Hide resolved
src/chain/shared_state.rs Outdated Show resolved Hide resolved
src/chain/shared_state.rs Outdated Show resolved Hide resolved
let mut state = SharedState::new(sec_0);

// add keys for neighbours 10 and 11
let pk_sec_10 = gen_pk(pfx_10);
Copy link
Contributor

Choose a reason for hiding this comment

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

What happen if we do not have pfx_10 or pfx_11?
What happen if we only have our side of the prefix when starting with pfx_0 (and we had a key when we were empty prefix).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What do you mean by "our side of the prefix"?
Also note that this starts with not having 10 or 11 in their_keys - they are simply inserted, then.

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant something like.

Start empty prefix.
Split -> Prefix0 & Prefix1
We are Prefix0, we do not have key for Prefix1?

(not sure it is possible, I guess we would have both key at the time of the split and so we would also always add Prefix1?).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the plan was that we'll have both keys from the DKGs we were running when preparing for the split (we'll have the private key share only from one of them, but we'll be able to obtain PublicKeySets from both).

Copy link
Contributor

Choose a reason for hiding this comment

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

So I guess the initial state should be:

        // our section is 0, so when we splited we have already added Prefix 1. 
        let sec_0 = gen_section_info(pfx_0);
        let mut state = SharedState::new(sec_0);
        let pk_sec_1 = gen_pk(pfx_1);
        state.update_their_keys(pfx_1, pk_sec_1.clone());

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could be. But I think the one in the test is also valid - we might have just become an elder of 0, and 10 and 11 might have already existed. We would then initialise the chain in a manner similar to what is in the test.

Copy link
Contributor

Choose a reason for hiding this comment

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

i'm not 100% sure that is the case, that bring a new thing to be careful about:
Are we doing the right thing when a new node join? (i.e is all the information necessary in Parsec).
Or after a split when I guess we are re-voting for all these sections info so new joining nodes get the right thing. Do we have the section re-consensused in order?

i.e should

             // Update their_keys in chain
            self.chain.update_their_keys(
                *sec_info.prefix(),
                BlsPublicKey::from_section_info(&sec_info),
            ); 

Take care of version number? Of parents consensused after children prefix?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are we doing the right thing when a new node join? (i.e is all the information necessary in Parsec).

I'm not sure if it is there, but we certainly were planning for it to be there - the whole shared state is supposed to be included in the Genesis event eventually (maybe it already is, I'm not sure).

So a joining node should receive the initial shared state from the Genesis event, and then any updates would result from other consensused events, which it would receive as well.

jeanphilippeD
jeanphilippeD previously approved these changes Jul 24, 2019
Copy link
Contributor

@jeanphilippeD jeanphilippeD left a comment

Choose a reason for hiding this comment

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

Everything looks good, just a comment that will probably be relevant for the future.


#[test]
fn single_prefix_multiple_updates() {
update_keys_and_check("0", vec!["1", "1", "1", "1"], vec![("1", 3)]);
Copy link
Contributor

Choose a reason for hiding this comment

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

The fact that we keep the last that we see suggest that we have to make sure not to add a old one after the new one.
i think I mention this somewhere, but we will probably need to care about version number at some point.
(Nothing to do for this PR.)

jeanphilippeD
jeanphilippeD previously approved these changes Jul 24, 2019
if let Some(&pfx) = self
.their_keys
.keys()
.find(|pfx| pfx.is_compatible(&prefix))
Copy link
Member

Choose a reason for hiding this comment

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

say the incoming prefix is 01, and we have 010 and 011, will this compatible check only make 010 to be updated?
or, we shall only keep one of the 010 or 011, due to the neighbouring rule ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should actually remove both 010 and 011 in such a case - but this situation can only happen if there is a merge, and we explicitly don't cater to merges for now. I could work on making this algorithm merge-safe, though, if we think it makes sense.

Copy link
Member

@maqi maqi Jul 24, 2019

Choose a reason for hiding this comment

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

Not sure about the plan of merge though. maybe @jeanphilippeD will be better to decide whether shall be merge-safe or not.
Or maybe at least put a comment to remind?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm OK with having a very short comment here that this will not handle merging prefixes.

let mut current_pfx = prefix.sibling();
while !self.their_keys.contains_key(&current_pfx) && current_pfx != old_pfx_sibling {
let _ = self.their_keys.insert(current_pfx, old_key.clone());
current_pfx = current_pfx.popped().sibling();
Copy link
Member

Choose a reason for hiding this comment

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

why a sibling after pop ?
is a pop enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we want to cover the whole address space that was covered by the old prefix.

Say we have a key for prefix 1 and receive one for prefix 1000. This means that 1 split at some point, but we don't know what the other sections are. We decide to just cover the space of prefix 1 with shortest possible prefixes, such that one of them is 1000 - this means we have to create entries for prefixes 1000, 1001, 101 and 11. So we have:

  • 1000 → sibling → 1001
  • 1001 → popped → 100 → sibling → 101
  • 101 → popped → 10 → sibling → 11

Copy link
Member

Choose a reason for hiding this comment

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

hmm...
does the with shortest possible prefixes from 1000 to 1 is : 1000 -> 100 -> 10 -> 1 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But we don't want to just go from 1000 to 1. We want prefixes that cover the whole address space that 1 was covering. Basically, we want a set of potential prefixes that 1 could have split into, provided that one of them is 1000.

If prefix 1000 exists on the network, then neither 1, nor 10, nor 100 can exist. But 11 can exist, and so can 101 and 1001.

}

#[cfg(test)]
/// Returns the relevant entry in their_keys if it exists
Copy link
Member

Choose a reason for hiding this comment

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

this function actually gives out their_keys if have ?
the comment of returns the relevant entry indicates it shall be something like get_their_keys(prefix) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, the old version of the function did that, but I forgot to change the comment. Good catch 👍

jeanphilippeD
jeanphilippeD previously approved these changes Jul 24, 2019
maqi
maqi previously approved these changes Jul 25, 2019
Copy link
Contributor

@jeanphilippeD jeanphilippeD left a comment

Choose a reason for hiding this comment

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

Great

@jeanphilippeD jeanphilippeD merged commit 64abdd5 into maidsafe:fleming Jul 25, 2019
@fizyk20 fizyk20 deleted the issue-1671 branch July 25, 2019 11:45
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.

Update their_keys (*) on consensus on receiving a message from that section
3 participants