Skip to content

Commit

Permalink
Add epoch parameter in Membership trait's methods (#3751)
Browse files Browse the repository at this point in the history
* Add epoch parameter in `Membership` trait's methods

* Fixes for dependency-tasks tests

* Fix possible deadlock

* Add epoch_height to config file

* Rename `ViewTime` and `EpochTime` to `View` and `Epoch`
  • Loading branch information
lukaszrzasik authored Oct 18, 2024
1 parent 6e95ec6 commit bd68432
Show file tree
Hide file tree
Showing 67 changed files with 1,004 additions and 538 deletions.
2 changes: 1 addition & 1 deletion crates/example-types/src/auction_results_provider_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub struct TestAuctionResultsProvider<TYPES: NodeType> {
impl<TYPES: NodeType> AuctionResultsProvider<TYPES> for TestAuctionResultsProvider<TYPES> {
/// Mock fetching the auction results, with optional error injection to simulate failure cases
/// in the solver.
async fn fetch_auction_result(&self, view_number: TYPES::Time) -> Result<TYPES::AuctionResult> {
async fn fetch_auction_result(&self, view_number: TYPES::View) -> Result<TYPES::AuctionResult> {
if let Some(url) = &self.broadcast_url {
let resp =
reqwest::get(url.join(&format!("/v0/api/auction_results/{}", *view_number))?)
Expand Down
27 changes: 15 additions & 12 deletions crates/example-types/src/node_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
// You should have received a copy of the MIT License
// along with the HotShot repository. If not, see <https://mit-license.org/>.

use crate::{
auction_results_provider_types::{TestAuctionResult, TestAuctionResultsProvider},
block_types::{TestBlockHeader, TestBlockPayload, TestTransaction},
state_types::{TestInstanceState, TestValidatedState},
storage_types::TestStorage,
};
use hotshot::traits::{
election::{
randomized_committee::RandomizedCommittee, static_committee::StaticCommittee,
Expand All @@ -12,6 +18,7 @@ use hotshot::traits::{
implementations::{CombinedNetworks, Libp2pNetwork, MemoryNetwork, PushCdnNetwork},
NodeImplementation,
};
use hotshot_types::data::EpochNumber;
use hotshot_types::{
data::ViewNumber,
signature_key::{BLSPubKey, BuilderKey},
Expand All @@ -20,13 +27,6 @@ use hotshot_types::{
use serde::{Deserialize, Serialize};
use vbs::version::StaticVersion;

use crate::{
auction_results_provider_types::{TestAuctionResult, TestAuctionResultsProvider},
block_types::{TestBlockHeader, TestBlockPayload, TestTransaction},
state_types::{TestInstanceState, TestValidatedState},
storage_types::TestStorage,
};

#[derive(
Copy,
Clone,
Expand All @@ -45,7 +45,8 @@ use crate::{
pub struct TestTypes;
impl NodeType for TestTypes {
type AuctionResult = TestAuctionResult;
type Time = ViewNumber;
type View = ViewNumber;
type Epoch = EpochNumber;
type BlockHeader = TestBlockHeader;
type BlockPayload = TestBlockPayload;
type SignatureKey = BLSPubKey;
Expand Down Expand Up @@ -74,7 +75,8 @@ impl NodeType for TestTypes {
pub struct TestTypesRandomizedLeader;
impl NodeType for TestTypesRandomizedLeader {
type AuctionResult = TestAuctionResult;
type Time = ViewNumber;
type View = ViewNumber;
type Epoch = EpochNumber;
type BlockHeader = TestBlockHeader;
type BlockPayload = TestBlockPayload;
type SignatureKey = BLSPubKey;
Expand Down Expand Up @@ -103,7 +105,8 @@ impl NodeType for TestTypesRandomizedLeader {
pub struct TestConsecutiveLeaderTypes;
impl NodeType for TestConsecutiveLeaderTypes {
type AuctionResult = TestAuctionResult;
type Time = ViewNumber;
type View = ViewNumber;
type Epoch = EpochNumber;
type BlockHeader = TestBlockHeader;
type BlockPayload = TestBlockPayload;
type SignatureKey = BLSPubKey;
Expand Down Expand Up @@ -235,8 +238,8 @@ mod tests {

let data = TestData { data: 10 };

let view_0 = <TestTypes as NodeType>::Time::new(0);
let view_1 = <TestTypes as NodeType>::Time::new(1);
let view_0 = <TestTypes as NodeType>::View::new(0);
let view_1 = <TestTypes as NodeType>::View::new(1);

let versioned_data_0 =
VersionedVoteData::<TestTypes, TestData, MarketplaceTestVersions>::new(
Expand Down
18 changes: 9 additions & 9 deletions crates/example-types/src/storage_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ use hotshot_types::{
use crate::testable_delay::{DelayConfig, SupportedTraitTypesForAsyncDelay, TestableDelay};

type VidShares<TYPES> = HashMap<
<TYPES as NodeType>::Time,
<TYPES as NodeType>::View,
HashMap<<TYPES as NodeType>::SignatureKey, Proposal<TYPES, VidDisperseShare<TYPES>>>,
>;

#[derive(Clone, Debug)]
pub struct TestStorageState<TYPES: NodeType> {
vids: VidShares<TYPES>,
das: HashMap<TYPES::Time, Proposal<TYPES, DaProposal<TYPES>>>,
proposals: BTreeMap<TYPES::Time, Proposal<TYPES, QuorumProposal<TYPES>>>,
das: HashMap<TYPES::View, Proposal<TYPES, DaProposal<TYPES>>>,
proposals: BTreeMap<TYPES::View, Proposal<TYPES, QuorumProposal<TYPES>>>,
high_qc: Option<hotshot_types::simple_certificate::QuorumCertificate<TYPES>>,
action: TYPES::Time,
action: TYPES::View,
}

impl<TYPES: NodeType> Default for TestStorageState<TYPES> {
Expand All @@ -49,7 +49,7 @@ impl<TYPES: NodeType> Default for TestStorageState<TYPES> {
das: HashMap::new(),
proposals: BTreeMap::new(),
high_qc: None,
action: TYPES::Time::genesis(),
action: TYPES::View::genesis(),
}
}
}
Expand Down Expand Up @@ -87,7 +87,7 @@ impl<TYPES: NodeType> TestableDelay for TestStorage<TYPES> {
impl<TYPES: NodeType> TestStorage<TYPES> {
pub async fn proposals_cloned(
&self,
) -> BTreeMap<TYPES::Time, Proposal<TYPES, QuorumProposal<TYPES>>> {
) -> BTreeMap<TYPES::View, Proposal<TYPES, QuorumProposal<TYPES>>> {
self.inner.read().await.proposals.clone()
}
pub async fn high_qc_cloned(&self) -> Option<QuorumCertificate<TYPES>> {
Expand All @@ -96,7 +96,7 @@ impl<TYPES: NodeType> TestStorage<TYPES> {
pub async fn decided_upgrade_certificate(&self) -> Option<UpgradeCertificate<TYPES>> {
self.decided_upgrade_certificate.read().await.clone()
}
pub async fn last_actioned_view(&self) -> TYPES::Time {
pub async fn last_actioned_view(&self) -> TYPES::View {
self.inner.read().await.action
}
}
Expand Down Expand Up @@ -145,7 +145,7 @@ impl<TYPES: NodeType> Storage<TYPES> for TestStorage<TYPES> {

async fn record_action(
&self,
view: <TYPES as NodeType>::Time,
view: <TYPES as NodeType>::View,
action: hotshot_types::event::HotShotAction,
) -> Result<()> {
if self.should_return_err {
Expand Down Expand Up @@ -180,7 +180,7 @@ impl<TYPES: NodeType> Storage<TYPES> for TestStorage<TYPES> {
async fn update_undecided_state(
&self,
_leafs: CommitmentMap<Leaf<TYPES>>,
_state: BTreeMap<TYPES::Time, View<TYPES>>,
_state: BTreeMap<TYPES::View, View<TYPES>>,
) -> Result<()> {
if self.should_return_err {
bail!("Failed to update high qc to storage");
Expand Down
4 changes: 2 additions & 2 deletions crates/examples/infra/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ pub trait RunDa<
let start = Instant::now();

let mut event_stream = context.event_stream();
let mut anchor_view: TYPES::Time = <TYPES::Time as ConsensusTime>::genesis();
let mut anchor_view: TYPES::View = <TYPES::View as ConsensusTime>::genesis();
let mut num_successful_commits = 0;

context.hotshot.start_consensus().await;
Expand Down Expand Up @@ -563,7 +563,7 @@ pub trait RunDa<
.hotshot
.memberships
.quorum_membership
.committee_leaders(TYPES::Time::genesis())
.committee_leaders(TYPES::View::genesis(), TYPES::Epoch::genesis())
.len();
let total_num_views = usize::try_from(consensus.locked_view().u64()).unwrap();
// `failed_num_views` could include uncommitted views
Expand Down
36 changes: 22 additions & 14 deletions crates/hotshot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ pub struct SystemContext<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versi
instance_state: Arc<TYPES::InstanceState>,

/// The view to enter when first starting consensus
start_view: TYPES::Time,
start_view: TYPES::View,

/// Access to the output event stream.
output_event_stream: (Sender<Event<TYPES>>, InactiveReceiver<Event<TYPES>>),
Expand Down Expand Up @@ -302,9 +302,17 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> SystemContext<T
saved_payloads.insert(anchored_leaf.view_number(), Arc::clone(&encoded_txns));
}

let anchored_epoch = if config.epoch_height == 0 {
TYPES::Epoch::new(0)
} else if anchored_leaf.height() % config.epoch_height == 0 {
TYPES::Epoch::new(anchored_leaf.height() / config.epoch_height)
} else {
TYPES::Epoch::new(anchored_leaf.height() / config.epoch_height + 1)
};
let consensus = Consensus::new(
validated_state_map,
anchored_leaf.view_number(),
anchored_epoch,
anchored_leaf.view_number(),
anchored_leaf.view_number(),
initializer.actioned_view,
Expand Down Expand Up @@ -391,7 +399,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> SystemContext<T
self.internal_event_stream
.0
.broadcast_direct(Arc::new(HotShotEvent::ValidatedStateUpdated(
TYPES::Time::new(*self.start_view),
TYPES::View::new(*self.start_view),
validated_state.clone(),
)))
.await
Expand Down Expand Up @@ -420,7 +428,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> SystemContext<T
{
// Some applications seem to expect a leaf decide event for the genesis leaf,
// which contains only that leaf and nothing else.
if self.anchored_leaf.view_number() == TYPES::Time::genesis() {
if self.anchored_leaf.view_number() == TYPES::View::genesis() {
let (validated_state, state_delta) =
TYPES::ValidatedState::genesis(&self.instance_state);

Expand Down Expand Up @@ -558,7 +566,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> SystemContext<T
/// [`decided_state`](Self::decided_state)) or if there is no path for the requested
/// view to ever be decided.
#[instrument(skip_all, target = "SystemContext", fields(id = self.id))]
pub async fn state(&self, view: TYPES::Time) -> Option<Arc<TYPES::ValidatedState>> {
pub async fn state(&self, view: TYPES::View) -> Option<Arc<TYPES::ValidatedState>> {
self.consensus.read().await.state(view).cloned()
}

Expand Down Expand Up @@ -964,10 +972,10 @@ pub struct HotShotInitializer<TYPES: NodeType> {
state_delta: Option<Arc<<TYPES::ValidatedState as ValidatedState<TYPES>>::Delta>>,

/// Starting view number that should be equivelant to the view the node shut down with last.
start_view: TYPES::Time,
start_view: TYPES::View,
/// The view we last performed an action in. An action is Proposing or voting for
/// Either the quorum or DA.
actioned_view: TYPES::Time,
actioned_view: TYPES::View,
/// Highest QC that was seen, for genesis it's the genesis QC. It should be for a view greater
/// than `inner`s view number for the non genesis case because we must have seen higher QCs
/// to decide on the leaf.
Expand All @@ -978,9 +986,9 @@ pub struct HotShotInitializer<TYPES: NodeType> {
/// to vote and propose right away if they didn't miss anything while down.
undecided_leafs: Vec<Leaf<TYPES>>,
/// Not yet decided state
undecided_state: BTreeMap<TYPES::Time, View<TYPES>>,
undecided_state: BTreeMap<TYPES::View, View<TYPES>>,
/// Proposals we have sent out to provide to others for catchup
saved_proposals: BTreeMap<TYPES::Time, Proposal<TYPES, QuorumProposal<TYPES>>>,
saved_proposals: BTreeMap<TYPES::View, Proposal<TYPES, QuorumProposal<TYPES>>>,
}

impl<TYPES: NodeType> HotShotInitializer<TYPES> {
Expand All @@ -997,8 +1005,8 @@ impl<TYPES: NodeType> HotShotInitializer<TYPES> {
inner: Leaf::genesis(&validated_state, &instance_state).await,
validated_state: Some(Arc::new(validated_state)),
state_delta: Some(Arc::new(state_delta)),
start_view: TYPES::Time::new(0),
actioned_view: TYPES::Time::new(0),
start_view: TYPES::View::new(0),
actioned_view: TYPES::View::new(0),
saved_proposals: BTreeMap::new(),
high_qc,
decided_upgrade_certificate: None,
Expand All @@ -1020,13 +1028,13 @@ impl<TYPES: NodeType> HotShotInitializer<TYPES> {
anchor_leaf: Leaf<TYPES>,
instance_state: TYPES::InstanceState,
validated_state: Option<Arc<TYPES::ValidatedState>>,
start_view: TYPES::Time,
actioned_view: TYPES::Time,
saved_proposals: BTreeMap<TYPES::Time, Proposal<TYPES, QuorumProposal<TYPES>>>,
start_view: TYPES::View,
actioned_view: TYPES::View,
saved_proposals: BTreeMap<TYPES::View, Proposal<TYPES, QuorumProposal<TYPES>>>,
high_qc: QuorumCertificate<TYPES>,
decided_upgrade_certificate: Option<UpgradeCertificate<TYPES>>,
undecided_leafs: Vec<Leaf<TYPES>>,
undecided_state: BTreeMap<TYPES::Time, View<TYPES>>,
undecided_state: BTreeMap<TYPES::View, View<TYPES>>,
) -> Self {
Self {
inner: anchor_leaf,
Expand Down
3 changes: 2 additions & 1 deletion crates/hotshot/src/tasks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ pub fn add_network_event_task<
) {
let network_state: NetworkEventTaskState<_, V, _, _> = NetworkEventTaskState {
network,
view: TYPES::Time::genesis(),
view: TYPES::View::genesis(),
epoch: TYPES::Epoch::genesis(),
quorum_membership,
da_membership,
storage: Arc::clone(&handle.storage()),
Expand Down
10 changes: 9 additions & 1 deletion crates/hotshot/src/tasks/task_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState
return Self {
output_event_stream: handle.hotshot.external_event_stream.0.clone(),
cur_view: handle.cur_view().await,
cur_epoch: handle.cur_epoch().await,
quorum_membership: handle.hotshot.memberships.quorum_membership.clone().into(),
network: Arc::clone(&handle.hotshot.network),
vote_collectors: BTreeMap::default(),
Expand All @@ -91,6 +92,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState
return Self {
output_event_stream: handle.hotshot.external_event_stream.0.clone(),
cur_view: handle.cur_view().await,
cur_epoch: handle.cur_epoch().await,
quorum_membership: handle.hotshot.memberships.quorum_membership.clone().into(),
network: Arc::clone(&handle.hotshot.network),
vote_collector: None.into(),
Expand Down Expand Up @@ -118,6 +120,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState
Self {
consensus: OuterConsensus::new(handle.hotshot.consensus()),
cur_view: handle.cur_view().await,
cur_epoch: handle.cur_epoch().await,
vote_collector: None,
network: Arc::clone(&handle.hotshot.network),
membership: handle.hotshot.memberships.quorum_membership.clone().into(),
Expand All @@ -140,6 +143,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState
network: Arc::clone(&handle.hotshot.network),
quorum_membership: handle.hotshot.memberships.quorum_membership.clone().into(),
cur_view: handle.cur_view().await,
cur_epoch: handle.cur_epoch().await,
vote_collectors: BTreeMap::default(),
public_key: handle.public_key().clone(),
private_key: handle.private_key().clone(),
Expand All @@ -160,6 +164,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState
Self {
current_view: cur_view,
next_view: cur_view,
current_epoch: handle.cur_epoch().await,
network: Arc::clone(&handle.hotshot.network),
membership: handle.hotshot.memberships.quorum_membership.clone().into(),
public_key: handle.public_key().clone(),
Expand All @@ -171,7 +176,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState
finalize_relay_map: HashMap::default().into(),
view_sync_timeout: handle.hotshot.config.view_sync_timeout,
id: handle.hotshot.id,
last_garbage_collected_view: TYPES::Time::new(0),
last_garbage_collected_view: TYPES::View::new(0),
upgrade_lock: handle.hotshot.upgrade_lock.clone(),
}
}
Expand All @@ -187,6 +192,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState
output_event_stream: handle.hotshot.external_event_stream.0.clone(),
consensus: OuterConsensus::new(handle.hotshot.consensus()),
cur_view: handle.cur_view().await,
cur_epoch: handle.cur_epoch().await,
network: Arc::clone(&handle.hotshot.network),
membership: handle.hotshot.memberships.quorum_membership.clone().into(),
public_key: handle.public_key().clone(),
Expand Down Expand Up @@ -280,6 +286,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState
consensus: OuterConsensus::new(consensus),
cur_view: handle.cur_view().await,
cur_view_time: Utc::now().timestamp(),
cur_epoch: handle.cur_epoch().await,
network: Arc::clone(&handle.hotshot.network),
quorum_membership: handle.hotshot.memberships.quorum_membership.clone().into(),
timeout_membership: handle.hotshot.memberships.quorum_membership.clone().into(),
Expand Down Expand Up @@ -317,6 +324,7 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState
storage: Arc::clone(&handle.storage),
cur_view: handle.cur_view().await,
cur_view_time: Utc::now().timestamp(),
cur_epoch: handle.cur_epoch().await,
output_event_stream: handle.hotshot.external_event_stream.0.clone(),
timeout_task: async_spawn(async {}),
timeout: handle.hotshot.config.next_view_timeout,
Expand Down
Loading

0 comments on commit bd68432

Please sign in to comment.