Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TransationManifest::securify_unsecurified_entity & ProvisionalSecurifiedConfig #293

Merged
merged 22 commits into from
Dec 17, 2024

Conversation

CyonAlexRDX
Copy link
Contributor

@CyonAlexRDX CyonAlexRDX commented Dec 6, 2024

Preface

This should have been two PRs, sorry about that. It could have made sense for all the changes to be part of the same PR if I also implemented the SecurifyEntitiesManager - which I started doing because I'm bad at not-scope-creeping, but I did not wanna create yet another 6k LOC PR.

So two (somewhat distinct) changes this PR brings is:

  1. TransactionManifest::securify_unsecurified_entity
  2. Adds a provisional: Option<ProvisionalSecurifiedConfig> on UnsecurifiedEntityControl and SecurifiedEntityControl

Additional changes:

  • Removed authentication_signing: Option<HierarchicalDeterministicFactorInstance> field on UnsecurifiedEntityControl
  • Added authentication_signing_factor_instance: HierarchicalDeterministicFactorInstance field to SecurifiedEntityControl SecurityStructureOfFactorInstances

TransactionManifest::securify_unsecurified_entity

Resurrected impl From<Role> for ScryptoAccessRole (implemented by @0xOmarA ) from before #286 was merged (which temporarily removed this).

ProvisionalSecurifiedConfig

Once a user has selected some accounts and/or personas to securify with a new shield, those accounts should now retain the information that user wants to use some shield with them.

But the FactorInstancesProvider might not contain enough factors to securify all those accounts now. And user can always cancel derivation even if we try to derive more factors. **This means we cannot directly save SecurityStructureOfFactorInstances per account. **

So we start with saving the unique shield ID - SecurityStructureID associated with the accounts (or personas). This is the variant ShieldSelected(SecurityStructureID) of the new type ProvisionalSecurifiedConfig.

Then later when we were able to use the FactorInstanceProvider to provide factor instances for the SecurityStructureOfFactorSourceIds - identified by SecurityStructureID of ProvisionalSecurifiedConfig::ShieldSelected - we update the provisional state of all relevant entities in Profile
from: ProvisionalSecurifiedConfig::ShieldSelected
to: ProvisionalSecurifiedConfig::FactorInstancesDerived(SecurityStructureOfFactorInstances).

Later we might ask user to sign a batch of transaction. User might cancel, so we must support reminding user to batch sign these transaction later.

Later, once signed we update the provisional state of all relevant entities in Profile
from: ProvisionalSecurifiedConfig::FactorInstancesDerived
to: ProvisionalSecurifiedConfig::TransactionQueued(SecurityStructureOfFactorInstances, TXID).

I've put assertions on what is destructive / unsupported transitions:
FactorInstancesDerived(SecurityStructureOfFactorInstances) -> ShieldSelected is invalid for now, since those FactorInstance already have been deleted from the FactorInstancesCache so those factor instances would be lost, and we would have "gaps" in the derivation entity index - not the woooorst thing which can happen, but it makes Account Recovery Scan tricker in the future, since we would need to scan a broader range. So we should try to avoid creating such gaps. By "invalid for now" I mean this PR does not support it. But we can probably quite easily support this as a feature, by allowing us to "put instance back into the cache"!

Furthermore transitions from TransactionQueued to FactorInstancesDerived is not directly supported by set_provisional, I've exposed a dedicated method for it called cancel_queued_transaction, making it clear that we should first actually cancel the transaction and removed it from the queue, and then call account.entity_security_state.cancel_queued_transaction(..).

Copy link

codecov bot commented Dec 6, 2024

Codecov Report

Attention: Patch coverage is 95.68106% with 13 lines in your changes missing coverage. Please review.

Project coverage is 93.3%. Comparing base (0c5278b) to head (3ba71d3).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...a/secured_entity_control/secured_entity_control.rs 90.0% 4 Missing ⚠️
..._structures/matrices/matrix_of_factor_instances.rs 94.8% 2 Missing ⚠️
.../sargon/src/system/sargon_os/sargon_os_accounts.rs 0.0% 2 Missing ⚠️
crates/sargon/src/types/samples/persona_samples.rs 95.5% 2 Missing ⚠️
...100/entity_security_state/entity_security_state.rs 94.7% 1 Missing ⚠️
...l/manifest_building/manifests_access_controller.rs 93.7% 1 Missing ⚠️
...low_level/transaction_hashes/transaction_hashes.rs 0.0% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff           @@
##            main    #293    +/-   ##
======================================
  Coverage   93.2%   93.3%            
======================================
  Files       1104    1109     +5     
  Lines      23303   23528   +225     
  Branches      79      79            
======================================
+ Hits       21735   21955   +220     
- Misses      1553    1558     +5     
  Partials      15      15            
Flag Coverage Δ
kotlin 97.1% <ø> (ø)
rust 92.8% <95.6%> (+<0.1%) ⬆️
swift 94.8% <100.0%> (-0.1%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...pple/Sources/Sargon/Protocols/EntityProtocol.swift 100.0% <100.0%> (ø)
crates/sargon/src/core/error/common_error.rs 93.3% <ø> (ø)
...ates/sargon/src/core/types/signatures/signature.rs 88.5% <100.0%> (+1.4%) ⬆️
...e/logic/profile_network/profile_network_details.rs 98.7% <100.0%> (+1.4%) ⬆️
...or_instance_level/role_into_scrypto_access_rule.rs 100.0% <100.0%> (ø)
..._factors/security_structure_of_factor_instances.rs 100.0% <100.0%> (ø)
...factors/security_structure_of_factor_source_ids.rs 100.0% <ø> (+13.3%) ⬆️
.../sargon/src/profile/v100/entity/account/account.rs 96.5% <100.0%> (+1.7%) ⬆️
...rgon/src/profile/v100/entity/has_security_state.rs 100.0% <100.0%> (ø)
.../sargon/src/profile/v100/entity/persona/persona.rs 99.3% <100.0%> (+<0.1%) ⬆️
... and 24 more

... and 1 file with indirect coverage changes

@CyonAlexRDX CyonAlexRDX changed the title Reintroduce From<RoleWithFactorInstances<ROLE>> for ScryptoAccessRule [WIP] Into (Scrypto) AccessRule & RuleSet for MatrixOfFactorInstances Dec 10, 2024
@CyonAlexRDX CyonAlexRDX force-pushed the scrypto_access_rules_for_matrix_of_factor_instances branch from 670f899 to 8faaf3e Compare December 16, 2024 09:07
@CyonAlexRDX CyonAlexRDX marked this pull request as ready for review December 16, 2024 14:01
@CyonAlexRDX CyonAlexRDX changed the title [WIP] Into (Scrypto) AccessRule & RuleSet for MatrixOfFactorInstances TransationManifest: create_access_controller & ProvisionalSecurifiedConfig Dec 16, 2024
@CyonAlexRDX CyonAlexRDX changed the title TransationManifest: create_access_controller & ProvisionalSecurifiedConfig TransationManifest: securify_unsecurified_entity & ProvisionalSecurifiedConfig Dec 16, 2024
@CyonAlexRDX CyonAlexRDX changed the title TransationManifest: securify_unsecurified_entity & ProvisionalSecurifiedConfig TransationManifest::securify_unsecurified_entity & ProvisionalSecurifiedConfig Dec 16, 2024
README.md Outdated Show resolved Hide resolved

/// A provisional new security structure configuration which user
/// is about to change to
pub provisional: Option<ProvisionalSecurifiedConfig>,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatives to provisional:

  • draft - discarded since it sounds like it is not "saved" or otherwise incomplete.
  • pending - make it sound like it has been submitted to the network and waiting for a tx complete
  • user_intention - some version of this might be ok.

Definition of provisional: "arranged or existing for the present, possibly to be changed later."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temporal?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean temporary I think? Hmm temporary relates more to time, whereas I'm going for a term which relates more to step in a sequence of steps, which I feel is a little bit more precise. And "temporary" also has a meaning that after some time it is no longer relevant, whereas what is actually happening here is that it holds the state which will be the future state, so not at all temporary, just that we are note quite there yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2024-12-17 at 09 43 02

I asked ChatGPT about the nuances of "temporal" vs "temporary"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved, and added authentication_signing_factor_instance: HierarchicalDeterministicFactorInstance,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also added new ctor with validation!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you

security_structure_id: SecurityStructureID,
matrix_of_factors: MatrixOfFactorInstances,
) -> Self {
Self {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was not throwing, is now!

Array<Enum>(
Enum<0u8>(
Enum<2u8>(
2u8,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this 2 is threshold

;
CREATE_ACCESS_CONTROLLER
Bucket("bucket1")
Tuple(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@0xOmarA the RuleSet uses position (index) to determine which AccessRule is primary, recovery and confirmation? Because The values of the Enum seems to be the same?

        Enum<2u8>(
            Enum<1u8>(
                Array<Enum>(

for all three?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does indeed use the position to determine that since these are just arguments to the function.

@CyonAlexRDX CyonAlexRDX requested a review from 0xOmarA December 16, 2024 15:52
@@ -105,12 +173,17 @@ impl MnemonicWithPassphrase {
impl MatrixOfFactorInstances {
fn sample_from_matrix_of_sources(
matrix_of_sources: MatrixOfFactorSources,
entity_kind: CAP26EntityKind,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we now have stricter validation so that we do not accidentally use Account factorinstances for Persona or vice versa.

use crate::prelude::*;

impl<const ROLE: u8> From<RoleWithFactorInstances<ROLE>> for ScryptoAccessRule {
fn from(value: RoleWithFactorInstances<ROLE>) -> Self {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small upgrade of impl we got from @0xOmarA some months ago.


pub const MINUTES_PER_DAY: u32 = 24 * 60;

impl From<SecurityStructureOfFactorInstances> for ScryptoRecoveryProposal {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this PR does not make use of this From for ScryptoRecoveryProposal

Copy link
Contributor

@GhenadieVP GhenadieVP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! Left some minor-ish comments.

/// Non-optional since we can replace it with a new one for entities
/// we have recovered during Onboarding Account Recovery Scan for securified
/// entities
pub authentication_signing_factor_instance:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to update the docs for the SecurityStructureOfFactorInstances as it is no more accurate.
@micbakos-rdx FYI, this will be used for ROLA signing.

/// The factor instance which can be used for ROLA.
pub authentication_signing: Option<HierarchicalDeterministicFactorInstance>,
/// The provisional security structure configuration
pub provisional: Option<ProvisionalSecurifiedConfig>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe provisional_securified_configu

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure!

}
_ => false, // TODO change that
};
let has_auth_signing_key = persona.is_securified();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does has_auth_signing_key mean? That it literally as a dedicated signing key or that there is some key for signing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AuthorizedPersonaDetailed struct contains that field. Not sure we use it anywhere in hosts, but I did not wanna change that. And the assignment let has_auth_signing_key = persona.is_securified(); is correct. ALL Securified Entties has an auth signing factor. No Unsecurified has one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CyonAlexRDX We discussed using transaction_signing factor instance when an entity is not securified. Doesn't that mean that has_auth_signing_key will always be true? Or does has_auth_signing_key mean like a true ROLA key?

Copy link
Contributor

@Sajjon Sajjon Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does has_auth_signing_key mean like a true ROLA key?

YES. auth signing KeyKind/Instance == true ROLA

so rather has_auth_signing_key will always be false for unsecurified entities. But unsecurified entities can ofc proof-ownership (which it does using transaction_signing.)

I'm not sure this field is at all relevant. I think it might have been used by iOS behind DEBUG flag. So we should not put too much importance on this field.

Copy link
Contributor

@micbakos-rdx micbakos-rdx Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Alex, indeed it was used to disable the button that created the rola key for unsecurified entities (under debug ofc). Indeed unneeded.

Comment on lines +73 to +79
// We have already consumed FactorInstances from the FactorInstancesCache.
// We currently do not have a way of putting these back. We don't want to
// create gaps if we can. Wallet Features might change, to REQUIRE us to
// allow this, if so we can change this - allowing transition from
// `FactorInstancesDerived` to Non-TransactionQueued state.
Err(
CommonError::SecurityEntityControlCannotChangeProvisionalAlreadyDerivedInstances,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can happen quite easily if user updates a shield a second time before applying it. So most likely we will need to handle this, let's discuss in design session how to do it.

}
}

pub const MINUTES_PER_DAY: u32 = 24 * 60;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do have a constants file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constants which have a "natural home" - should be put in a natural home I think. That is most Rusty I think. The constants file seems to contain mostly constants relating to GW?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well I agree, at the same time MINUTES_PER_DAY is very generic. Anyway, this is minor, we'll migrate in case there will be other components using this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, ok agreed, this should be moved, since it is common relating to time!

@@ -294,7 +294,7 @@ impl Profile {
.items()
.into_iter()
.map(Into::<AccountOrPersona>::into)
.map(|e| (e.clone(), e.unique_factor_instances()))
.map(|e| (e.clone(), e.unique_tx_signing_factor_instances()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not all instances including authentication_signing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, this should have been unique_all_factor_instances, thx, will change


/// The authentication signing factor instance which is used to sign
/// proof of ownership - aka "True Rola Key". User can select which FactorSource
/// to use during Shield Building, but typically most users will user the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in will user

}
_ => false, // TODO change that
};
let has_auth_signing_key = persona.is_securified();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CyonAlexRDX We discussed using transaction_signing factor instance when an entity is not securified. Doesn't that mean that has_auth_signing_key will always be true? Or does has_auth_signing_key mean like a true ROLA key?

@CyonAlexRDX CyonAlexRDX merged commit 7f13683 into main Dec 17, 2024
13 checks passed
@CyonAlexRDX CyonAlexRDX deleted the scrypto_access_rules_for_matrix_of_factor_instances branch December 17, 2024 10:13
@CyonAlexRDX CyonAlexRDX restored the scrypto_access_rules_for_matrix_of_factor_instances branch December 17, 2024 10:48
@CyonAlexRDX CyonAlexRDX deleted the scrypto_access_rules_for_matrix_of_factor_instances branch December 18, 2024 07:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants