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

Skipped | Failed -> Rejected. #4

Merged
merged 6 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions _typos.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
default.extend-ignore-identifiers-re = [
"[Hh][Dd][[:alnum:]]*"
]
51 changes: 22 additions & 29 deletions src/signing/collector/signatures_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl SignaturesCollector {
Continue
}

async fn use_factor_sources(&self, factor_sources_of_kind: &FactorSourcesOfKind) -> Result<()> {
async fn sign_with_factors_of_kind(&self, factor_sources_of_kind: FactorSourcesOfKind) {
let interactor = self
.dependencies
.interactors
Expand All @@ -161,15 +161,15 @@ impl SignaturesCollector {
.map(|f| f.factor_source_id())
.collect(),
);
if !request.invalid_transactions_if_skipped.is_empty() {
if !request.invalid_transactions_if_neglected.is_empty() {
info!(
"If factors {:?} are skipped, invalid TXs: {:?}",
"If factors {:?} are neglected, invalid TXs: {:?}",
request.per_factor_source.keys(),
request.invalid_transactions_if_skipped
request.invalid_transactions_if_neglected
)
}
debug!("Dispatching parallel request to interactor: {:?}", request);
let response = interactor.sign(request).await?;
let response = interactor.sign(request).await;
debug!("Got response from parallel interactor: {:?}", response);
self.process_batch_response(response);
}
Expand All @@ -185,16 +185,17 @@ impl SignaturesCollector {
let request =
self.request_for_serial_interactor(&factor_source.factor_source_id());

if !request.invalid_transactions_if_skipped.is_empty() {
if !request.invalid_transactions_if_neglected.is_empty() {
info!(
"If factor {:?} are skipped, invalid TXs: {:?}",
request.input.factor_source_id, request.invalid_transactions_if_skipped
"If factor {:?} are neglected, invalid TXs: {:?}",
request.input.factor_source_id,
request.invalid_transactions_if_neglected
)
}

debug!("Dispatching serial request to interactor: {:?}", request);
// Produce the results from the interactor
let response = interactor.sign(request).await?;
let response = interactor.sign(request).await;
debug!("Got response from serial interactor: {:?}", response);

// Report the results back to the collector
Expand All @@ -206,17 +207,6 @@ impl SignaturesCollector {
}
}
}
Ok(())
}

async fn sign_with_factors_of_kind(&self, factor_sources_of_kind: FactorSourcesOfKind) {
let Err(e) = self.use_factor_sources(&factor_sources_of_kind).await else {
return;
};
error!("Failure using factor {:?}", e);
self.process_batch_response(SignWithFactorSourceOrSourcesOutcome::Skipped {
ids_of_skipped_factors_sources: factor_sources_of_kind.factor_source_ids(),
})
}

/// In decreasing "friction order"
Expand Down Expand Up @@ -256,7 +246,7 @@ impl SignaturesCollector {

SerialBatchSigningRequest::new(
batch_signing_request,
self.invalid_transactions_if_skipped_factor_sources(IndexSet::from_iter([
self.invalid_transactions_if_neglected_factor_sources(IndexSet::from_iter([
*factor_source_id,
]))
.into_iter()
Expand All @@ -274,27 +264,30 @@ impl SignaturesCollector {
.map(|fid| (*fid, self.input_for_interactor(fid)))
.collect::<IndexMap<FactorSourceIDFromHash, BatchTXBatchKeySigningRequest>>();

let invalid_transactions_if_skipped =
self.invalid_transactions_if_skipped_factor_sources(factor_source_ids);
let invalid_transactions_if_neglected =
self.invalid_transactions_if_neglected_factor_sources(factor_source_ids);

info!("Invalid if skipped: {:?}", invalid_transactions_if_skipped);
info!(
"Invalid if neglected: {:?}",
invalid_transactions_if_neglected
);

// Prepare the request for the interactor
ParallelBatchSigningRequest::new(per_factor_source, invalid_transactions_if_skipped)
ParallelBatchSigningRequest::new(per_factor_source, invalid_transactions_if_neglected)
}

fn invalid_transactions_if_skipped_factor_sources(
fn invalid_transactions_if_neglected_factor_sources(
&self,
factor_source_ids: IndexSet<FactorSourceIDFromHash>,
) -> IndexSet<InvalidTransactionIfSkipped> {
) -> IndexSet<InvalidTransactionIfNeglected> {
self.state
.borrow()
.petitions
.borrow()
.invalid_transactions_if_skipped_factors(factor_source_ids)
.invalid_transactions_if_neglected_factors(factor_source_ids)
}

fn process_batch_response(&self, response: SignWithFactorSourceOrSourcesOutcome) {
fn process_batch_response(&self, response: SignWithFactorsOutcome) {
let state = self.state.borrow_mut();
let petitions = state.petitions.borrow_mut();
petitions.process_batch_response(response)
Expand Down
6 changes: 3 additions & 3 deletions src/signing/interactors/parallel_batch_signing_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ pub struct ParallelBatchSigningRequest {

/// A collection of transactions which would be invalid if the user skips
/// signing with this factor source.
pub invalid_transactions_if_skipped: IndexSet<InvalidTransactionIfSkipped>,
pub invalid_transactions_if_neglected: IndexSet<InvalidTransactionIfNeglected>,
}

impl ParallelBatchSigningRequest {
pub fn new(
per_factor_source: IndexMap<FactorSourceIDFromHash, BatchTXBatchKeySigningRequest>,
invalid_transactions_if_skipped: IndexSet<InvalidTransactionIfSkipped>,
invalid_transactions_if_neglected: IndexSet<InvalidTransactionIfNeglected>,
) -> Self {
Self {
per_factor_source,
invalid_transactions_if_skipped,
invalid_transactions_if_neglected,
}
}
}
10 changes: 5 additions & 5 deletions src/signing/interactors/serial_batch_signing_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ use crate::prelude::*;
/// A batch signing request used with a SignWithFactorSerialInteractor, containing
/// a collection of transactions to sign with multiple keys (derivation paths),
/// and a collection of transactions which would be invalid if the user skips
/// signing with this factor source.
/// signing with this factor source, or if we fail to sign.
#[derive(derive_more::Debug)]
#[debug("input: {:#?}", input)]
pub struct SerialBatchSigningRequest {
pub input: BatchTXBatchKeySigningRequest,
/// A collection of transactions which would be invalid if the user skips
/// signing with this factor source.
pub invalid_transactions_if_skipped: Vec<InvalidTransactionIfSkipped>,
/// signing with this factor source, or if we fail to sign
pub invalid_transactions_if_neglected: Vec<InvalidTransactionIfNeglected>,
}

impl SerialBatchSigningRequest {
pub fn new(
input: BatchTXBatchKeySigningRequest,
invalid_transactions_if_skipped: Vec<InvalidTransactionIfSkipped>,
invalid_transactions_if_neglected: Vec<InvalidTransactionIfNeglected>,
) -> Self {
Self {
input,
invalid_transactions_if_skipped,
invalid_transactions_if_neglected,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,5 @@ use crate::prelude::*;
/// Example of a Parallel Batch Signing Driver is that for DeviceFactorSource.
#[async_trait::async_trait]
pub trait SignWithFactorParallelInteractor {
async fn sign(
&self,
request: ParallelBatchSigningRequest,
) -> Result<SignWithFactorSourceOrSourcesOutcome>;
async fn sign(&self, request: ParallelBatchSigningRequest) -> SignWithFactorsOutcome;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,5 @@ use crate::prelude::*;
/// might not even even allow multiple SecurityQuestionsFactorSources to be used).
#[async_trait::async_trait]
pub trait SignWithFactorSerialInteractor {
async fn sign(
&self,
request: SerialBatchSigningRequest,
) -> Result<SignWithFactorSourceOrSourcesOutcome>;
async fn sign(&self, request: SerialBatchSigningRequest) -> SignWithFactorsOutcome;
}
69 changes: 37 additions & 32 deletions src/signing/petition_types/petition_entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ impl PetitionEntity {
.collect::<IndexSet<_>>()
}

pub fn all_skipped_factor_instance(&self) -> IndexSet<HierarchicalDeterministicFactorInstance> {
self.union_of(|f| f.all_skipped())
pub fn all_neglected_factor_instances(&self) -> IndexSet<NeglectedFactorInstance> {
self.union_of(|f| f.all_neglected())
}

pub fn all_skipped_factor_sources(&self) -> IndexSet<FactorSourceIDFromHash> {
self.all_skipped_factor_instance()
pub fn all_neglected_factor_sources(&self) -> IndexSet<NeglectedFactor> {
self.all_neglected_factor_instances()
.into_iter()
.map(|f| f.factor_source_id)
.map(|n| n.as_neglected_factor())
.collect::<IndexSet<_>>()
}

Expand Down Expand Up @@ -143,12 +143,12 @@ impl PetitionEntity {
self.both(r#do, |_, _| ())
}

pub fn skipped_factor_source_if_relevant(&self, factor_source_id: &FactorSourceIDFromHash) {
self.both_void(|l| l.skip_if_references(factor_source_id, true));
pub fn neglected_factor_source_if_relevant(&self, neglected: NeglectedFactor) {
self.both_void(|l| l.neglect_if_references(neglected.clone(), true));
}

/// # Panics
/// Panics if this factor source has already been skipped or signed with.
/// Panics if this factor source has already been neglected or signed with.
///
/// Or panics if the factor source is not known to this petition.
pub fn add_signature(&self, signature: HDSignature) {
Expand All @@ -164,17 +164,17 @@ impl PetitionEntity {
})
}

pub fn invalid_transactions_if_skipped_factors(
pub fn invalid_transactions_if_neglected_factors(
&self,
factor_source_ids: IndexSet<FactorSourceIDFromHash>,
) -> IndexSet<InvalidTransactionIfSkipped> {
let skip_status = self.status_if_skipped_factors(factor_source_ids);
match skip_status {
) -> IndexSet<InvalidTransactionIfNeglected> {
let status_if_neglected = self.status_if_neglected_factors(factor_source_ids);
match status_if_neglected {
PetitionFactorsStatus::Finished(finished_reason) => match finished_reason {
PetitionFactorsStatusFinished::Fail => {
let intent_hash = self.intent_hash.clone();
let invalid_transaction =
InvalidTransactionIfSkipped::new(intent_hash, vec![self.entity.clone()]);
InvalidTransactionIfNeglected::new(intent_hash, vec![self.entity.clone()]);
IndexSet::from_iter([invalid_transaction])
}
PetitionFactorsStatusFinished::Success => IndexSet::new(),
Expand All @@ -183,25 +183,27 @@ impl PetitionEntity {
}
}

pub fn status_if_skipped_factors(
pub fn status_if_neglected_factors(
&self,
factor_source_ids: IndexSet<FactorSourceIDFromHash>,
) -> PetitionFactorsStatus {
let simulation = self.clone();
for factor_source_id in factor_source_ids.iter() {
simulation
.did_skip_if_relevant(factor_source_id, true)
.neglect_if_relevant(
NeglectedFactor::new(
NeglectFactorReason::UserExplicitlySkipped,
*factor_source_id,
),
true,
)
.unwrap();
}
simulation.status()
}

pub fn did_skip_if_relevant(
&self,
factor_source_id: &FactorSourceIDFromHash,
simulated: bool,
) -> Result<()> {
self.both_void(|p| p.did_skip_if_relevant(factor_source_id, simulated));
pub fn neglect_if_relevant(&self, neglected: NeglectedFactor, simulated: bool) -> Result<()> {
self.both_void(|p| p.neglect_if_relevant(neglected.clone(), simulated));
Ok(())
}

Expand Down Expand Up @@ -299,7 +301,7 @@ mod tests {
let entity = AddressOfAccountOrPersona::Account(AccountAddress::sample());
let tx = IntentHash::sample_third();
let sut = Sut::new_securified(tx.clone(), entity.clone(), matrix);
let invalid = sut.invalid_transactions_if_skipped_factors(IndexSet::from_iter([
let invalid = sut.invalid_transactions_if_neglected_factors(IndexSet::from_iter([
d0.factor_source_id(),
d1.factor_source_id(),
]));
Expand Down Expand Up @@ -337,8 +339,9 @@ mod tests {
let entity = AddressOfAccountOrPersona::Account(AccountAddress::sample());
let tx = IntentHash::sample_third();
let sut = Sut::new_securified(tx.clone(), entity.clone(), matrix);
let invalid = sut
.invalid_transactions_if_skipped_factors(IndexSet::from_iter([d0.factor_source_id()]));
let invalid = sut.invalid_transactions_if_neglected_factors(IndexSet::from_iter([
d0.factor_source_id()
]));
assert!(invalid.is_empty());
}

Expand All @@ -362,7 +365,7 @@ mod tests {
let entity = AddressOfAccountOrPersona::Account(AccountAddress::sample());
let tx = IntentHash::sample_third();
let sut = Sut::new_securified(tx.clone(), entity.clone(), matrix);
let invalid = sut.invalid_transactions_if_skipped_factors(IndexSet::from_iter([
let invalid = sut.invalid_transactions_if_neglected_factors(IndexSet::from_iter([
d0.factor_source_id(),
d1.factor_source_id(),
]));
Expand Down Expand Up @@ -404,8 +407,9 @@ mod tests {
let tx = IntentHash::sample_third();
let sut = Sut::new_securified(tx.clone(), entity.clone(), matrix);

let invalid = sut
.invalid_transactions_if_skipped_factors(IndexSet::from_iter([d1.factor_source_id()]));
let invalid = sut.invalid_transactions_if_neglected_factors(IndexSet::from_iter([
d1.factor_source_id()
]));

assert_eq!(
invalid
Expand Down Expand Up @@ -445,15 +449,16 @@ mod tests {
let tx = IntentHash::sample_third();
let sut = Sut::new_securified(tx.clone(), entity.clone(), matrix);

let invalid = sut
.invalid_transactions_if_skipped_factors(IndexSet::from_iter([d1.factor_source_id()]));
let invalid = sut.invalid_transactions_if_neglected_factors(IndexSet::from_iter([
d1.factor_source_id()
]));

assert!(invalid.is_empty());
}

#[test]
fn debug() {
pretty_assertions::assert_eq!(format!("{:?}", Sut::sample()), "intent_hash: TXID(\"dedede\"), entity: acco_Grace, \"threshold_factors PetitionFactors(input: PetitionFactorsInput(factors: {\\n factor_source_id: Device:00, derivation_path: 0/A/tx/6,\\n factor_source_id: Arculus:03, derivation_path: 0/A/tx/6,\\n factor_source_id: Yubikey:05, derivation_path: 0/A/tx/6,\\n}), state_snapshot: signatures: \\\"\\\", skipped: \\\"\\\")\"\"override_factors PetitionFactors(input: PetitionFactorsInput(factors: {\\n factor_source_id: Ledger:01, derivation_path: 0/A/tx/6,\\n factor_source_id: Arculus:04, derivation_path: 0/A/tx/6,\\n}), state_snapshot: signatures: \\\"\\\", skipped: \\\"\\\")\"");
pretty_assertions::assert_eq!(format!("{:?}", Sut::sample()), "intent_hash: TXID(\"dedede\"), entity: acco_Grace, \"threshold_factors PetitionFactors(input: PetitionFactorsInput(factors: {\\n factor_source_id: Device:00, derivation_path: 0/A/tx/6,\\n factor_source_id: Arculus:03, derivation_path: 0/A/tx/6,\\n factor_source_id: Yubikey:05, derivation_path: 0/A/tx/6,\\n}), state_snapshot: signatures: \\\"\\\", neglected: \\\"\\\")\"\"override_factors PetitionFactors(input: PetitionFactorsInput(factors: {\\n factor_source_id: Ledger:01, derivation_path: 0/A/tx/6,\\n factor_source_id: Arculus:04, derivation_path: 0/A/tx/6,\\n}), state_snapshot: signatures: \\\"\\\", neglected: \\\"\\\")\"");
}

#[test]
Expand Down Expand Up @@ -517,7 +522,7 @@ mod tests {
}

#[test]
fn invalid_transactions_if_skipped_success() {
fn invalid_transactions_if_neglected_success() {
let sut = Sut::sample();
sut.add_signature(HDSignature::produced_signing_with_input(
HDSignatureInput::new(
Expand All @@ -535,7 +540,7 @@ mod tests {
assert!(sut
// Already signed with override factor `FactorSourceIDFromHash::fs1()`. Thus
// can skip
.invalid_transactions_if_skipped_factors(IndexSet::from_iter([f]))
.invalid_transactions_if_neglected_factors(IndexSet::from_iter([f]))
.is_empty())
};
can_skip(FactorSourceIDFromHash::fs0());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::prelude::*;

pub trait FactorSourceReferencing: std::hash::Hash + PartialEq + Eq + Clone {
Copy link
Contributor

Choose a reason for hiding this comment

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

Make crate pub?

fn factor_source_id(&self) -> FactorSourceIDFromHash;
}

impl FactorSourceReferencing for HierarchicalDeterministicFactorInstance {
fn factor_source_id(&self) -> FactorSourceIDFromHash {
self.factor_source_id
}
}

impl FactorSourceReferencing for HDSignature {
fn factor_source_id(&self) -> FactorSourceIDFromHash {
self.owned_factor_instance()
.factor_instance()
.factor_source_id
}
}
Loading
Loading