Skip to content

Commit

Permalink
finished proposal creation and consensus state map update for manual …
Browse files Browse the repository at this point in the history
…view 2
  • Loading branch information
dailinsubjam committed Dec 19, 2023
1 parent b59d7af commit ce6d5d9
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 51 deletions.
33 changes: 20 additions & 13 deletions crates/hotshot/src/types/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{traits::NodeImplementation, types::Event, SystemContext};
use async_compatibility_layer::channel::UnboundedStream;
use async_lock::RwLock;
use commit::Committable;
use ethereum_types::U256;
use futures::Stream;
use hotshot_task::{
boxed_sync,
Expand All @@ -14,21 +15,18 @@ use hotshot_task::{
};
use hotshot_task_impls::events::HotShotEvent;
use hotshot_types::simple_vote::QuorumData;
use hotshot_types::traits::election::Membership;
use hotshot_types::traits::signature_key::SignatureKey;
use hotshot_types::{
consensus::Consensus,
error::HotShotError,
event::EventType,
message::{MessageKind, SequencingMessage},
traits::{
node_implementation::NodeType, state::ConsensusTime, storage::Storage,
},
traits::{node_implementation::NodeType, state::ConsensusTime, storage::Storage},
};
use hotshot_types::{data::Leaf, simple_certificate::QuorumCertificate};
use std::sync::Arc;
use tracing::error;
use hotshot_types::traits::election::Membership;
use ethereum_types::U256;
use hotshot_types::traits::signature_key::SignatureKey;

/// Event streaming handle for a [`SystemContext`] instance running in the background
///
Expand Down Expand Up @@ -201,22 +199,31 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES> + 'static> SystemContextHandl
}

// Below is for testing only:

/// Gets the current membership of the [`HotShot`] instance
#[cfg(feature = "hotshot-testing")]
pub fn get_committee_qc_stake_table(&self) -> Vec<<<TYPES as NodeType>::SignatureKey as SignatureKey>::StakeTableEntry>{
pub fn get_committee_qc_stake_table(
&self,
) -> Vec<<<TYPES as NodeType>::SignatureKey as SignatureKey>::StakeTableEntry> {
self.hotshot
.inner
.memberships
.quorum_membership.get_committee_qc_stake_table()
.inner
.memberships
.quorum_membership
.get_committee_qc_stake_table()
}

/// Gets the threshold of current membership of the [`HotShot`] instance
#[cfg(feature = "hotshot-testing")]
pub fn get_threshold(&self) -> U256 {
U256::from(self.hotshot.inner.memberships.quorum_membership.success_threshold().get())
U256::from(
self.hotshot
.inner
.memberships
.quorum_membership
.success_threshold()
.get(),
)
}


/// Wrapper for `HotShotConsensusApi`'s `get_leader` function
#[allow(clippy::unused_async)] // async for API compatibility reasons
Expand Down
13 changes: 9 additions & 4 deletions crates/task-impls/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,15 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, A: ConsensusApi<TYPES, I> +
// Check if we are able to vote, like whether the proposal is valid,
// whether we have DAC and VID share, and if so, vote.
async fn vote_if_able(&self) -> bool {
error!("Step 1 inside vote_if_able()"); // Sishan TODO: remove these error message
if !self.quorum_membership.has_stake(&self.public_key) {
debug!(
"We were not chosen for consensus committee on {:?}",
self.cur_view
);
return false;
}
error!("Step 2 inside vote_if_able()");
if let Some(proposal) = &self.current_proposal {
// ED Need to account for the genesis DA cert
// No need to check vid share nor da cert for genesis
Expand Down Expand Up @@ -230,7 +232,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, A: ConsensusApi<TYPES, I> +
return true;
}
}

error!("Step 3 inside vote_if_able(), going to check vid share");
// Only vote if you has seen the VID share for this view
if let Some(_vid_share) = self.vid_shares.get(&proposal.view_number) {
} else {
Expand Down Expand Up @@ -318,7 +320,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, A: ConsensusApi<TYPES, I> +
return true;
}
}
debug!(
error!( // Sishan TODO: change to debug level
"Received VID share, but couldn't find DAC cert in certs, meaning we haven't received it yet for view {:?}",
*proposal.get_view_number(),
);
Expand Down Expand Up @@ -436,7 +438,11 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, A: ConsensusApi<TYPES, I> +
warn!("Leader key does not match key in proposal");
return;
}
error!("Step 3, proposal.data.justify_qc.get_view_number() = {:?}, view - 1 = {:?}", proposal.data.justify_qc.get_view_number(), view - 1);
error!(
"Step 3, proposal.data.justify_qc.get_view_number() = {:?}, view - 1 = {:?}",
proposal.data.justify_qc.get_view_number(),
view - 1
);
// Verify a timeout certificate exists and is valid
if proposal.data.justify_qc.get_view_number() != view - 1 {
let Some(timeout_cert) = proposal.data.timeout_certificate.clone() else {
Expand Down Expand Up @@ -483,7 +489,6 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, A: ConsensusApi<TYPES, I> +
.cloned()
};

//
// Justify qc's leaf commitment is not the same as the parent's leaf commitment, but it should be (in this case)
let Some(parent) = parent else {
// If no parent then just update our state map and return. We will not vote.
Expand Down
86 changes: 54 additions & 32 deletions crates/testing/src/task_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ use hotshot_types::{
vote::HasViewNumber,
};

use hotshot_types::vote::Certificate;
use async_std::sync::RwLockUpgradableReadGuard;
use bincode::Options;
use bitvec::bitvec;
use hotshot_types::simple_vote::QuorumVote;
use hotshot_types::simple_vote::QuorumData;
use hotshot_types::simple_vote::QuorumVote;
use hotshot_types::utils::View;
use hotshot_types::utils::ViewInner;
use hotshot_types::vote::Certificate;
use hotshot_types::vote::Vote;
use hotshot_utils::bincode::bincode_opts;
use bincode::Options;
use tracing::error;

pub async fn build_system_handle(
Expand Down Expand Up @@ -112,15 +115,14 @@ pub async fn build_system_handle(
}

pub fn build_assembled_sig<
TYPES: NodeType<SignatureKey = BLSPubKey>,
VOTE: Vote<TYPES>,
CERT: Certificate<TYPES, Voteable = VOTE::Commitment>
>(
leaf: Leaf<TYPES>,
handle: &SystemContextHandle<TestTypes, MemoryImpl>,
view: TYPES::Time
TYPES: NodeType<SignatureKey = BLSPubKey>,
VOTE: Vote<TYPES>,
CERT: Certificate<TYPES, Voteable = VOTE::Commitment>,
>(
leaf: Leaf<TYPES>,
handle: &SystemContextHandle<TestTypes, MemoryImpl>,
view: TYPES::Time,
) -> <TYPES::SignatureKey as SignatureKey>::QCType {

// Assemble QC
let stake_table = handle.get_committee_qc_stake_table();
let real_qc_pp: <TYPES::SignatureKey as SignatureKey>::QCParams =
Expand All @@ -144,30 +146,30 @@ pub fn build_assembled_sig<
&private_key,
);
let original_signature: <TYPES::SignatureKey as SignatureKey>::PureAssembledSignatureType =
bincode_opts()
.deserialize(&vote.get_signature().0)
.expect("Deserialization on the signature shouldn't be able to fail.");
bincode_opts()
.deserialize(&vote.get_signature().0)
.expect("Deserialization on the signature shouldn't be able to fail.");
sig_lists.push(original_signature);
}

let real_qc_sig = <TYPES::SignatureKey as SignatureKey>::assemble(
&real_qc_pp,
signers.as_bitslice(),
&sig_lists[..],
&sig_lists[..],
);

real_qc_sig
real_qc_sig
}

pub fn build_qc<
TYPES: NodeType,
VOTE: Vote<TYPES, Commitment = QuorumData<TYPES>>,
CERT: Certificate<TYPES, Voteable = VOTE::Commitment>
>(
real_qc_sig: <TYPES::SignatureKey as SignatureKey>::QCType,
leaf: Leaf<TYPES>,
view: TYPES::Time,
public_key: &TYPES::SignatureKey,
VOTE: Vote<TYPES, Commitment = QuorumData<TYPES>>,
CERT: Certificate<TYPES, Voteable = VOTE::Commitment>,
>(
real_qc_sig: <TYPES::SignatureKey as SignatureKey>::QCType,
leaf: Leaf<TYPES>,
view: TYPES::Time,
public_key: &TYPES::SignatureKey,
private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
) -> CERT {
let vote = QuorumVote::<TYPES>::create_signed_vote(
Expand All @@ -193,8 +195,10 @@ async fn build_quorum_proposal_and_signature(
public_key: &BLSPubKey,
view: u64,
) -> (QuorumProposal<TestTypes>, EncodedSignature) {
let consensus_lock = handle.get_consensus();
let consensus = consensus_lock.read().await;
let temp_consensus = handle.get_consensus();
let cur_consensus = temp_consensus.upgradable_read().await;
let mut consensus = RwLockUpgradableReadGuard::upgrade(cur_consensus).await;

let api: HotShotConsensusApi<TestTypes, MemoryImpl> = HotShotConsensusApi {
inner: handle.hotshot.inner.clone(),
};
Expand All @@ -209,7 +213,6 @@ async fn build_quorum_proposal_and_signature(
panic!("Failed to find high QC parent.");
};
let parent_leaf = leaf.clone();
error!("parent_leaf's view = {:?}", parent_leaf.view_number);

// every event input is seen on the event stream in the output.
let block = <TestBlockPayload as TestableBlock>::genesis();
Expand All @@ -235,21 +238,40 @@ async fn build_quorum_proposal_and_signature(
};

if view == 2 {
let created_assembled_sig =
build_assembled_sig::<TestTypes, QuorumVote<TestTypes>, QuorumCertificate<TestTypes>>(leaf.clone(), handle, ViewNumber::new(1));
let created_qc = build_qc::<TestTypes, QuorumVote<TestTypes>, QuorumCertificate<TestTypes>>(created_assembled_sig, leaf.clone(), ViewNumber::new(1), public_key, private_key);
consensus.state_map.insert(
ViewNumber::new(1),
View {
view_inner: ViewInner::Leaf {
leaf: leaf.commit(),
},
},
);
consensus.saved_leaves.insert(leaf.commit(), leaf.clone());
let created_assembled_sig = build_assembled_sig::<
TestTypes,
QuorumVote<TestTypes>,
QuorumCertificate<TestTypes>,
>(leaf.clone(), handle, ViewNumber::new(1));
let created_qc = build_qc::<TestTypes, QuorumVote<TestTypes>, QuorumCertificate<TestTypes>>(
created_assembled_sig,
leaf.clone(),
ViewNumber::new(1),
public_key,
private_key,
);
let parent_leaf = leaf.clone();
let leaf_view2 = Leaf {
view_number: ViewNumber::new(2),
justify_qc: created_qc.clone(),
justify_qc: created_qc.clone(),
parent_commitment: parent_leaf.commit(),
block_header: block_header.clone(),
block_payload: None,
rejected: vec![],
timestamp: 0,
proposer_id: api.public_key().to_bytes(),
};
let signature_view2 = <BLSPubKey as SignatureKey>::sign(private_key, leaf_view2.commit().as_ref());
let signature_view2 =
<BLSPubKey as SignatureKey>::sign(private_key, leaf_view2.commit().as_ref());
let proposal_view2 = QuorumProposal::<TestTypes> {
block_header,
view_number: ViewNumber::new(2),
Expand All @@ -258,7 +280,7 @@ async fn build_quorum_proposal_and_signature(
proposer_id: leaf_view2.proposer_id,
};
error!("Have you really entered view 2?");
return (proposal_view2, signature_view2)
return (proposal_view2, signature_view2);
}

(proposal, signature)
Expand Down
3 changes: 1 addition & 2 deletions crates/testing/tests/consensus_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ async fn test_consensus_with_vid_vote() {
use hotshot_types::{
data::VidDisperse, message::Proposal, traits::node_implementation::NodeType,
};
use tracing::error;
use std::marker::PhantomData;

async_compatibility_layer::logging::setup_logging();
Expand Down Expand Up @@ -244,7 +243,7 @@ async fn test_consensus_with_vid_vote() {
tokio::test(flavor = "multi_thread", worker_threads = 2)
)]
#[cfg_attr(async_executor_impl = "async-std", async_std::test)]
#[ignore]
#[ignore] // Sishan TODO: delete this ignore later.
async fn test_consensus_no_vote_without_vid_share() {
use hotshot_task_impls::harness::run_harness;
use hotshot_testing::task_helpers::build_system_handle;
Expand Down

0 comments on commit ce6d5d9

Please sign in to comment.