Skip to content

Commit 48503c2

Browse files
authored
Merge branch 'main' into jp/rename-in-docs
2 parents 9b83e11 + b904f76 commit 48503c2

28 files changed

+827
-97
lines changed

hotshot-example-types/src/block_types.rs

+16
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,22 @@ impl TestBlockHeader {
298298
}
299299
}
300300

301+
impl Default for TestBlockHeader {
302+
fn default() -> Self {
303+
let metadata = TestMetadata {
304+
num_transactions: 0,
305+
};
306+
Self {
307+
block_number: 0,
308+
payload_commitment: Default::default(),
309+
builder_commitment: Default::default(),
310+
metadata,
311+
timestamp: 0,
312+
random: 0,
313+
}
314+
}
315+
}
316+
301317
impl<
302318
TYPES: NodeType<
303319
BlockHeader = Self,

hotshot-example-types/src/node_types.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ pub use hotshot::traits::election::helpers::{
1111
};
1212
use hotshot::traits::{
1313
election::{
14-
helpers::QuorumFilterConfig, randomized_committee::Committee,
15-
randomized_committee_members::RandomizedCommitteeMembers,
14+
dummy_catchup_membership::DummyCatchupCommittee, helpers::QuorumFilterConfig,
15+
randomized_committee::Committee, randomized_committee_members::RandomizedCommitteeMembers,
1616
static_committee::StaticCommittee,
1717
static_committee_leader_two_views::StaticCommitteeLeaderForTwoViews,
1818
two_static_committees::TwoStaticCommittees,
@@ -101,6 +101,36 @@ impl NodeType for TestTypesRandomizedLeader {
101101
type BuilderSignatureKey = BuilderKey;
102102
}
103103

104+
#[derive(
105+
Copy,
106+
Clone,
107+
Debug,
108+
Default,
109+
Hash,
110+
PartialEq,
111+
Eq,
112+
PartialOrd,
113+
Ord,
114+
serde::Serialize,
115+
serde::Deserialize,
116+
)]
117+
pub struct TestTypesEpochCatchupTypes;
118+
impl NodeType for TestTypesEpochCatchupTypes {
119+
const UPGRADE_CONSTANTS: UpgradeConstants = TEST_UPGRADE_CONSTANTS;
120+
121+
type AuctionResult = TestAuctionResult;
122+
type View = ViewNumber;
123+
type Epoch = EpochNumber;
124+
type BlockHeader = TestBlockHeader;
125+
type BlockPayload = TestBlockPayload;
126+
type SignatureKey = BLSPubKey;
127+
type Transaction = TestTransaction;
128+
type ValidatedState = TestValidatedState;
129+
type InstanceState = TestInstanceState;
130+
type Membership = DummyCatchupCommittee<TestTypesEpochCatchupTypes>;
131+
type BuilderSignatureKey = BuilderKey;
132+
}
133+
104134
#[derive(
105135
Copy,
106136
Clone,

hotshot-query-service/src/data_source/update.rs

+45-16
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ use anyhow::{ensure, Context};
2222
use async_trait::async_trait;
2323
use futures::future::Future;
2424
use hotshot::types::{Event, EventType};
25-
use hotshot_types::data::{VidDisperseShare, VidShare};
25+
use hotshot_types::{data::VidCommitment, event::LeafInfo};
2626
use hotshot_types::{
27-
data::Leaf2,
27+
data::{ns_table::parse_ns_table, Leaf2},
2828
traits::{
2929
block_contents::{BlockHeader, BlockPayload, EncodeBytes, GENESIS_VID_NUM_STORAGE_NODES},
3030
node_implementation::{ConsensusTime, NodeType},
3131
},
3232
vid::advz::advz_scheme,
3333
};
34-
use hotshot_types::{data::VidCommitment, event::LeafInfo};
34+
use hotshot_types::{
35+
data::{VidDisperseShare, VidShare},
36+
vid::avidm::{init_avidm_param, AvidMScheme},
37+
};
3538
use jf_vid::VidScheme;
3639
use std::iter::once;
3740

@@ -168,19 +171,45 @@ fn genesis_vid<Types: NodeType>(
168171
) -> anyhow::Result<(VidCommonQueryData<Types>, VidShare)> {
169172
let payload = Payload::<Types>::empty().0;
170173
let bytes = payload.encode();
171-
let mut disperse = advz_scheme(GENESIS_VID_NUM_STORAGE_NODES)
172-
.disperse(bytes)
173-
.context("unable to compute VID dispersal for genesis block")?;
174-
ensure!(
175-
VidCommitment::V0(disperse.commit) == leaf.block_header().payload_commitment(),
176-
"computed VID commit {} for genesis block does not match header commit {}",
177-
disperse.commit,
178-
leaf.block_header().payload_commitment()
179-
);
180-
Ok((
181-
VidCommonQueryData::new(leaf.block_header().clone(), Some(disperse.common)),
182-
VidShare::V0(disperse.shares.remove(0)),
183-
))
174+
175+
match leaf.block_header().payload_commitment() {
176+
VidCommitment::V0(commit) => {
177+
let mut disperse = advz_scheme(GENESIS_VID_NUM_STORAGE_NODES)
178+
.disperse(bytes)
179+
.context("unable to compute VID dispersal for genesis block")?;
180+
181+
ensure!(
182+
disperse.commit == commit,
183+
"computed VID commit {} for genesis block does not match header commit {}",
184+
disperse.commit,
185+
commit
186+
);
187+
Ok((
188+
VidCommonQueryData::new(leaf.block_header().clone(), Some(disperse.common)),
189+
VidShare::V0(disperse.shares.remove(0)),
190+
))
191+
}
192+
VidCommitment::V1(commit) => {
193+
let avidm_param = init_avidm_param(GENESIS_VID_NUM_STORAGE_NODES)?;
194+
let weights = vec![1; GENESIS_VID_NUM_STORAGE_NODES];
195+
let ns_table = parse_ns_table(bytes.len(), &leaf.block_header().metadata().encode());
196+
197+
let (calculated_commit, mut shares) =
198+
AvidMScheme::ns_disperse(&avidm_param, &weights, &bytes, ns_table).unwrap();
199+
200+
ensure!(
201+
calculated_commit == commit,
202+
"computed VID commit {} for genesis block does not match header commit {}",
203+
calculated_commit,
204+
commit
205+
);
206+
207+
Ok((
208+
VidCommonQueryData::new(leaf.block_header().clone(), None),
209+
VidShare::V1(shares.remove(0)),
210+
))
211+
}
212+
}
184213
}
185214

186215
/// A data source with an atomic transaction-based synchronization interface.

hotshot-testing/tests/tests_1/da_task.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ async fn test_da_task() {
4747
&[],
4848
membership
4949
.membership_for_epoch(None)
50-
.await.unwrap()
50+
.await
51+
.unwrap()
5152
.total_nodes()
5253
.await,
5354
default_version,
@@ -162,17 +163,16 @@ async fn test_da_task_storage_failure() {
162163
&[],
163164
membership
164165
.membership_for_epoch(None)
165-
.await.unwrap()
166+
.await
167+
.unwrap()
166168
.total_nodes()
167169
.await,
168170
default_version,
169171
);
170172

171-
let mut generator = TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
173+
let mut generator =
174+
TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
172175

173-
let mut proposals = Vec::new();
174-
let mut leaders = Vec::new();
175-
let mut votes = Vec::new();
176176
let mut dacs = Vec::new();
177177
let mut vids = Vec::new();
178178

hotshot-testing/tests/tests_1/quorum_proposal_task.rs

+20-11
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ async fn test_quorum_proposal_task_quorum_proposal_view_1() {
5050
let membership = handle.hotshot.membership_coordinator.clone();
5151
let epoch_1_mem = membership
5252
.membership_for_epoch(Some(EpochNumber::new(1)))
53-
.await.unwrap();
53+
.await
54+
.unwrap();
5455
let version = handle
5556
.hotshot
5657
.upgrade_lock
@@ -64,7 +65,8 @@ async fn test_quorum_proposal_task_quorum_proposal_view_1() {
6465
)
6566
.await;
6667

67-
let mut generator = TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
68+
let mut generator =
69+
TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
6870

6971
let mut proposals = Vec::new();
7072
let mut leaders = Vec::new();
@@ -151,7 +153,8 @@ async fn test_quorum_proposal_task_quorum_proposal_view_gt_1() {
151153
let membership = handle.hotshot.membership_coordinator.clone();
152154
let epoch_1_mem = membership
153155
.membership_for_epoch(Some(EpochNumber::new(1)))
154-
.await.unwrap();
156+
.await
157+
.unwrap();
155158

156159
let mut generator =
157160
TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
@@ -328,23 +331,25 @@ async fn test_quorum_proposal_task_qc_timeout() {
328331
build_system_handle::<TestTypes, MemoryImpl, TestVersions>(node_id).await;
329332
let membership = handle.hotshot.membership_coordinator.clone();
330333
let epoch_1_mem = membership
331-
.membership_for_epoch(Some(EpochNumber::new(1)))
332-
.await.unwrap();
334+
.membership_for_epoch(Some(EpochNumber::new(1)))
335+
.await
336+
.unwrap();
333337
let version = handle
334338
.hotshot
335339
.upgrade_lock
336340
.version_infallible(ViewNumber::new(node_id))
337341
.await;
338342

339343
let payload_commitment = build_payload_commitment::<TestTypes, TestVersions>(
340-
&epoch_1_mem,
344+
&epoch_1_mem,
341345
ViewNumber::new(node_id),
342346
version,
343347
)
344348
.await;
345349
let builder_commitment = BuilderCommitment::from_raw_digest(sha2::Sha256::new().finalize());
346350

347-
let mut generator = TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
351+
let mut generator =
352+
TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
348353

349354
let mut proposals = Vec::new();
350355
let mut leaders = Vec::new();
@@ -425,7 +430,8 @@ async fn test_quorum_proposal_task_view_sync() {
425430
let membership = handle.hotshot.membership_coordinator.clone();
426431
let epoch_1_mem = membership
427432
.membership_for_epoch(Some(EpochNumber::new(1)))
428-
.await.unwrap();
433+
.await
434+
.unwrap();
429435
let version = handle
430436
.hotshot
431437
.upgrade_lock
@@ -440,7 +446,8 @@ async fn test_quorum_proposal_task_view_sync() {
440446
.await;
441447
let builder_commitment = BuilderCommitment::from_raw_digest(sha2::Sha256::new().finalize());
442448

443-
let mut generator = TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
449+
let mut generator =
450+
TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
444451

445452
let mut proposals = Vec::new();
446453
let mut leaders = Vec::new();
@@ -521,9 +528,11 @@ async fn test_quorum_proposal_task_liveness_check() {
521528
let membership = handle.hotshot.membership_coordinator.clone();
522529
let epoch_1_mem = membership
523530
.membership_for_epoch(Some(EpochNumber::new(1)))
524-
.await.unwrap();
531+
.await
532+
.unwrap();
525533

526-
let mut generator = TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
534+
let mut generator =
535+
TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
527536

528537
let mut proposals = Vec::new();
529538
let mut leaders = Vec::new();

hotshot-testing/tests/tests_1/upgrade_task_with_proposal.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,11 @@ async fn test_upgrade_task_with_proposal() {
8585
let membership = handle.hotshot.membership_coordinator.clone();
8686
let epoch_1_mem = membership
8787
.membership_for_epoch(Some(EpochNumber::new(1)))
88-
.await.unwrap();
88+
.await
89+
.unwrap();
8990

90-
let mut generator = TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
91+
let mut generator =
92+
TestViewGenerator::<TestVersions>::generate(membership.clone(), node_key_map);
9193

9294
for view in (&mut generator).take(1).collect::<Vec<_>>().await {
9395
proposals.push(view.quorum_proposal.clone());

hotshot-testing/tests/tests_6/test_epochs.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use hotshot_example_types::{
99
CombinedImpl, EpochUpgradeTestVersions, EpochsTestVersions, Libp2pImpl, MemoryImpl,
1010
PushCdnImpl, RandomOverlapQuorumFilterConfig, StableQuorumFilterConfig,
1111
TestConsecutiveLeaderTypes, TestTwoStakeTablesTypes, TestTypes,
12-
TestTypesRandomizedCommitteeMembers, TestTypesRandomizedLeader,
12+
TestTypesRandomizedCommitteeMembers, TestTypesRandomizedLeader, TestTypesEpochCatchupTypes
1313
},
1414
testable_delay::{DelayConfig, DelayOptions, DelaySettings, SupportedTraitTypesForAsyncDelay},
1515
};
@@ -52,6 +52,7 @@ cross_tests!(
5252
Impls: [MemoryImpl, Libp2pImpl, PushCdnImpl],
5353
Types: [
5454
TestTypes,
55+
TestTypesEpochCatchupTypes,
5556
TestTypesRandomizedLeader,
5657
TestTypesRandomizedCommitteeMembers<StableQuorumFilterConfig<123, 2>>, // Overlap = F
5758
TestTypesRandomizedCommitteeMembers<StableQuorumFilterConfig<123, 3>>, // Overlap = F+1

hotshot-types/src/consensus.rs

+4
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,10 @@ impl<TYPES: NodeType> Consensus<TYPES> {
922922
self.saved_leaves.get(&leaf).unwrap().clone()
923923
}
924924

925+
pub fn undecided_leaves(&self) -> Vec<Leaf2<TYPES>> {
926+
self.saved_leaves.values().cloned().collect::<Vec<_>>()
927+
}
928+
925929
/// Gets the validated state with the given view number, if in the state map.
926930
#[must_use]
927931
pub fn state(&self, view_number: TYPES::View) -> Option<&Arc<TYPES::ValidatedState>> {

hotshot-types/src/epoch_membership.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,24 @@ where
120120
};
121121

122122
// Get the epoch root headers and update our membership with them, finally sync them
123-
// Verification of the root is handled in get_epoch_root
124-
let (next_epoch, header) = root_membership
125-
.get_epoch_root(root_block_in_epoch(*root_epoch, self.epoch_height))
123+
// Verification of the root is handled in get_epoch_root_and_drb
124+
let Ok((header, drb)) = root_membership
125+
.get_epoch_root_and_drb(root_block_in_epoch(*root_epoch, self.epoch_height))
126126
.await
127-
.ok_or(anytrace::warn!("get epoch root failed"))?;
127+
else {
128+
anytrace::bail!("get epoch root failed for epoch {:?}", root_epoch);
129+
};
128130
let updater = self
129131
.membership
130132
.read()
131133
.await
132-
.add_epoch_root(next_epoch, header)
134+
.add_epoch_root(epoch, header)
133135
.await
134136
.ok_or(anytrace::warn!("add epoch root failed"))?;
135137
updater(&mut *(self.membership.write().await));
136138

139+
self.membership.write().await.add_drb_result(epoch, drb);
140+
137141
Ok(EpochMembership {
138142
epoch: Some(epoch),
139143
coordinator: self.clone(),
@@ -212,15 +216,18 @@ impl<TYPES: NodeType> EpochMembership<TYPES> {
212216
}
213217

214218
/// Wraps the same named Membership trait fn
215-
async fn get_epoch_root(
219+
async fn get_epoch_root_and_drb(
216220
&self,
217221
block_height: u64,
218-
) -> Option<(TYPES::Epoch, TYPES::BlockHeader)> {
222+
) -> anyhow::Result<(TYPES::BlockHeader, DrbResult)> {
223+
let Some(epoch) = self.epoch else {
224+
anyhow::bail!("Cannot get root for None epoch");
225+
};
219226
self.coordinator
220227
.membership
221228
.read()
222229
.await
223-
.get_epoch_root(block_height)
230+
.get_epoch_root_and_drb(block_height, self.coordinator.epoch_height, epoch)
224231
.await
225232
}
226233

hotshot-types/src/traits/election.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,17 @@ pub trait Membership<TYPES: NodeType>: Debug + Send + Sync {
128128

129129
/// Gets the validated block header and epoch number of the epoch root
130130
/// at the given block height
131-
fn get_epoch_root(
131+
fn get_epoch_root_and_drb(
132132
&self,
133-
block_height: u64,
134-
) -> impl std::future::Future<Output = Option<(TYPES::Epoch, TYPES::BlockHeader)>> + Send;
133+
_block_height: u64,
134+
_epoch_height: u64,
135+
_epoch: TYPES::Epoch,
136+
) -> impl std::future::Future<Output = anyhow::Result<(TYPES::BlockHeader, DrbResult)>> + Send
137+
{
138+
async {
139+
anyhow::bail!("Not implemented");
140+
}
141+
}
135142

136143
#[allow(clippy::type_complexity)]
137144
/// Handles notifications that a new epoch root has been created

0 commit comments

Comments
 (0)