Skip to content

Commit cf05798

Browse files
lints
1 parent 5b003b8 commit cf05798

3 files changed

Lines changed: 159 additions & 11 deletions

File tree

actor/src/mailbox.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ pub trait Policy: Sized {
9393
/// Overflow storage used by this policy.
9494
type Overflow: Overflow<Self>;
9595

96-
/// Handle `message` when it cannot enter the bounded ready queue immediately.
96+
/// Reliably handle `message` when it cannot enter the bounded ready queue immediately.
9797
///
9898
/// This may retain the message, coalesce it with retained work, replace older retained work,
9999
/// or deliberately do no work because the message is already satisfied, superseded, or no
@@ -116,7 +116,7 @@ pub trait UnreliablePolicy: Sized {
116116
/// Overflow storage used by this policy.
117117
type Overflow: Overflow<Self>;
118118

119-
/// Handle `message` when it cannot enter the bounded ready queue immediately.
119+
/// Unreliably handle `message` when it cannot enter the bounded ready queue immediately.
120120
///
121121
/// Returns `true` when the policy considered the message's effects. This includes retaining
122122
/// the message, coalescing it with retained work, replacing older retained work, or deliberately

consensus/src/simplex/scheme/bls12381_threshold/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! - [`standard`]: Certificates contain only a vote signature (requires half the computation to verify
66
//! partial signatures and recover threshold signatures as [`vrf`]).
77
//!
8-
//! - [`vrf`]: Certificates contain a vote signature and a view signature (a seed that can be used
8+
//! - [`vrf`]: Certificates contain a vote signature and a round signature (a seed that can be used
99
//! as a VRF).
1010
//!
1111
//! # Non-Attributable Signatures

consensus/src/simplex/scheme/bls12381_threshold/vrf.rs

Lines changed: 156 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! BLS12-381 threshold VRF implementation of the [`Scheme`] trait for `simplex`.
22
//!
3-
//! Certificates contain a vote signature and a view signature (a seed that can be used
3+
//! Certificates contain a vote signature and a round signature (a seed that can be used
44
//! as a VRF).
55
//!
66
//! # Using the VRF
@@ -314,7 +314,7 @@ where
314314
pub struct Signature<V: Variant> {
315315
/// Signature over the consensus vote message (partial or recovered aggregate).
316316
pub vote_signature: V::Signature,
317-
/// Signature over the per-view seed (partial or recovered aggregate).
317+
/// Signature over the per-round seed (partial or recovered aggregate).
318318
pub seed_signature: V::Signature,
319319
}
320320

@@ -833,18 +833,18 @@ impl<P: PublicKey, V: Variant> certificate::Scheme for Scheme<P, V> {
833833
let vote_message = context.message();
834834
entries.push((vote_namespace, vote_message, cert.vote_signature));
835835

836-
// Seed signatures are per-view, so multiple certificates for the same view
836+
// Seed signatures are per-round, so multiple certificates for the same round
837837
// (e.g., notarization and finalization) share the same seed. We only include
838838
// each unique seed once in the aggregate, but verify all certificates for a
839-
// view have matching seeds.
840-
if let Some(previous) = seeds.get(&context.view()) {
839+
// round have matching seeds.
840+
let seed_message = seed_message_from_subject(&context);
841+
if let Some(previous) = seeds.get(&seed_message) {
841842
if *previous != cert.seed_signature {
842843
return false;
843844
}
844845
} else {
845-
let seed_message = seed_message_from_subject(&context);
846-
entries.push((&namespace.seed, seed_message, cert.seed_signature));
847-
seeds.insert(context.view(), cert.seed_signature);
846+
entries.push((&namespace.seed, seed_message.clone(), cert.seed_signature));
847+
seeds.insert(seed_message, cert.seed_signature);
848848
}
849849
}
850850

@@ -2027,6 +2027,154 @@ mod tests {
20272027
verify_certificates_rejects_malleability::<MinSig>();
20282028
}
20292029

2030+
fn assemble_notarization_certificate<V: Variant>(
2031+
schemes: &[Scheme<V>],
2032+
proposal: &Proposal<Sha256Digest>,
2033+
) -> Certificate<V> {
2034+
let quorum = N3f1::quorum(schemes.len()) as usize;
2035+
let votes: Vec<_> = schemes
2036+
.iter()
2037+
.take(quorum)
2038+
.map(|scheme| scheme.sign(Subject::Notarize { proposal }).unwrap())
2039+
.collect();
2040+
2041+
schemes[0]
2042+
.assemble::<_, N3f1>(votes, &Sequential)
2043+
.expect("assemble notarization certificate")
2044+
}
2045+
2046+
fn assemble_finalization_certificate<V: Variant>(
2047+
schemes: &[Scheme<V>],
2048+
proposal: &Proposal<Sha256Digest>,
2049+
) -> Certificate<V> {
2050+
let quorum = N3f1::quorum(schemes.len()) as usize;
2051+
let votes: Vec<_> = schemes
2052+
.iter()
2053+
.skip(schemes.len() - quorum)
2054+
.map(|scheme| scheme.sign(Subject::Finalize { proposal }).unwrap())
2055+
.collect();
2056+
2057+
schemes[0]
2058+
.assemble::<_, N3f1>(votes, &Sequential)
2059+
.expect("assemble finalization certificate")
2060+
}
2061+
2062+
fn verify_certificates_accepts_shared_round_seed<V: Variant>() {
2063+
let mut rng = test_rng();
2064+
let (schemes, verifier) = setup_signers::<V>(4, 81);
2065+
let proposal = sample_proposal(Epoch::new(1), View::new(35), 19);
2066+
let notarization_certificate = assemble_notarization_certificate(&schemes, &proposal);
2067+
let finalization_certificate = assemble_finalization_certificate(&schemes, &proposal);
2068+
2069+
assert!(verifier.verify_certificates::<_, Sha256Digest, _, N3f1>(
2070+
&mut rng,
2071+
[
2072+
(
2073+
Subject::Notarize {
2074+
proposal: &proposal,
2075+
},
2076+
&notarization_certificate,
2077+
),
2078+
(
2079+
Subject::Finalize {
2080+
proposal: &proposal,
2081+
},
2082+
&finalization_certificate,
2083+
),
2084+
]
2085+
.into_iter(),
2086+
&Sequential,
2087+
));
2088+
}
2089+
2090+
#[test]
2091+
fn test_verify_certificates_accepts_shared_round_seed() {
2092+
verify_certificates_accepts_shared_round_seed::<MinPk>();
2093+
verify_certificates_accepts_shared_round_seed::<MinSig>();
2094+
}
2095+
2096+
fn verify_certificates_rejects_cross_epoch_seed_replay<V: Variant>() {
2097+
let mut rng = test_rng();
2098+
let (schemes, verifier) = setup_signers::<V>(4, 83);
2099+
let view = View::new(35);
2100+
let proposal1 = sample_proposal(Epoch::new(1), view, 19);
2101+
let proposal2 = sample_proposal(Epoch::new(2), view, 20);
2102+
let certificate1 = assemble_notarization_certificate(&schemes, &proposal1);
2103+
let certificate2 = assemble_notarization_certificate(&schemes, &proposal2);
2104+
2105+
assert!(verifier.verify_certificates::<_, Sha256Digest, _, N3f1>(
2106+
&mut rng,
2107+
[
2108+
(
2109+
Subject::Notarize {
2110+
proposal: &proposal1,
2111+
},
2112+
&certificate1,
2113+
),
2114+
(
2115+
Subject::Notarize {
2116+
proposal: &proposal2,
2117+
},
2118+
&certificate2,
2119+
),
2120+
]
2121+
.into_iter(),
2122+
&Sequential,
2123+
));
2124+
2125+
let cert1 = certificate1.get().unwrap();
2126+
let cert2 = certificate2.get().unwrap();
2127+
let forged_certificate2: Certificate<V> = Signature {
2128+
vote_signature: cert2.vote_signature,
2129+
seed_signature: cert1.seed_signature,
2130+
}
2131+
.into();
2132+
2133+
assert!(!verifier.verify_certificate::<_, Sha256Digest, N3f1>(
2134+
&mut rng,
2135+
Subject::Notarize {
2136+
proposal: &proposal2,
2137+
},
2138+
&forged_certificate2,
2139+
&Sequential,
2140+
));
2141+
2142+
let batch = [
2143+
(
2144+
Subject::Notarize {
2145+
proposal: &proposal1,
2146+
},
2147+
&certificate1,
2148+
),
2149+
(
2150+
Subject::Notarize {
2151+
proposal: &proposal2,
2152+
},
2153+
&forged_certificate2,
2154+
),
2155+
];
2156+
2157+
assert!(!verifier.verify_certificates::<_, Sha256Digest, _, N3f1>(
2158+
&mut rng,
2159+
batch.iter().copied(),
2160+
&Sequential,
2161+
));
2162+
assert_eq!(
2163+
verifier.verify_certificates_bisect::<_, Sha256Digest, N3f1>(
2164+
&mut rng,
2165+
&batch,
2166+
&Sequential,
2167+
),
2168+
vec![true, false],
2169+
);
2170+
}
2171+
2172+
#[test]
2173+
fn test_verify_certificates_rejects_cross_epoch_seed_replay() {
2174+
verify_certificates_rejects_cross_epoch_seed_replay::<MinPk>();
2175+
verify_certificates_rejects_cross_epoch_seed_replay::<MinSig>();
2176+
}
2177+
20302178
#[cfg(feature = "arbitrary")]
20312179
mod conformance {
20322180
use super::*;

0 commit comments

Comments
 (0)