use crate::algebra::mv::Mv;
use crate::governance::governance::Governance;
use crate::governance::phase::Phase;
use crate::governance::predicate::Predicate;
use crate::governance::profile::GeneratorProfile;
use crate::governance::reading::{ExtractionError, ReadingRules};
use crate::governance::rule::ProofTerm;
use crate::scalar::Scalar;
use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct Geoit {
pub(crate) mv: Mv,
pub(crate) governance: Arc<Governance>,
pub(crate) predicate: Predicate,
pub(crate) phase: Phase,
pub(crate) readings: ReadingRules,
pub(crate) profile: GeneratorProfile,
pub(crate) proof: ProofTerm,
}
impl Geoit {
pub fn mv(&self) -> &Mv {
&self.mv
}
pub fn governance(&self) -> &Governance {
&self.governance
}
pub fn predicate(&self) -> &Predicate {
&self.predicate
}
pub fn phase(&self) -> Phase {
self.phase
}
pub fn profile(&self) -> &GeneratorProfile {
&self.profile
}
pub fn proof(&self) -> &ProofTerm {
&self.proof
}
pub fn is_satisfied(&self) -> bool {
self.predicate.is_satisfied()
}
pub fn has_overflow(&self) -> bool {
self.predicate.has_overflow()
}
pub fn read(&self, param_index: usize) -> Result<Scalar, ExtractionError> {
self.readings.read(&self.mv, param_index)
}
pub fn read_all(&self) -> Result<Vec<Scalar>, ExtractionError> {
self.readings.apply(&self.mv)
}
pub fn snapshot(&self) -> GeoitSnapshot {
GeoitSnapshot {
mv: self.mv.clone(),
governance: (*self.governance).clone(),
predicate: self.predicate.clone(),
phase: self.phase,
readings: self.readings.clone(),
profile: self.profile,
proof: self.proof.clone(),
}
}
}
impl std::fmt::Display for Geoit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Geoit({}, {:?}, {})",
self.mv.display_with(&self.governance.sig),
self.phase,
if self.is_satisfied() {
"satisfied"
} else {
"FAILED"
}
)
}
}
#[derive(Clone, Debug)]
pub struct GeoitSnapshot {
pub mv: Mv,
pub governance: Governance,
pub predicate: Predicate,
pub phase: Phase,
pub readings: ReadingRules,
pub profile: GeneratorProfile,
pub proof: ProofTerm,
}
impl GeoitSnapshot {
pub fn into_geoit(self) -> Geoit {
Geoit {
mv: self.mv,
governance: Arc::new(self.governance),
predicate: self.predicate,
phase: self.phase,
readings: self.readings,
profile: self.profile,
proof: self.proof,
}
}
pub fn into_geoit_with(self, governance: Arc<Governance>) -> Geoit {
Geoit {
mv: self.mv,
governance,
predicate: self.predicate,
phase: self.phase,
readings: self.readings,
profile: self.profile,
proof: self.proof,
}
}
}
impl std::fmt::Display for GeoitSnapshot {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"GeoitSnapshot({}, {:?}, {})",
self.mv.display_with(&self.governance.sig),
self.phase,
if self.predicate.is_satisfied() {
"satisfied"
} else {
"FAILED"
}
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::scalar::Rat;
#[test]
fn geoit_read() {
let mv = Mv::from_rat_terms(&[(0b001, Rat::from(3)), (0b010, Rat::from(4))]);
let gov = Arc::new(Governance {
sig: crate::algebra::signature::Signature::new(0, 0, 2).unwrap(),
derived_gens: vec![],
geom_classes: vec![],
constructions: vec![],
probe: None,
transform_rules: vec![],
});
let geoit = Geoit {
mv,
governance: gov,
predicate: Predicate::new(0, &[], &[], vec![], vec![], false),
phase: Phase::Commitment,
readings: ReadingRules {
extractions: vec![
crate::governance::reading::ExtractionMap::Coefficient(0b001),
crate::governance::reading::ExtractionMap::Coefficient(0b010),
],
},
profile: GeneratorProfile::EMPTY,
proof: ProofTerm::Checked { class_index: 0 },
};
assert_eq!(geoit.read(0).unwrap(), Scalar::from(3i64));
assert_eq!(geoit.read(1).unwrap(), Scalar::from(4i64));
assert!(geoit.read(2).is_err());
}
#[test]
fn snapshot_roundtrip() {
let mv = Mv::from_rat_terms(&[(0b001, Rat::from(7))]);
let gov = Arc::new(Governance {
sig: crate::algebra::signature::Signature::new(0, 0, 2).unwrap(),
derived_gens: vec![],
geom_classes: vec![],
constructions: vec![],
probe: None,
transform_rules: vec![],
});
let geoit = Geoit {
mv: mv.clone(),
governance: gov,
predicate: Predicate::new(0, &[], &[], vec![], vec![], false),
phase: Phase::Commitment,
readings: ReadingRules {
extractions: vec![],
},
profile: GeneratorProfile::EMPTY,
proof: ProofTerm::Checked { class_index: 0 },
};
let snap = geoit.snapshot();
assert_eq!(snap.mv, mv);
assert_eq!(snap.phase, Phase::Commitment);
let geoit2 = snap.into_geoit();
assert_eq!(geoit2.mv(), &mv);
assert_eq!(geoit2.phase(), Phase::Commitment);
}
}