use crate::allocator::CertificateReceipt;
use crate::proposal::mix64;
use crate::stability::StabilityCandidate;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct CertificateBindings {
pub admitted_graph: u64,
pub generated_payload: u64,
pub kernel_specialization_identity: u64,
pub numeric_profile: u64,
pub q_registry: u64,
pub pricing_law: u64,
pub floor_law: u64,
pub control_mode: u64,
pub influence_state: u64,
pub comparison_derivation: u64,
pub round_identity: u64,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum CertificationRefusal {
WitnessMarginInsufficient,
AdmittedGraphMismatch,
GeneratedPayloadMismatch,
KernelSpecializationIdentityMismatch,
NumericProfileMismatch,
QRegistryMismatch,
PricingLawMismatch,
FloorLawMismatch,
ControlModeMismatch,
InfluenceStateMismatch,
ComparisonDerivationMismatch,
RoundIdentityMismatch,
}
impl core::fmt::Display for CertificationRefusal {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
core::fmt::Debug::fmt(self, f)
}
}
#[cfg(feature = "std")]
impl std::error::Error for CertificationRefusal {}
#[allow(deprecated)] pub fn seal_certificate(
candidate: StabilityCandidate,
actual: CertificateBindings,
expected: CertificateBindings,
) -> Result<CertificateReceipt, CertificationRefusal> {
if !witness_holds(&candidate) {
return Err(CertificationRefusal::WitnessMarginInsufficient);
}
if actual.admitted_graph != expected.admitted_graph {
return Err(CertificationRefusal::AdmittedGraphMismatch);
}
if actual.generated_payload != expected.generated_payload {
return Err(CertificationRefusal::GeneratedPayloadMismatch);
}
if actual.kernel_specialization_identity != expected.kernel_specialization_identity {
return Err(CertificationRefusal::KernelSpecializationIdentityMismatch);
}
if actual.numeric_profile != expected.numeric_profile {
return Err(CertificationRefusal::NumericProfileMismatch);
}
if actual.q_registry != expected.q_registry {
return Err(CertificationRefusal::QRegistryMismatch);
}
if actual.pricing_law != expected.pricing_law {
return Err(CertificationRefusal::PricingLawMismatch);
}
if actual.floor_law != expected.floor_law {
return Err(CertificationRefusal::FloorLawMismatch);
}
if actual.control_mode != expected.control_mode {
return Err(CertificationRefusal::ControlModeMismatch);
}
if actual.influence_state != expected.influence_state {
return Err(CertificationRefusal::InfluenceStateMismatch);
}
if actual.comparison_derivation != expected.comparison_derivation {
return Err(CertificationRefusal::ComparisonDerivationMismatch);
}
if actual.round_identity != expected.round_identity {
return Err(CertificationRefusal::RoundIdentityMismatch);
}
let seal_digest = seal_digest(&candidate, &actual);
Ok(CertificateReceipt::admit_certificate(seal_digest))
}
#[inline(always)]
fn witness_holds(candidate: &StabilityCandidate) -> bool {
let scale = crate::stability::SCALE as i128;
let g = candidate.g();
let d = candidate.d();
let one_minus_delta = scale - candidate.margin_delta() as i128;
for r in 0..crate::stability::DIM {
let mut acc: i128 = 0;
for c in 0..crate::stability::DIM {
acc += (g[r][c] as i128) * (d[c] as i128);
}
let gd = acc / scale;
let bound = (one_minus_delta * d[r] as i128) / scale;
if gd > bound {
return false;
}
}
true
}
#[inline(always)]
fn seal_digest(candidate: &StabilityCandidate, bindings: &CertificateBindings) -> u64 {
let mut d = mix64(candidate.candidate_digest(), bindings.admitted_graph);
d = mix64(d, bindings.generated_payload);
d = mix64(d, bindings.kernel_specialization_identity);
d = mix64(d, bindings.numeric_profile);
d = mix64(d, bindings.q_registry);
d = mix64(d, bindings.pricing_law);
d = mix64(d, bindings.floor_law);
d = mix64(d, bindings.control_mode);
d = mix64(d, bindings.influence_state);
d = mix64(d, bindings.comparison_derivation);
d = mix64(d, bindings.round_identity);
d
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct DwellSatisfied {
pub(crate) round_identity: u64,
pub(crate) transition_identity: u64,
}
impl DwellSatisfied {
#[inline(always)]
pub fn round_identity(&self) -> u64 {
self.round_identity
}
#[inline(always)]
pub fn transition_identity(&self) -> u64 {
self.transition_identity
}
}
pub fn observe_dwell(
round_identity: u64,
transition_identity: u64,
elapsed_ticks: u64,
required_ticks: u64,
) -> Option<DwellSatisfied> {
if elapsed_ticks < required_ticks {
return None;
}
Some(DwellSatisfied {
round_identity,
transition_identity,
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::jump::JumpKind;
use crate::stability::{derive_stability_candidate, DIM, SCALE};
fn contracting_candidate() -> StabilityCandidate {
let g: [[i64; DIM]; DIM] = [[SCALE / 2, 0], [0, SCALE / 2]];
let d: [i64; DIM] = [SCALE, SCALE];
derive_stability_candidate(
JumpKind::FixedPointStateJump,
g,
d,
SCALE / 4,
0,
0,
SCALE,
0,
1,
0,
42,
)
.unwrap()
}
fn matching_bindings() -> CertificateBindings {
CertificateBindings {
admitted_graph: 1,
generated_payload: 2,
kernel_specialization_identity: 3,
numeric_profile: 4,
q_registry: 5,
pricing_law: 6,
floor_law: 7,
control_mode: 8,
influence_state: 9,
comparison_derivation: 10,
round_identity: 11,
}
}
#[test]
fn seals_when_witness_holds_and_all_bindings_match() {
let c = contracting_candidate();
let b = matching_bindings();
assert!(seal_certificate(c, b, b).is_ok());
}
#[test]
fn refuses_solo_mismatch_admitted_graph() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.admitted_graph ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::AdmittedGraphMismatch)
);
}
#[test]
fn refuses_solo_mismatch_generated_payload() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.generated_payload ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::GeneratedPayloadMismatch)
);
}
#[test]
fn refuses_solo_mismatch_kernel_specialization_identity() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.kernel_specialization_identity ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::KernelSpecializationIdentityMismatch)
);
}
#[test]
fn refuses_solo_mismatch_numeric_profile() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.numeric_profile ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::NumericProfileMismatch)
);
}
#[test]
fn refuses_solo_mismatch_q_registry() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.q_registry ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::QRegistryMismatch)
);
}
#[test]
fn refuses_solo_mismatch_pricing_law() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.pricing_law ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::PricingLawMismatch)
);
}
#[test]
fn refuses_solo_mismatch_floor_law() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.floor_law ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::FloorLawMismatch)
);
}
#[test]
fn refuses_solo_mismatch_control_mode() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.control_mode ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::ControlModeMismatch)
);
}
#[test]
fn refuses_solo_mismatch_influence_state() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.influence_state ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::InfluenceStateMismatch)
);
}
#[test]
fn refuses_solo_mismatch_comparison_derivation() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.comparison_derivation ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::ComparisonDerivationMismatch)
);
}
#[test]
fn refuses_solo_mismatch_round_identity() {
let c = contracting_candidate();
let expected = matching_bindings();
let mut actual = expected;
actual.round_identity ^= 1;
assert_eq!(
seal_certificate(c, actual, expected),
Err(CertificationRefusal::RoundIdentityMismatch)
);
}
#[test]
fn refuses_when_witness_margin_insufficient() {
let g: [[i64; DIM]; DIM] = [[SCALE, 0], [0, SCALE]]; let d: [i64; DIM] = [SCALE, SCALE];
let refusal = derive_stability_candidate(
JumpKind::FixedPointStateJump,
g,
d,
SCALE / 4,
0,
0,
SCALE,
0,
1,
0,
42,
);
assert_eq!(
refusal,
Err(crate::stability::StabilityDerivationRefusal::ContractionMarginInsufficient)
);
}
#[test]
fn observe_dwell_refuses_when_elapsed_insufficient() {
assert_eq!(observe_dwell(1, 2, 3, 10), None);
}
#[test]
fn observe_dwell_grants_when_elapsed_sufficient_and_binds_identities() {
let dwell = observe_dwell(1, 2, 10, 10).unwrap();
assert_eq!(dwell.round_identity(), 1);
assert_eq!(dwell.transition_identity(), 2);
}
}