Skip to content
This repository was archived by the owner on Feb 4, 2025. It is now read-only.

Commit

Permalink
[no ci] WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Sajjon committed Nov 30, 2024
1 parent 0c5f86f commit 3919c6b
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/rules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ serde_json = { version = "1.0.133", features = ["preserve_order"] }
assert-json-diff = "2.0.2"
once_cell = "1.20.2"
itertools = "0.13.0"
uuid = { version = "1.11.0", features = ["serde", "v4"] }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ["cfg(tarpaulin_include)"] }
3 changes: 3 additions & 0 deletions crates/rules/src/matrices/builder/matrix_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pub type MatrixBuilder = AbstractMatrixBuilderOrBuilt<
Built, // this is HACKY
>;

pub type MatrixTemplate = AbstractMatrixBuilt<FactorSourceTemplate>;


// ==================
// ===== PUBLIC =====
// ==================
Expand Down
131 changes: 131 additions & 0 deletions crates/rules/src/matrices/matrix_of_factor_source_ids.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::vec;

use crate::prelude::*;

pub type MatrixOfFactorSourceIds = AbstractMatrixBuilt<FactorSourceID>;
Expand Down Expand Up @@ -532,6 +534,132 @@ impl MatrixOfFactorSourceIds {
}
}

#[cfg(test)]
mod test_templates {
use super::*;

#[test]
fn temp() {
let c = MatrixTemplate::config_90();
let m = c
.fulfill(vec![
FactorSourceID::sample_device(),
FactorSourceID::sample_device_other(),
FactorSourceID::sample_ledger(),
FactorSourceID::sample_ledger_other(),
FactorSourceID::sample_arculus(),
FactorSourceID::sample_arculus_other(),
FactorSourceID::sample_passphrase(),
FactorSourceID::sample_passphrase_other(),
FactorSourceID::sample_security_questions(),
FactorSourceID::sample_security_questions_other(),
FactorSourceID::sample_trusted_contact(),
FactorSourceID::sample_trusted_contact_other(),
])
.unwrap();
pretty_assertions::assert_eq!(m, MatrixOfFactorSourceIds::sample_config_90());
}
}

impl MatrixTemplate {
pub fn config_90() -> Self {
Self {
built: PhantomData,
primary_role: PrimaryRoleTemplate::with_factors(
2,
vec![
FactorSourceTemplate::device(0),
FactorSourceTemplate::ledger(0),
],
vec![],
),
recovery_role: RecoveryRoleTemplate::with_factors(
0,
vec![],
vec![
FactorSourceTemplate::trusted_contact(0),
FactorSourceTemplate::device(0),
],
),
confirmation_role: ConfirmationRoleTemplate::with_factors(
0,
vec![],
vec![FactorSourceTemplate::security_questions(0)],
),
number_of_days_until_auto_confirm: Self::DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM,
}
}
}

impl<const R: u8> AbstractBuiltRoleWithFactor<R, FactorSourceTemplate> {
pub(crate) fn fulfill(
self,
factor_source_id_assigner: &mut FactorSourceIdAssigner,
) -> Result<RoleWithFactorSourceIds<R>, CommonError> {
let mut fulfill =
|xs: &Vec<FactorSourceTemplate>| -> Result<Vec<FactorSourceID>, CommonError> {
xs.into_iter()
.map(|f| factor_source_id_assigner.next(f))
.collect::<Result<Vec<_>, CommonError>>()
};
Ok(RoleWithFactorSourceIds::with_factors(
self.get_threshold(),
fulfill(self.get_threshold_factors())?,
fulfill(self.get_override_factors())?,
))
}
}
pub(crate) struct FactorSourceIdAssigner {
factor_source_ids: Vec<FactorSourceID>,
map: IndexMap<FactorSourceTemplate, FactorSourceID>,
}
impl FactorSourceIdAssigner {
fn new(factor_source_ids: impl IntoIterator<Item = FactorSourceID>) -> Self {
Self {
factor_source_ids: factor_source_ids.into_iter().collect_vec(),
map: IndexMap::new(),
}
}
fn next(&mut self, template: &FactorSourceTemplate) -> Result<FactorSourceID, CommonError> {
if let Some(existing) = self.map.get(template) {
println!("🎭 existing for ID={:?}, using: {:?}", template, *existing);
Ok(*existing)
} else if let Some(index_of_next) = self
.factor_source_ids
.iter()
.position(|f| f.get_factor_source_kind() == template.kind)
{
let next = self.factor_source_ids.remove(index_of_next);
println!("🎭 Consuming and using new: for template={:?}, next: {:?}", template, next);
self.map.insert(template.clone(), next);
Ok(next)
} else {
Err(CommonError::Unknown)
}
}
}

impl MatrixTemplate {
pub fn fulfill(
self,
factor_source_ids: impl IntoIterator<Item = FactorSourceID>,
) -> Result<MatrixOfFactorSourceIds, CommonError> {
let mut assigner = FactorSourceIdAssigner::new(factor_source_ids);
let primary_role = self.primary_role.fulfill(&mut assigner)?;
let recovery_role = self.recovery_role.fulfill(&mut assigner)?;
let confirmation_role = self.confirmation_role.fulfill(&mut assigner)?;

Ok(MatrixOfFactorSourceIds {
built: PhantomData,
primary_role,
recovery_role,
confirmation_role,
number_of_days_until_auto_confirm:
MatrixOfFactorSourceIds::DEFAULT_NUMBER_OF_DAYS_UNTIL_AUTO_CONFIRM,
})
}
}

impl HasSampleValues for MatrixOfFactorSourceIds {
fn sample() -> Self {
Self::sample_config_11()
Expand All @@ -548,6 +676,9 @@ mod tests {
#[allow(clippy::upper_case_acronyms)]
type SUT = MatrixOfFactorSourceIds;

#[test]
fn template() {}

#[test]
fn equality() {
assert_eq!(SUT::sample(), SUT::sample());
Expand Down
45 changes: 45 additions & 0 deletions crates/rules/src/roles/abstract_role_builder_or_built.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,51 @@ pub struct AbstractRoleBuilderOrBuilt<const R: u8, F, T> {
pub(crate) type AbstractBuiltRoleWithFactor<const R: u8, F> = AbstractRoleBuilderOrBuilt<R, F, ()>;
pub(crate) type RoleBuilder<const R: u8> = AbstractRoleBuilderOrBuilt<R, FactorSourceID, Built>;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FactorSourceTemplate {
pub kind: FactorSourceKind,
pub id: u8,
}
impl FactorSourceTemplate {
pub fn new(kind: FactorSourceKind, id: u8) -> Self {
Self { kind, id }
}
pub fn device(id: u8) -> Self {
Self::new(FactorSourceKind::Device, id)
}
pub fn ledger(id: u8) -> Self {
Self::new(FactorSourceKind::LedgerHQHardwareWallet, id)
}
pub fn arculus(id: u8) -> Self {
Self::new(FactorSourceKind::ArculusCard, id)
}

pub fn password(id: u8) -> Self {
Self::new(FactorSourceKind::Password, id)
}

pub fn trusted_contact(id: u8) -> Self {
Self::new(FactorSourceKind::TrustedContact, id)
}

pub fn security_questions(id: u8) -> Self {
Self::new(FactorSourceKind::SecurityQuestions, id)
}
}

impl IsMaybeKeySpaceAware for FactorSourceTemplate {
fn maybe_key_space(&self) -> Option<KeySpace> {
None
}
}

pub(crate) type PrimaryRoleTemplate =
AbstractBuiltRoleWithFactor<{ ROLE_PRIMARY }, FactorSourceTemplate>;
pub(crate) type RecoveryRoleTemplate =
AbstractBuiltRoleWithFactor<{ ROLE_RECOVERY }, FactorSourceTemplate>;
pub(crate) type ConfirmationRoleTemplate =
AbstractBuiltRoleWithFactor<{ ROLE_CONFIRMATION }, FactorSourceTemplate>;

impl<const R: u8, F: IsMaybeKeySpaceAware, T> AbstractRoleBuilderOrBuilt<R, F, T> {
pub fn role(&self) -> RoleKind {
RoleKind::from_u8(R).expect("RoleKind should be valid")
Expand Down

0 comments on commit 3919c6b

Please sign in to comment.