-
Notifications
You must be signed in to change notification settings - Fork 1
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
[WIP] Apply Shield Wallet Interaction Part 2 #355
base: main
Are you sure you want to change the base?
Changes from 11 commits
1a52f44
fdea748
9015925
e7fd884
54e9967
20cbf2a
25188e9
4d8fc6d
f2babd1
12704e2
58fc8cb
4007bae
0ce2b35
5529715
15e0558
252f2bd
3489880
3ac37f3
ebde221
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use crate::prelude::*; | ||
use radix_engine_interface::blueprints::access_controller::{ | ||
AccessControllerInitiateRecoveryAsPrimaryInput as ScryptoAccessControllerInitiateRecoveryAsPrimaryInput, | ||
AccessControllerInitiateRecoveryAsRecoveryInput as ScryptoAccessControllerInitiateRecoveryAsRecoveryInput, | ||
AccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput as ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput, | ||
AccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput as ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput, | ||
AccessControllerTimedConfirmRecoveryInput as ScryptoAccessControllerTimedConfirmRecoveryInput, | ||
}; | ||
|
||
/// An ephemeral DTO that is used to create the input for the access controller | ||
/// methods that require factors and time - which we create from a | ||
/// `SecurityStructureOfFactorInstances` | ||
#[derive(Debug, Clone)] | ||
pub struct AccessControllerFactorsAndTimeInput { | ||
/// RuleSet is Scrypto representation of the security structure's | ||
/// MatrixOfFactors | ||
rule_set: ScryptoRuleSet, | ||
/// The timed recovery delay in minutes we get from `SecurityStructureOfFactorInstances`. | ||
timed_recovery_delay_in_minutes: u32, | ||
} | ||
|
||
impl AccessControllerFactorsAndTimeInput { | ||
pub fn new( | ||
Check warning on line 23 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L23
|
||
security_structure_of_factor_instances: &SecurityStructureOfFactorInstances, | ||
) -> Self { | ||
let rule_set = ScryptoRuleSet::from( | ||
security_structure_of_factor_instances | ||
.matrix_of_factors | ||
.clone(), | ||
Check warning on line 29 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L27-L29
|
||
); | ||
|
||
let timed_recovery_delay_in_minutes = | ||
security_structure_of_factor_instances | ||
Check warning on line 33 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L32-L33
|
||
.timed_recovery_delay_in_minutes(); | ||
|
||
Self { | ||
rule_set, | ||
timed_recovery_delay_in_minutes, | ||
} | ||
} | ||
} | ||
|
||
impl From<&AccessControllerFactorsAndTimeInput> | ||
for ScryptoAccessControllerInitiateRecoveryAsRecoveryInput | ||
{ | ||
fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { | ||
Check warning on line 46 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L46
|
||
Self { | ||
rule_set: value.rule_set.clone(), | ||
timed_recovery_delay_in_minutes: Some( | ||
Check warning on line 49 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L48-L49
|
||
value.timed_recovery_delay_in_minutes, | ||
), | ||
} | ||
} | ||
} | ||
|
||
impl From<&AccessControllerFactorsAndTimeInput> | ||
for ScryptoAccessControllerInitiateRecoveryAsPrimaryInput | ||
{ | ||
fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { | ||
Check warning on line 59 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L59
|
||
Self { | ||
rule_set: value.rule_set.clone(), | ||
timed_recovery_delay_in_minutes: Some( | ||
Check warning on line 62 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L61-L62
|
||
value.timed_recovery_delay_in_minutes, | ||
), | ||
} | ||
} | ||
} | ||
|
||
impl From<&AccessControllerFactorsAndTimeInput> | ||
for ScryptoAccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput | ||
{ | ||
fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { | ||
Check warning on line 72 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L72
|
||
Self { | ||
rule_set: value.rule_set.clone(), | ||
timed_recovery_delay_in_minutes: Some( | ||
Check warning on line 75 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L74-L75
|
||
value.timed_recovery_delay_in_minutes, | ||
), | ||
} | ||
} | ||
} | ||
|
||
impl From<&AccessControllerFactorsAndTimeInput> | ||
for ScryptoAccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput | ||
{ | ||
fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { | ||
Check warning on line 85 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L85
|
||
Self { | ||
rule_set: value.rule_set.clone(), | ||
timed_recovery_delay_in_minutes: Some( | ||
Check warning on line 88 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L87-L88
|
||
value.timed_recovery_delay_in_minutes, | ||
), | ||
} | ||
} | ||
} | ||
|
||
impl From<&AccessControllerFactorsAndTimeInput> | ||
for ScryptoAccessControllerTimedConfirmRecoveryInput | ||
{ | ||
fn from(value: &AccessControllerFactorsAndTimeInput) -> Self { | ||
Check warning on line 98 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L98
|
||
Self { | ||
rule_set: value.rule_set.clone(), | ||
timed_recovery_delay_in_minutes: Some( | ||
Check warning on line 101 in crates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/access_controller_factors_and_time_input.rs#L100-L101
|
||
value.timed_recovery_delay_in_minutes, | ||
), | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use crate::prelude::*; | ||
|
||
// use radix_engine_interface::blueprints::access_controller::{ | ||
// AccessControllerTimedConfirmRecoveryInput as ScryptoAccessControllerTimedConfirmRecoveryInput, | ||
// ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT as SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, | ||
// }; | ||
|
||
pub trait TransactionManifestConfirmTimedRecovery { | ||
/// TBD | ||
/// TODO: Figure out how to do this... | ||
/// since `AccessControllerTimedConfirmRecoveryInput` need the input of | ||
/// the factors and time which was used to start recovery - which could not | ||
/// be quick confirmed. We need to figure out how we best represent this | ||
/// in Profile. Perhaps a new variant on ProvisionalSecurityConfig? Something | ||
/// like: | ||
/// `WaitingForTimedRecovery(SecurityStructureOfFactorInstances)` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @GhenadieVP good thing we kept |
||
fn confirm_timed_recovery() -> Result<TransactionManifest>; | ||
// { | ||
// builder.call_method( | ||
// access_controller, | ||
// SCRYPTO_ACCESS_CONTROLLER_TIMED_CONFIRM_RECOVERY_IDENT, | ||
// ScryptoAccessControllerTimedConfirmRecoveryInput::from( | ||
// factors_and_time, | ||
// ), | ||
// ); | ||
// } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
use profile_supporting_types::AnySecurifiedEntity; | ||
use radix_engine_interface::blueprints::access_controller::{ | ||
AccessControllerLockRecoveryFeeInput as ScryptoAccessControllerLockRecoveryFeeInput, | ||
ACCESS_CONTROLLER_LOCK_RECOVERY_FEE_IDENT as SCRYPTO_ACCESS_CONTROLLER_LOCK_RECOVERY_FEE_IDENT, | ||
}; | ||
use radix_transactions::prelude::ManifestBuilder; | ||
|
||
use crate::prelude::*; | ||
|
||
pub trait TransactionManifestLockFeeAgainstXrdVaultOfAccessController { | ||
/// Locks transaction fee against the XRD vault of the access controller of | ||
/// `entity_applying_shield` - either AC of an Account or of a Persona. | ||
/// | ||
/// We need to call this later when we have made a preview/dry-run of the | ||
/// `manifest` to get the actual fee to lock. | ||
/// | ||
/// `manifest` was produced by `apply_security_shield_for_securified_entity`. | ||
/// | ||
/// In fact we will be locking fee for 6 flavours of transaction manifest | ||
/// which updates the security shield of an entity, as returned by | ||
/// `TransactionManifestApplySecurityShieldKind::all()`, and we could try to | ||
/// be smart and run preview of each six to get a minimial fee per manifest, | ||
/// but we will avoid that complexity. | ||
/// | ||
/// Only relevant for securified entities - since it is only securified entities | ||
/// which have an access controller to lock against. | ||
fn modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller( | ||
Check warning on line 27 in crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs#L27
|
||
manifest: TransactionManifest, | ||
fee: Decimal192, | ||
// TODO: remove `entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity. | ||
entity_applying_shield: AnySecurifiedEntity, | ||
) -> TransactionManifest { | ||
let mut builder = ManifestBuilder::with_manifest(manifest); | ||
let access_controller_address = entity_applying_shield | ||
.securified_entity_control | ||
.access_controller_address; | ||
Check warning on line 36 in crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs#L33-L36
|
||
// Lock fee against XRD vault of the access controller | ||
builder = builder.call_method( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @0xOmarA here I'm appending this instruction last. Is that OK? Or must this be prepended, index 0 of the manifest? if so I need to do a lot of trickery to do that. Since I cannot create the instruction in rust code "manually" and since calling @GhenadieVP alternatively we just lock a "large" amount. Which ""should work"" for most shields... and if we do that we can lock fee in |
||
access_controller_address.scrypto(), | ||
SCRYPTO_ACCESS_CONTROLLER_LOCK_RECOVERY_FEE_IDENT, | ||
ScryptoAccessControllerLockRecoveryFeeInput { | ||
amount: ScryptoDecimal192::from(fee), | ||
Check warning on line 42 in crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs#L38-L42
|
||
}, | ||
); | ||
|
||
TransactionManifest::sargon_built( | ||
builder, | ||
entity_applying_shield.entity.network_id(), | ||
Check warning on line 48 in crates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/lock_fee_against_xrd_vault_of_access_controller.rs#L47-L48
|
||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#![allow(dead_code)] | ||
use crate::prelude::*; | ||
use std::ops::Deref; | ||
|
||
use profile_supporting_types::AnySecurifiedEntity; | ||
|
||
pub trait TransactionManifestSecurifySecurifiedEntity: | ||
TransactionManifestSetRolaKey | ||
{ | ||
fn apply_security_shield_for_securified_entity( | ||
securified_entity: AnySecurifiedEntity, | ||
security_structure_of_factor_instances: | ||
SecurityStructureOfFactorInstances, | ||
apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, | ||
) -> Result<TransactionManifest>; | ||
} | ||
|
||
impl TransactionManifestSecurifySecurifiedEntity for TransactionManifest { | ||
/// Updates the security shield of a securified entity to `security_structure_of_factor_instances`. | ||
/// | ||
/// Also conditionally updates the Rola key of the entity - if it is new. | ||
/// | ||
/// Later once we have got a preview from Gateway - we will need to call: | ||
/// * `modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller` | ||
/// | ||
/// And when we know the fee we can calculate how much to top up the XRD vault of the AccessController | ||
/// and call | ||
/// * `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` | ||
/// | ||
/// For timed confirmation - much later (`timed_recovery_delay_in_minutes` later ) the | ||
/// host app will need to call `confirm_timed_recovery` | ||
fn apply_security_shield_for_securified_entity( | ||
Check warning on line 32 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L32
|
||
securified_entity: AnySecurifiedEntity, | ||
security_structure_of_factor_instances: | ||
SecurityStructureOfFactorInstances, | ||
apply_shield_manifest_kind: TransactionManifestApplySecurityShieldKind, | ||
) -> Result<Self> { | ||
let kind = apply_shield_manifest_kind; | ||
let entity_address = securified_entity.entity.address(); | ||
Check warning on line 39 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L38-L39
|
||
|
||
// ACCESS_CONTROLLER_CREATE_PROOF_IDENT | ||
let mut builder = TransactionManifest::produce_owner_badge( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does:
|
||
ScryptoTransactionManifestBuilder::new(), | ||
&securified_entity.entity, | ||
Check warning on line 44 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L43-L44
|
||
); | ||
|
||
let access_controller_address = securified_entity | ||
.securified_entity_control | ||
.access_controller_address; | ||
Check warning on line 49 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L47-L49
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have forgotten to add the withdrawal of XRD from AccessControllera XRD vault. I’m adding it now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right we need to add the locking of fee against XRD vault of AccessController later (like the top up) - since we dont know how big a fee to lock. Ive added |
||
let factors_and_time_input = &AccessControllerFactorsAndTimeInput::new( | ||
&security_structure_of_factor_instances, | ||
Check warning on line 52 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L51-L52
|
||
); | ||
|
||
// INITIATE RECOVERY | ||
let (init_method, init_input) = | ||
kind.input_for_initialization(factors_and_time_input); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Depending on selector of which of the six For details see |
||
builder = builder.call_method( | ||
access_controller_address.scrypto(), | ||
init_method, | ||
(init_input.deref(),), | ||
Check warning on line 61 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L56-L61
|
||
); | ||
|
||
// QUICK CONFIRM RECOVERY - Only if we can exercise the confirmation role explicitly. | ||
if let Some((confirm_method, confirm_input)) = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only call "quick confirm" if we can exercise confirmation role explicitly. Else we skip quick confirm and we will LATER ( |
||
kind.input_for_quick_confirm(factors_and_time_input) | ||
Check warning on line 66 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L65-L66
|
||
{ | ||
builder = builder.call_method( | ||
access_controller_address.scrypto(), | ||
confirm_method, | ||
(confirm_input.deref(),), | ||
); | ||
} | ||
|
||
// Set Rola Key | ||
let should_set_rola_key = security_structure_of_factor_instances | ||
.authentication_signing_factor_instance | ||
!= securified_entity | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dont set ROLA key if it is unchanged |
||
.current_authentication_signing_factor_instance(); | ||
Check warning on line 79 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L76-L79
|
||
|
||
if should_set_rola_key { | ||
if kind.can_set_rola_key() { | ||
builder = TransactionManifest::set_rola_key( | ||
builder, | ||
&security_structure_of_factor_instances | ||
.authentication_signing_factor_instance, | ||
&entity_address, | ||
Check warning on line 87 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L81-L87
|
||
); | ||
} else { | ||
return Err(CommonError::Unknown); // TODO: new error variant | ||
Check warning on line 90 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L90
|
||
} | ||
} | ||
|
||
let manifest = TransactionManifest::sargon_built( | ||
builder, | ||
securified_entity.network_id(), | ||
Check warning on line 96 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L95-L96
|
||
); | ||
|
||
// N.B. | ||
// We will not lock fee against the XRD vault yet - we will do that | ||
// later when we have made a preview/dry-run of the `manifest` to get | ||
// the estimated fee to lock, by calling `modify_manifest_add_lock_fee_against_xrd_vault_of_access_controller` | ||
// | ||
// Furthermore: | ||
// We do NOT top of XRD vault of AccessController - yet! | ||
// Host will need to call the function: | ||
// `modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account` | ||
// after user has selected account to pay in wallet GUI. | ||
// (and as usual also call `modify_manifest_lock_fee`) | ||
|
||
Ok(manifest) | ||
Check warning on line 111 in crates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs Codecov / codecov/patchcrates/transaction/manifests/src/manifests_security_shield/manifests_securify_shield_securified_entity.rs#L111
|
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shared type to create:
AccessControllerInitiateRecoveryAsPrimaryInput
AccessControllerInitiateRecoveryAsRecoveryInput
AccessControllerQuickConfirmPrimaryRoleRecoveryProposalInput
AccessControllerQuickConfirmRecoveryRoleRecoveryProposalInput
AccessControllerTimedConfirmRecoveryInput
Input to
call_method
instruction, usingSecurityStructureOfFactorInstances
- which isInto<RuleSet>
(and time u32).