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

Commit

Permalink
feat: keep the genesis key and use it for fallback proofs
Browse files Browse the repository at this point in the history
  • Loading branch information
madadam committed Mar 29, 2021
1 parent f325711 commit 99fb5ca
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 101 deletions.
4 changes: 2 additions & 2 deletions src/delivery_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ mod tests {
let elders0: Vec<_> = elders_info0.peers().copied().collect();
let elders_info0 = proven(&sk, elders_info0)?;

let mut section = Section::new(chain, elders_info0)?;
let mut section = Section::new(pk, chain, elders_info0)?;

for peer in elders0 {
let member_info = MemberInfo::joined(peer);
Expand Down Expand Up @@ -434,7 +434,7 @@ mod tests {

let (elders_info, _) = gen_elders_info(prefix0, ELDER_SIZE);
let elders_info = proven(&sk, elders_info)?;
let section = Section::new(chain, elders_info)?;
let section = Section::new(pk, chain, elders_info)?;

let network = Network::new();
let our_name = section.prefix().substituted_in(rand::random());
Expand Down
21 changes: 16 additions & 5 deletions src/messages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,21 @@ impl Message {
new_first_key: &bls::PublicKey,
full_chain: &SectionChain,
) -> Result<Self, ExtendProofChainError> {
if let Some(proof_chain) = &mut self.proof_chain {
*proof_chain = proof_chain.extend(new_first_key, full_chain)?
} else {
return Err(ExtendProofChainError::NoProofChain);
}
let proof_chain = self
.proof_chain
.as_mut()
.ok_or(ExtendProofChainError::NoProofChain)?;

*proof_chain = match proof_chain.extend(new_first_key, full_chain) {
Ok(chain) => chain,
Err(SectionChainError::InvalidOperation) => {
// This means the tip of the proof chain is not reachable from `new_first_key`.
// Extend it from the root key of the full chain instead as that should be the
// genesis key which is implicitly trusted.
proof_chain.extend(full_chain.root_key(), full_chain)?
}
Err(error) => return Err(error.into()),
};

Ok(Self::new_signed(
self.src,
Expand Down Expand Up @@ -516,6 +526,7 @@ mod tests {
let member_info = consensus::test_utils::proven(&sk1, member_info)?;

let variant = Variant::NodeApproval {
genesis_key: pk0,
elders_info,
member_info,
};
Expand Down
4 changes: 4 additions & 0 deletions src/messages/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub(crate) enum Variant {
/// Message sent to newly joined node containing the necessary info to become a member of our
/// section.
NodeApproval {
genesis_key: bls::PublicKey,
elders_info: Proven<EldersInfo>,
member_info: Proven<MemberInfo>,
},
Expand Down Expand Up @@ -127,6 +128,7 @@ impl Variant {
Self::NodeApproval {
elders_info,
member_info,
..
} => {
let proof_chain = proof_chain.ok_or(Error::InvalidMessage)?;

Expand Down Expand Up @@ -171,10 +173,12 @@ impl Debug for Variant {
.finish(),
Self::UserMessage(payload) => write!(f, "UserMessage({:10})", HexFmt(payload)),
Self::NodeApproval {
genesis_key,
elders_info,
member_info,
} => f
.debug_struct("NodeApproval")
.field("genesis_key", genesis_key)
.field("elders_info", elders_info)
.field("member_info", member_info)
.finish(),
Expand Down
2 changes: 1 addition & 1 deletion src/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ mod tests {
);
let elders_info = proven(&sk, elders_info)?;

let mut section = Section::new(SectionChain::new(pk), elders_info)?;
let mut section = Section::new(pk, SectionChain::new(pk), elders_info)?;

for peer in &peers {
let info = MemberInfo::joined(*peer);
Expand Down
4 changes: 3 additions & 1 deletion src/routing/approved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,8 @@ impl Approved {
.section
.chain()
.keys()
.chain(self.network.keys().map(|(_, key)| key));
.chain(self.network.keys().map(|(_, key)| key))
.chain(iter::once(self.section.genesis_key()));

match msg.verify(known_keys) {
Ok(VerifyStatus::Full) => Ok(true),
Expand Down Expand Up @@ -1836,6 +1837,7 @@ impl Approved {
)?;

let variant = Variant::NodeApproval {
genesis_key: *self.section.genesis_key(),
elders_info: self.section.proven_elders_info().clone(),
member_info,
};
Expand Down
32 changes: 24 additions & 8 deletions src/routing/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub(crate) async fn initial(
let state = State::new(node, send_tx, recv_rx);

future::join(
state.run(vec![bootstrap_addr], None),
state.run(vec![bootstrap_addr], None, None),
send_messages(send_rx, comm),
)
.instrument(span)
Expand All @@ -73,6 +73,7 @@ pub(crate) async fn relocate(
comm: &Comm,
recv_rx: mpsc::Receiver<(MessageType, SocketAddr)>,
bootstrap_addrs: Vec<SocketAddr>,
genesis_key: bls::PublicKey,
relocate_details: SignedRelocateDetails,
) -> Result<(Node, Section, Vec<(Message, SocketAddr)>)> {
let (send_tx, send_rx) = mpsc::channel(1);
Expand All @@ -81,7 +82,7 @@ pub(crate) async fn relocate(
let state = State::new(node, send_tx, recv_rx);

future::join(
state.run(bootstrap_addrs, Some(relocate_details)),
state.run(bootstrap_addrs, Some(genesis_key), Some(relocate_details)),
send_messages(send_rx, comm),
)
.await
Expand Down Expand Up @@ -115,6 +116,7 @@ impl<'a> State<'a> {
async fn run(
mut self,
bootstrap_addrs: Vec<SocketAddr>,
genesis_key: Option<bls::PublicKey>,
relocate_details: Option<SignedRelocateDetails>,
) -> Result<(Node, Section, Vec<(Message, SocketAddr)>)> {
let (prefix, section_key, elders) = self
Expand All @@ -127,7 +129,8 @@ impl<'a> State<'a> {
None
};

self.join(section_key, elders, relocate_payload).await
self.join(section_key, elders, genesis_key, relocate_payload)
.await
}

// Send a `GetSectionQuery` and waits for the response. If the response is `Redirect`,
Expand Down Expand Up @@ -282,6 +285,7 @@ impl<'a> State<'a> {
mut self,
mut section_key: bls::PublicKey,
elders: BTreeMap<XorName, SocketAddr>,
genesis_key: Option<bls::PublicKey>,
relocate_payload: Option<RelocatePayload>,
) -> Result<(Node, Section, Vec<(Message, SocketAddr)>)> {
let join_request = JoinRequest {
Expand All @@ -294,18 +298,19 @@ impl<'a> State<'a> {

loop {
let (response, sender) = self
.receive_join_response(relocate_payload.as_ref())
.receive_join_response(genesis_key.as_ref(), relocate_payload.as_ref())
.await?;

match response {
JoinResponse::Approval {
elders_info,
age,
genesis_key,
section_chain,
} => {
return Ok((
self.node.with_age(age),
Section::new(section_chain, elders_info)?,
Section::new(genesis_key, section_chain, elders_info)?,
self.backlog.into_iter().collect(),
));
}
Expand Down Expand Up @@ -386,6 +391,7 @@ impl<'a> State<'a> {

async fn receive_join_response(
&mut self,
expected_genesis_key: Option<&bls::PublicKey>,
relocate_payload: Option<&RelocatePayload>,
) -> Result<(JoinResponse, SocketAddr)> {
while let Some((message, sender)) = self.recv_rx.next().await {
Expand Down Expand Up @@ -441,6 +447,7 @@ impl<'a> State<'a> {
));
}
Variant::NodeApproval {
genesis_key,
elders_info,
member_info,
} => {
Expand All @@ -449,6 +456,13 @@ impl<'a> State<'a> {
continue;
}

if let Some(expected_genesis_key) = expected_genesis_key {
if expected_genesis_key != genesis_key {
error!("Unexpected Genesis key");
continue;
}
}

let trusted_key = if let Some(payload) = relocate_payload {
Some(&payload.relocate_details().destination_key)
} else {
Expand All @@ -459,7 +473,6 @@ impl<'a> State<'a> {
continue;
}

// Transition from Joining to Approved
let section_chain = message.proof_chain()?.clone();

info!(
Expand All @@ -471,6 +484,7 @@ impl<'a> State<'a> {
JoinResponse::Approval {
elders_info: elders_info.clone(),
age: member_info.value.peer.age(),
genesis_key: *genesis_key,
section_chain,
},
sender,
Expand Down Expand Up @@ -515,6 +529,7 @@ enum JoinResponse {
Approval {
elders_info: Proven<EldersInfo>,
age: u8,
genesis_key: bls::PublicKey,
section_chain: SectionChain,
},
Retry {
Expand Down Expand Up @@ -613,7 +628,7 @@ mod tests {
// Create the bootstrap task, but don't run it yet.
let bootstrap = async move {
state
.run(vec![bootstrap_addr], None)
.run(vec![bootstrap_addr], None, None)
.await
.map_err(Error::from)
};
Expand Down Expand Up @@ -667,6 +682,7 @@ mod tests {
&bootstrap_node,
DstLocation::Direct,
Variant::NodeApproval {
genesis_key: pk,
elders_info,
member_info,
},
Expand Down Expand Up @@ -906,7 +922,7 @@ mod tests {
let elders = (0..ELDER_SIZE)
.map(|_| (good_prefix.substituted_in(rand::random()), gen_addr()))
.collect();
let join_task = state.join(section_key, elders, None);
let join_task = state.join(section_key, elders, None, None);

let test_task = async {
let (message, _) = send_rx
Expand Down
3 changes: 2 additions & 1 deletion src/routing/lazy_messaging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,8 @@ mod tests {
let node = nodes.remove(0);

let elders_info0 = proven(&our_sk, elders_info0)?;
let section = Section::new(chain, elders_info0).context("failed to create section")?;
let section = Section::new(*chain.root_key(), chain, elders_info0)
.context("failed to create section")?;

let (elders_info1, _) = gen_elders_info(prefix1, ELDER_SIZE);
let elders_info1 = proven(&our_sk, elders_info1)?;
Expand Down
2 changes: 1 addition & 1 deletion src/routing/split_barrier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ mod tests {
let elders_info = EldersInfo::new(elders, Prefix::default());
let elders_info = proven(&sk, elders_info)?;

let mut section = Section::new(chain, elders_info)?;
let mut section = Section::new(pk, chain, elders_info)?;

for peer in members0.iter().chain(&members1).copied() {
let info = MemberInfo::joined(peer);
Expand Down
16 changes: 13 additions & 3 deletions src/routing/stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,21 @@ impl Stage {
details: SignedRelocateDetails,
message_rx: mpsc::Receiver<(MessageType, SocketAddr)>,
) -> Result<Vec<Command>> {
let node = self.state.lock().await.node().clone();
let (genesis_key, node) = {
let state = self.state.lock().await;
(*state.section().genesis_key(), state.node().clone())
};
let previous_name = node.name();

let (node, section, backlog) =
bootstrap::relocate(node, &self.comm, message_rx, bootstrap_addrs, details).await?;
let (node, section, backlog) = bootstrap::relocate(
node,
&self.comm,
message_rx,
bootstrap_addrs,
genesis_key,
details,
)
.await?;

let mut state = self.state.lock().await;
let event_tx = state.event_tx.clone();
Expand Down
Loading

0 comments on commit 99fb5ca

Please sign in to comment.