Skip to content

Commit 38d2305

Browse files
[marshal] Start at Anchor (#3855)
1 parent 86f9be7 commit 38d2305

13 files changed

Lines changed: 762 additions & 110 deletions

File tree

consensus/conformance.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ hash = "51b04637257c54cecdc4e5ded4568efccafbc08f20be3fe0951369cab43ba2b6"
2222
n_cases = 65536
2323
hash = "e53b4b684f0344590427aae976d298e3b6fd2b08ef46ff2cad5def04b4f7690b"
2424

25+
["commonware_consensus::marshal::conformance::CodingStorageConformance"]
26+
n_cases = 32
27+
hash = "9234e6644b5aaf723be352e7e17b8613efafb7e80869e8dffe8b5527c04128ef"
28+
29+
["commonware_consensus::marshal::conformance::StandardStorageConformance"]
30+
n_cases = 32
31+
hash = "05033526f41131ceb367df9177c4090d9670d6ea0119d8478211f894e2d557d7"
32+
2533
["commonware_consensus::marshal::resolver::handler::tests::conformance::CodecConformance<Key<D>>"]
2634
n_cases = 65536
2735
hash = "481cd68f2e6452c0dda512c75d74ddd2e19ac6c9fb19c642c1a152a0d830c1b2"

consensus/src/marshal/coding/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,11 @@ mod tests {
779779
harness::ack_pipeline_backlog_persists_on_restart::<CodingHarness>();
780780
}
781781

782+
#[test_traced("WARN")]
783+
fn test_coding_genesis_emitted_once() {
784+
harness::genesis_emitted_once::<CodingHarness>();
785+
}
786+
782787
#[test_traced("WARN")]
783788
fn test_coding_proposed_success_implies_recoverable_after_restart() {
784789
harness::proposed_success_implies_recoverable_after_restart::<CodingHarness>(0..16);

consensus/src/marshal/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::num::{NonZeroU64, NonZeroUsize};
1818
pub enum Start<S: Scheme, C: Digest, B> {
1919
/// Start from the height-zero genesis block.
2020
Genesis(B),
21-
/// Start from an already-processed finalized commitment.
21+
/// Start from a finalized commitment.
2222
Floor(Finalization<S, C>),
2323
}
2424

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//! Marshal storage conformance tests.
2+
3+
use super::mocks::{
4+
application::Application,
5+
harness::{
6+
self, CodingHarness, StandardHarness, TestHarness, ValidatorHandle, ValidatorSetup,
7+
BLOCKS_PER_EPOCH, NAMESPACE, NUM_VALIDATORS, QUORUM, V,
8+
},
9+
};
10+
use crate::{
11+
simplex::{scheme::bls12381_threshold::vrf as bls12381_threshold_vrf, types::Proposal},
12+
types::{Epoch, Height, Round, View},
13+
};
14+
use commonware_conformance::{conformance_tests, Conformance};
15+
use commonware_cryptography::certificate::{mocks::Fixture, ConstantProvider};
16+
use commonware_runtime::{deterministic, Clock, Runner, Supervisor as _};
17+
use commonware_utils::NZUsize;
18+
use rand::Rng;
19+
use std::time::Duration;
20+
21+
const CASES: usize = 32;
22+
23+
struct StandardStorageConformance;
24+
struct CodingStorageConformance;
25+
26+
impl Conformance for StandardStorageConformance {
27+
async fn commit(seed: u64) -> Vec<u8> {
28+
marshal_commit::<StandardHarness>(seed)
29+
}
30+
}
31+
32+
impl Conformance for CodingStorageConformance {
33+
async fn commit(seed: u64) -> Vec<u8> {
34+
marshal_commit::<CodingHarness>(seed)
35+
}
36+
}
37+
38+
fn marshal_commit<H: TestHarness>(seed: u64) -> Vec<u8> {
39+
let runner = deterministic::Runner::new(
40+
deterministic::Config::default()
41+
.with_seed(seed)
42+
.with_timeout(Some(Duration::from_secs(30))),
43+
);
44+
runner.start(|mut context| async move {
45+
let Fixture {
46+
participants,
47+
schemes,
48+
..
49+
} = bls12381_threshold_vrf::fixture::<V, _>(&mut context, NAMESPACE, NUM_VALIDATORS);
50+
let mut oracle = harness::setup_network_with_participants(
51+
context.child("network"),
52+
NZUsize!(1),
53+
participants.clone(),
54+
)
55+
.await;
56+
57+
let validator = participants[0].clone();
58+
let provider = ConstantProvider::new(schemes[0].clone());
59+
let application = Application::<H::ApplicationBlock>::manual_ack();
60+
let setup = H::setup_validator_with(
61+
context.child("validator"),
62+
&mut oracle,
63+
validator,
64+
provider,
65+
NZUsize!(1),
66+
application,
67+
)
68+
.await;
69+
70+
assert_eq!(setup.application.acknowledged().await, Height::zero());
71+
wait_processed(&mut context, &setup, Height::zero()).await;
72+
73+
let mut handle = ValidatorHandle::<H> {
74+
mailbox: setup.mailbox.clone(),
75+
extra: setup.extra.clone(),
76+
};
77+
let mut peers = Vec::<ValidatorHandle<H>>::new();
78+
let mut parent = H::genesis_block(NUM_VALIDATORS as u16);
79+
let count = context.gen_range(1..=BLOCKS_PER_EPOCH.get().min(4));
80+
for height in 1..=count {
81+
let height = Height::new(height);
82+
let round = Round::new(Epoch::zero(), View::new(height.get()));
83+
let parent_view = height
84+
.previous()
85+
.map_or(View::zero(), |h| View::new(h.get()));
86+
let block = H::make_test_block(
87+
H::digest(&parent),
88+
H::commitment(&parent),
89+
height,
90+
context.gen(),
91+
NUM_VALIDATORS as u16,
92+
);
93+
H::verify(&mut handle, round, &block, &mut peers).await;
94+
95+
let proposal = Proposal::new(round, parent_view, H::commitment(&block));
96+
let finalization = H::make_finalization(proposal, &schemes, QUORUM);
97+
let mut mailbox = setup.mailbox.clone();
98+
H::report_finalization(&mut mailbox, finalization).await;
99+
100+
assert_eq!(setup.application.acknowledged().await, height);
101+
wait_processed(&mut context, &setup, height).await;
102+
parent = block;
103+
}
104+
105+
setup.actor_handle.abort();
106+
let _ = setup.actor_handle.await;
107+
context.storage_audit().to_vec()
108+
})
109+
}
110+
111+
async fn wait_processed<H: TestHarness>(
112+
context: &mut deterministic::Context,
113+
setup: &ValidatorSetup<H>,
114+
height: Height,
115+
) {
116+
loop {
117+
if setup.mailbox.get_processed_height().await == Some(height) {
118+
break;
119+
}
120+
context.sleep(Duration::from_millis(1)).await;
121+
}
122+
}
123+
124+
conformance_tests! {
125+
StandardStorageConformance => CASES,
126+
CodingStorageConformance => CASES,
127+
}

consensus/src/marshal/core/acks.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ impl<V: Variant, A: Acknowledgement> PendingAcks<V, A> {
6262
}
6363

6464
/// Returns the next height to dispatch while preserving sequential order.
65-
pub(super) fn next_dispatch_height(&self, last_processed_height: Height) -> Height {
65+
pub(super) fn next_dispatch_height(&self, start_height: Height) -> Height {
6666
self.queue
6767
.back()
6868
.map(|ack| ack.height.next())
6969
.or_else(|| self.current.as_ref().map(|ack| ack.height.next()))
70-
.unwrap_or_else(|| last_processed_height.next())
70+
.unwrap_or(start_height)
7171
}
7272

7373
/// Enqueues a newly dispatched ack, arming it immediately when idle.
@@ -136,18 +136,18 @@ mod tests {
136136
fn enqueue_tracks_capacity_and_fifo_ready_order() {
137137
let mut pending = PendingAcks::<TestVariant, Exact>::new(2);
138138
assert!(pending.has_capacity());
139-
assert_eq!(pending.next_dispatch_height(Height::new(7)), Height::new(8));
139+
assert_eq!(pending.next_dispatch_height(Height::new(8)), Height::new(8));
140140

141141
let (first, first_ack) = pending_ack(8, 1);
142142
pending.enqueue(first);
143143
assert!(pending.has_capacity());
144-
assert_eq!(pending.next_dispatch_height(Height::new(7)), Height::new(9));
144+
assert_eq!(pending.next_dispatch_height(Height::new(8)), Height::new(9));
145145

146146
let (second, second_ack) = pending_ack(9, 2);
147147
pending.enqueue(second);
148148
assert!(!pending.has_capacity());
149149
assert_eq!(
150-
pending.next_dispatch_height(Height::new(7)),
150+
pending.next_dispatch_height(Height::new(8)),
151151
Height::new(10)
152152
);
153153

@@ -185,7 +185,7 @@ mod tests {
185185
assert!(pending.pop_ready().is_none());
186186
assert!(pending.has_capacity());
187187
assert_eq!(
188-
pending.next_dispatch_height(Height::new(9)),
188+
pending.next_dispatch_height(Height::new(10)),
189189
Height::new(10)
190190
);
191191
}

0 commit comments

Comments
 (0)