Skip to content

Commit

Permalink
Merge branch 'main' into ss/leaf2
Browse files Browse the repository at this point in the history
  • Loading branch information
ss-es committed Oct 24, 2024
2 parents a9a7605 + 8068edc commit 088d7df
Show file tree
Hide file tree
Showing 96 changed files with 3,168 additions and 1,450 deletions.
163 changes: 87 additions & 76 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace.package]
version = "0.5.77" # same as `hotshot`, but workspace subcrate can also release its own version
version = "0.5.78" # same as `hotshot`, but workspace subcrate can also release its own version
authors = ["Espresso Systems <[email protected]>"]
edition = "2021"
rust-version = "1.76.0"
Expand All @@ -24,6 +24,7 @@ members = [
"crates/types",
"crates/builder-api",
"crates/fakeapi",
"crates/utils",
]
resolver = "2"

Expand Down
1 change: 1 addition & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
allowed-wildcard-imports = [ "utils", "hotshot_task_impls", "hotshot_types" ]
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
15 changes: 9 additions & 6 deletions crates/example-types/src/node_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use hotshot::traits::{
NodeImplementation,
};
use hotshot_types::{
data::ViewNumber,
data::{EpochNumber, ViewNumber},
signature_key::{BLSPubKey, BuilderKey},
traits::node_implementation::{NodeType, Versions},
};
Expand Down Expand Up @@ -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
22 changes: 11 additions & 11 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>>>,
proposals2: BTreeMap<TYPES::Time, Proposal<TYPES, QuorumProposal2<TYPES>>>,
das: HashMap<TYPES::View, Proposal<TYPES, DaProposal<TYPES>>>,
proposals: BTreeMap<TYPES::View, Proposal<TYPES, QuorumProposal<TYPES>>>,
proposals2: BTreeMap<TYPES::View, Proposal<TYPES, QuorumProposal2<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 @@ -50,7 +50,7 @@ impl<TYPES: NodeType> Default for TestStorageState<TYPES> {
proposals: BTreeMap::new(),
proposals2: BTreeMap::new(),
high_qc: None,
action: TYPES::Time::genesis(),
action: TYPES::View::genesis(),
}
}
}
Expand Down Expand Up @@ -88,7 +88,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 @@ -97,7 +97,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 @@ -160,7 +160,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 @@ -195,7 +195,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 All @@ -206,7 +206,7 @@ impl<TYPES: NodeType> Storage<TYPES> for TestStorage<TYPES> {
async fn update_undecided_state2(
&self,
_leafs: CommitmentMap<Leaf2<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
1 change: 1 addition & 0 deletions crates/fakeapi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ repository.workspace = true
toml = { workspace = true }
tide-disco = { workspace = true }
anyhow = { workspace = true }
async-compatibility-layer = { workspace = true }
hotshot-types = { path = "../types" }
vbs = { workspace = true }
serde = { workspace = true }
Expand Down
11 changes: 6 additions & 5 deletions crates/fakeapi/src/fake_solver.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::{
io::{self, ErrorKind},
thread, time,
time,
};

use anyhow::Result;
use async_compatibility_layer::art::async_sleep;
use async_lock::RwLock;
use futures::FutureExt;
use hotshot_example_types::auction_results_provider_types::TestAuctionResult;
Expand Down Expand Up @@ -83,7 +84,7 @@ impl FakeSolverState {
///
/// # Errors
/// Returns an error if the `should_fault` method is `Some`.
fn dump_builders(&self) -> Result<TestAuctionResult, ServerError> {
async fn dump_builders(&self) -> Result<TestAuctionResult, ServerError> {
if let Some(fault) = self.should_fault() {
match fault {
FakeSolverFaultType::InternalServerFault => {
Expand All @@ -94,7 +95,7 @@ impl FakeSolverState {
}
FakeSolverFaultType::TimeoutFault => {
// Sleep for the preconfigured 1 second timeout interval
thread::sleep(SOLVER_MAX_TIMEOUT_S);
async_sleep(SOLVER_MAX_TIMEOUT_S).await;
}
}
}
Expand Down Expand Up @@ -130,7 +131,7 @@ impl<TYPES: NodeType> FakeSolverApi<TYPES> for FakeSolverState {
&self,
_view_number: u64,
) -> Result<TestAuctionResult, ServerError> {
self.dump_builders()
self.dump_builders().await
}

/// Get the auction results with a valid signature.
Expand All @@ -139,7 +140,7 @@ impl<TYPES: NodeType> FakeSolverApi<TYPES> for FakeSolverState {
_view_number: u64,
_signature: &<TYPES::SignatureKey as SignatureKey>::PureAssembledSignatureType,
) -> Result<TestAuctionResult, ServerError> {
self.dump_builders()
self.dump_builders().await
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/hotshot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ sha2 = { workspace = true }
url = { workspace = true }
num_enum = "0.7"
parking_lot = "0.12"
utils = { path = "../utils" }

[target.'cfg(all(async_executor_impl = "tokio"))'.dependencies]
tokio = { workspace = true }
Expand Down
46 changes: 28 additions & 18 deletions crates/hotshot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,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 @@ -271,15 +271,19 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> SystemContext<T
let anchored_leaf = initializer.inner;
let instance_state = initializer.instance_state;

let (internal_tx, internal_rx) = internal_channel;
let (internal_tx, mut internal_rx) = internal_channel;
let (mut external_tx, mut external_rx) = external_channel;

let upgrade_lock =
UpgradeLock::<TYPES, V>::from_certificate(&initializer.decided_upgrade_certificate);

// Allow overflow on the channel, otherwise sending to it may block.
// Allow overflow on the external channel, otherwise sending to it may block.
external_rx.set_overflow(true);

// Allow overflow on the internal channel as well. We don't want to block consensus if we
// have a slow receiver
internal_rx.set_overflow(true);

// Get the validated state from the initializer or construct an incomplete one from the
// block header.
let validated_state = match initializer.validated_state {
Expand Down Expand Up @@ -321,9 +325,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 @@ -369,8 +381,6 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> SystemContext<T
/// Panics if sending genesis fails
#[instrument(skip_all, target = "SystemContext", fields(id = self.id))]
pub async fn start_consensus(&self) {
tracing::error!("HotShot is running with the dependency tasks feature enabled!!");

#[cfg(all(feature = "rewind", not(debug_assertions)))]
compile_error!("Cannot run rewind in production builds!");

Expand Down Expand Up @@ -412,7 +422,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 @@ -441,7 +451,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 @@ -579,7 +589,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 @@ -985,10 +995,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 @@ -999,9 +1009,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 @@ -1018,8 +1028,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 @@ -1041,13 +1051,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
Loading

0 comments on commit 088d7df

Please sign in to comment.