Skip to content

Commit

Permalink
Add SigningManagerDependencies and SaverOfIntentsToConfirmAfterDelay
Browse files Browse the repository at this point in the history
  • Loading branch information
Sajjon committed Feb 17, 2025
1 parent 40b0046 commit 02fbb3a
Show file tree
Hide file tree
Showing 19 changed files with 187 additions and 12 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/system/os/os/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ build-info = { workspace = true }
interactors = { workspace = true }
sub-systems = { workspace = true }
host-info = { workspace = true }
manifests = { workspace = true }
key-derivation-traits = { workspace = true }
signing-traits = { workspace = true }
factor-instances-provider = { workspace = true }
Expand Down
2 changes: 2 additions & 0 deletions crates/system/os/os/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod sargon_os_gateway;
mod sargon_os_gateway_client;
mod sargon_os_personas;
mod sargon_os_profile;
mod saver_of_intents_to_confirm_after_delay;
mod testing_interactors;

pub mod prelude {
Expand All @@ -25,6 +26,7 @@ pub mod prelude {
pub use crate::sargon_os_gateway_client::*;
pub use crate::sargon_os_personas::*;
pub use crate::sargon_os_profile::*;
pub use crate::saver_of_intents_to_confirm_after_delay::*;
pub use crate::testing_interactors::*;

pub(crate) use build_info::prelude::*;
Expand Down
6 changes: 6 additions & 0 deletions crates/system/os/os/src/sargon_os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,12 @@ impl SargonOS {
as Arc<dyn SignInteractor<TransactionIntent>>
}

pub fn saver_of_intents_to_confirm_after_delay(
&self,
) -> Arc<dyn SaverOfIntentsToConfirmAfterDelay> {
todo!("implement")
}

pub fn sign_subintents_interactor(
&self,
) -> Arc<dyn SignInteractor<Subintent>> {
Expand Down
13 changes: 13 additions & 0 deletions crates/system/os/os/src/saver_of_intents_to_confirm_after_delay.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use manifests::IntentVariantToConfirmAfterDelay;

use crate::prelude::*;

/// A trait used to save intents to confirm after a delay.
/// We save these intents to confirm after a delay so that we can confirm them after a delay.
#[async_trait::async_trait]
pub trait SaverOfIntentsToConfirmAfterDelay: Send + Sync {
async fn save_intents_to_confirm_after_delay(
&self,
intents: IndexSet<IntentVariantToConfirmAfterDelay>,
) -> Result<()>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ pub trait ApplyShieldTransactionsSigner: Send + Sync {
pub struct ApplyShieldTransactionsSignerImpl {
factor_sources_in_profile: IndexSet<FactorSource>,
interactor: Arc<dyn SignInteractor<TransactionIntent>>,
saver_of_intents_to_confirm_after_delay:
Arc<dyn SaverOfIntentsToConfirmAfterDelay>,
}

impl ApplyShieldTransactionsSignerImpl {
pub fn new(os: &SargonOS) -> Result<Self> {
os.profile().map(|profile| Self {
factor_sources_in_profile: profile.factor_sources(),
interactor: os.sign_transactions_interactor(),
saver_of_intents_to_confirm_after_delay: os
.saver_of_intents_to_confirm_after_delay(),
})
}
}
Expand All @@ -29,9 +33,11 @@ impl ApplyShieldTransactionsSigner for ApplyShieldTransactionsSignerImpl {
&self,
payload_to_sign: ApplySecurityShieldPayloadToSign,
) -> Result<ApplySecurityShieldSignedPayload> {
// Prepare the signing manager
let signing_manager = SigningManager::new(
self.factor_sources_in_profile.clone(),
self.interactor.clone(),
self.saver_of_intents_to_confirm_after_delay.clone(),
payload_to_sign.applications_with_intents,
);
// Prepare the notary manager
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod signing_manager;
mod signing_manager_dependencies;
mod signing_manager_get;
mod signing_manager_pub;
mod signing_manager_sign_for_fee_payer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@

use crate::prelude::*;

use super::signing_manager_dependencies::SigningManagerDependencies;

/// Implementation of complex signing flow laid out in this
/// [whimsical diagram][flow].
///
/// [flow]: https://whimsical.com/wallet-sargon-signing-flow-QFvU2NAVXFiX1VgNBuvj5g
#[derive(derive_more::Deref)]
pub(crate) struct SigningManager {
/// FactorSources in Profile
pub(super) factor_sources_in_profile: IndexSet<FactorSource>,
pub(super) interactor: Arc<dyn SignInteractor<TransactionIntent>>,
#[deref]
pub(super) dependencies: Immutable<SigningManagerDependencies>,

/// The internal state of the SigningManager
///
Expand Down Expand Up @@ -150,8 +151,13 @@ impl SigningManager {
pub(super) fn intermediary_outcome(
&self,
) -> Result<SigningManagerIntermediaryOutcome> {
let mut state = self.state.write().map_err(|_| CommonError::Unknown)?; // TODO specific error variant
todo!()
let successfully_signed_intent_sets: Vec<SignedIntentSet> = vec![];
let failed_intent_sets: Vec<SignedIntentSet> = vec![];
todo!();
Ok(SigningManagerIntermediaryOutcome::new(
successfully_signed_intent_sets,
failed_intent_sets,
))
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::prelude::*;

pub(crate) struct SigningManagerDependencies {
/// FactorSources in Profile
pub(super) factor_sources_in_profile: IndexSet<FactorSource>,
pub(super) interactor: Arc<dyn SignInteractor<TransactionIntent>>,
pub(super) saver_of_intents_to_confirm_after_delay:
Arc<dyn SaverOfIntentsToConfirmAfterDelay>,
}

impl SigningManagerDependencies {
pub(crate) fn new(
factor_sources_in_profile: IndexSet<FactorSource>,
interactor: Arc<dyn SignInteractor<TransactionIntent>>,
saver_of_intents_to_confirm_after_delay: Arc<
dyn SaverOfIntentsToConfirmAfterDelay,
>,
) -> Self {
Self {
factor_sources_in_profile,
interactor,
saver_of_intents_to_confirm_after_delay,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ use std::sync::RwLockReadGuard;
use crate::prelude::*;

// === Non-pub Get ===
impl SigningManager {
pub(super) fn get_intents_to_confirm_after_delay(
&self,
best_signed_intent: &[SignedIntentWithContext],
) -> Result<IndexSet<IntentVariantToConfirmAfterDelay>> {
best_signed_intent
.iter()
.filter_map(|s| s.as_confirm_after_delay_variant())
.collect::<Result<IndexSet<IntentVariantToConfirmAfterDelay>>>()
}
}
impl SigningManager {
pub(super) fn _get_state(
&self,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
use crate::prelude::*;

use super::signing_manager_dependencies::SigningManagerDependencies;

// ==============
// === PUBLIC ===
// ==============
impl SigningManager {
pub(crate) fn new(
factor_sources_in_profile: IndexSet<FactorSource>,
interactor: Arc<dyn SignInteractor<TransactionIntent>>,
saver_of_intents_to_confirm_after_delay: Arc<
dyn SaverOfIntentsToConfirmAfterDelay,
>,
intent_sets: impl IntoIterator<
Item = SecurityShieldApplicationWithTransactionIntents,
>,
) -> Self {
let state = SigningManagerState::new(intent_sets);
Self {
factor_sources_in_profile,
interactor,
dependencies: SigningManagerDependencies::new(
factor_sources_in_profile,
interactor,
saver_of_intents_to_confirm_after_delay,
)
.into(),
state: RwLock::new(state),
}
}
Expand Down Expand Up @@ -54,6 +63,13 @@ impl SigningManager {
let best_signed_intent = signed_for_with_entities_applying_shield
.get_best_signed_intents()?;

let intents_to_confirm_after_delay =
self.get_intents_to_confirm_after_delay(&best_signed_intent)?;

self.saver_of_intents_to_confirm_after_delay
.save_intents_to_confirm_after_delay(intents_to_confirm_after_delay)
.await?;

// Sign with fee payer - we only need to sign the best ones with
// the fee payer.
self.sign_for_fee_payers(best_signed_intent).await
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::prelude::*;

#[derive(Clone, PartialEq, Eq, StdHash, derive_more::Debug)]
pub(crate) struct EntitySigningContext {
pub intent_set_id: IntentSetID,
pub(crate) intent_set_id: IntentSetID, // only internally relevant
pub role_kind: RoleKind,
pub variant: Option<RolesExercisableInTransactionManifestCombination>,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::prelude::*;

#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, PartialEq, Eq, StdHash, Debug)]
pub(crate) struct IntentVariant {
pub(crate) variant:
Option<RolesExercisableInTransactionManifestCombination>,
pub(crate) intent: TransactionIntent,
}

impl IntentVariant {
pub fn new(
variant: impl Into<Option<RolesExercisableInTransactionManifestCombination>>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl SignedIntentSet {
Ok(SignedIntentWithContext {
signed_intent,
context: item.context,
entity_applying_shield: item.entity,
})
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,36 @@ use crate::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct SignedIntentWithContext {
pub signed_intent: SignedIntent,
pub entity_applying_shield: AccountOrPersona,
pub context: EntitySigningContext,
}

impl SignedIntentWithContext {
pub(crate) fn as_confirm_after_delay_variant(
&self,
) -> Option<Result<IntentVariantToConfirmAfterDelay>> {
let Some(variant) = self.context.variant else {
return None;
};

if variant.can_quick_confirm() {
None
} else {
Some(
self.entity_applying_shield
.get_provisional()
.ok_or(CommonError::EntityHasNoProvisionalSecurityConfigSet)
.and_then(|provisional| {
provisional.as_factor_instances_derived()
.cloned()
.ok_or(CommonError::ProvisionalConfigInWrongStateExpectedInstancesDerived)
})
.map(|provisional| IntentVariantToConfirmAfterDelay::new(
variant,
self.signed_intent.intent.clone(),
self.entity_applying_shield.address(),
provisional.timed_recovery_delay_in_minutes()
)))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ pub(crate) struct SigningManagerIntermediaryOutcome {
}

impl SigningManagerIntermediaryOutcome {
pub(crate) fn new(
successfully_signed_intent_sets: impl IntoIterator<Item = SignedIntentSet>,
failed_intent_sets: impl IntoIterator<Item = SignedIntentSet>,
) -> Self {
Self {
successfully_signed_intent_sets: successfully_signed_intent_sets
.into_iter()
.collect(),
failed_intent_sets: failed_intent_sets.into_iter().collect(),
}
}
pub(crate) fn get_best_signed_intents(
self,
) -> Result<Vec<SignedIntentWithContext>> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use crate::prelude::*;

#[derive(Clone, PartialEq, Eq, StdHash, Debug)]
pub struct IntentVariantToConfirmAfterDelay {
pub role_which_initiated_recovery: RoleInitiatingRecovery,
pub intent: TransactionIntent,
pub entity_applying_shield: AddressOfAccountOrPersona,
/// The time user has to wait after this intent has been broadcasted to
/// the network before recovery can be confirmed.
pub number_of_minutes_until_confirm_is_callable: u32,
}

impl IntentVariantToConfirmAfterDelay {
pub fn new(
role_which_initiated_recovery: impl Into<RoleInitiatingRecovery>,
intent: TransactionIntent,
entity_applying_shield: AddressOfAccountOrPersona,
number_of_minutes_until_confirm_is_callable: u32,
) -> Self {
let role_which_initiated_recovery =
role_which_initiated_recovery.into();
Self {
role_which_initiated_recovery,
intent,
entity_applying_shield,
number_of_minutes_until_confirm_is_callable,
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod access_controller_factors_and_time_input;
mod confirm_timed_recovery;
mod intent_variant_to_confirm_after_delay;
mod lock_fee_against_xrd_vault_of_access_controller;
mod manifests_securify_shield_securified_entity;
mod manifests_securify_shield_unsecurified_entity;
Expand All @@ -10,6 +11,7 @@ mod transaction_manifest_unsecurified_entity_owner_badge_into_bucket_putting;

pub use access_controller_factors_and_time_input::*;
pub use confirm_timed_recovery::*;
pub use intent_variant_to_confirm_after_delay::*;
pub use lock_fee_against_xrd_vault_of_access_controller::*;
pub use manifests_securify_shield_securified_entity::*;
pub use manifests_securify_shield_unsecurified_entity::*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,24 @@ pub enum OrderOfInstructionSettingRolaKey {
MustSetInFutureTxForConfirmRecovery,
}

#[derive(Clone, Debug, PartialEq, Eq)]
enum RoleInitiatingRecovery {
/// The role which initiated the recovery proposal.
#[derive(Clone, Debug, PartialEq, Eq, StdHash)]
pub enum RoleInitiatingRecovery {
/// Recovery was initiated using the `Primary` role.
Primary,
/// Recovery was initiated using the `Recovery` role.
Recovery,
}

impl From<RolesExercisableInTransactionManifestCombination>
for RoleInitiatingRecovery
{
fn from(
roles_combination: RolesExercisableInTransactionManifestCombination,
) -> Self {
roles_combination.role_initiating_recovery()
}
}
impl RolesExercisableInTransactionManifestCombination {
pub fn can_exercise_role(&self, role_kind: RoleKind) -> bool {
self.exercisable_roles().contains(&role_kind)
Expand Down

0 comments on commit 02fbb3a

Please sign in to comment.