From 5ee2a88b4fc80e9f833655b29446037026b671f5 Mon Sep 17 00:00:00 2001 From: Dmitry Borodin Date: Thu, 16 Nov 2023 11:55:05 +0300 Subject: [PATCH 1/4] work in progress - make transactions signing possible without state machine --- rust/navigator/src/lib.rs | 91 +++++++++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 8 deletions(-) diff --git a/rust/navigator/src/lib.rs b/rust/navigator/src/lib.rs index 041be72da9..0993bdd46c 100644 --- a/rust/navigator/src/lib.rs +++ b/rust/navigator/src/lib.rs @@ -41,6 +41,7 @@ pub mod screens; mod tests; pub use crate::error::{Error, Result}; +use crate::states::{SignResult, TransactionState}; //TODO: multithread here some day! lazy_static! { @@ -77,15 +78,89 @@ pub fn init_navigation(db: sled::Db, seed_names: Vec) -> Result<()> { Ok(()) } -/// Should be called when seed names are modified in native to synchronize data -pub fn update_seed_names(seed_names: Vec) -> Result<()> { - let mut navstate = STATE.lock().map_err(|_| Error::MutexPoisoned)?; - navstate - .as_mut() - .ok_or(Error::DbNotInitialized)? - .update_seed_names(seed_names); +/// Generate transaction from qr codes assembled data +pub fn get_transaction(database: &sled::Db, details_str: &str) -> Result { + Ok(TransactionState::new(database, details_str)?) +} - Ok(()) +pub fn sign_transaction(database: &sled::Db, + transaction_state: TransactionState, + password: Option<&str>,) -> Result<()> { + match transaction_state.action() { + transaction_parsing::TransactionAction::Sign { .. } => { + let mut new = transactionState.clone(); + new.update_seeds(secret_seed_phrase); + match password { + None => {} + Some(pass) => {new.password_entered(pass);} + } + + match new.handle_sign(database) { + Ok(result) => { + match result { + SignResult::RequestPassword { .. } => { + if t.ok() { + // here juse return wrong password error + new_navstate.screen = Screen::Transaction(new); + new_navstate.modal = Modal::EnterPassword; + } else { + new_navstate = Navstate::clean_screen(Screen::Log); + } + } + SignResult::Ready { signatures } => { + // result + new_navstate.modal = Modal::SignatureReady(signatures); + } + }; + } + Err(e) => { + // new_navstate.alert = Alert::Error; + // let _ = write!(&mut errorline, "{e}"); + // todo pass our error displayed with str + } + } + } + transaction_parsing::TransactionAction::Stub { + s: _, + u: checksum, + stub: stub_nav, + } => match transaction_signing::handle_stub(&self.db, *checksum) { + Ok(()) => match stub_nav { + transaction_parsing::StubNav::AddSpecs { + n: network_specs_key, + } => { + // check in what we do here, we may returm type of transaction or just blank processed + // check if we call sign for those transactions at all from mobile end + new_navstate = Navstate::clean_screen(Screen::NetworkDetails( + network_specs_key.clone(), + )); + } + transaction_parsing::StubNav::LoadMeta { + l: network_specs_key, + } => { + new_navstate = Navstate::clean_screen(Screen::NetworkDetails( + network_specs_key.clone(), + )); + } + transaction_parsing::StubNav::LoadTypes => { + new_navstate = Navstate::clean_screen(Screen::ManageNetworks); + } + }, + Err(e) => { + // new_navstate.alert = Alert::Error; + // let _ = write!(&mut errorline, "{e}"); + // todo pass our error displayed with str + } + }, + transaction_parsing::TransactionAction::Read { .. } => { + // do nothing + } + transaction_parsing::TransactionAction::Derivations { content: _ } => { + new_navstate = Navstate::clean_screen(Screen::SeedSelector); + } + }, + + Ok(()) //todo dmitry implement } /// Export key info with derivations. From 929b7f9cfd4fd994044da3dfd9af5ea5e0ab2d9a Mon Sep 17 00:00:00 2001 From: Dmitry Borodin Date: Fri, 17 Nov 2023 11:49:25 +0300 Subject: [PATCH 2/4] added comments as during discussion --- .../domain/backend/ScanFlowInteractor.kt | 3 +-- .../signer/screens/scan/ScanViewModel.kt | 2 +- rust/navigator/src/lib.rs | 18 +++++++++++++----- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/android/src/main/java/io/parity/signer/domain/backend/ScanFlowInteractor.kt b/android/src/main/java/io/parity/signer/domain/backend/ScanFlowInteractor.kt index 5b333c0bc8..b6ab5cba0c 100644 --- a/android/src/main/java/io/parity/signer/domain/backend/ScanFlowInteractor.kt +++ b/android/src/main/java/io/parity/signer/domain/backend/ScanFlowInteractor.kt @@ -1,6 +1,5 @@ package io.parity.signer.domain.backend -import io.parity.signer.R import io.parity.signer.domain.FakeNavigator import io.parity.signer.domain.NavigationError import io.parity.signer.domain.Navigator @@ -63,7 +62,7 @@ class ScanFlowInteractor { ) } - suspend fun performTransaction(payload: String): OperationResult { + suspend fun getTransaction(payload: String): OperationResult { resetMachineState() return try { OperationResult.Ok( diff --git a/android/src/main/java/io/parity/signer/screens/scan/ScanViewModel.kt b/android/src/main/java/io/parity/signer/screens/scan/ScanViewModel.kt index 546ba661a1..48be1b02f3 100644 --- a/android/src/main/java/io/parity/signer/screens/scan/ScanViewModel.kt +++ b/android/src/main/java/io/parity/signer/screens/scan/ScanViewModel.kt @@ -80,7 +80,7 @@ class ScanViewModel : ViewModel() { return } transactionIsInProgress.value = true - val navigateResponse = scanFlowInteractor.performTransaction(payload) + val navigateResponse = scanFlowInteractor.getTransaction(payload) when (navigateResponse) { is OperationResult.Err -> { diff --git a/rust/navigator/src/lib.rs b/rust/navigator/src/lib.rs index 0993bdd46c..a5b9a40da3 100644 --- a/rust/navigator/src/lib.rs +++ b/rust/navigator/src/lib.rs @@ -79,16 +79,23 @@ pub fn init_navigation(db: sled::Db, seed_names: Vec) -> Result<()> { } /// Generate transaction from qr codes assembled data -pub fn get_transaction(database: &sled::Db, details_str: &str) -> Result { - Ok(TransactionState::new(database, details_str)?) +pub fn get_transaction(database: &sled::Db, payload: &str) -> Result { + //return mtransaction data??? to know which keys used to sign and transaction action + Ok(TransactionState::new(database, details_str)?.action()?) } +//todo validate password for key function create + +/// all passwords should be validated separately before and here we just signing +/// transaction, that can be bulk, and expecting that error should never ocure pub fn sign_transaction(database: &sled::Db, - transaction_state: TransactionState, - password: Option<&str>,) -> Result<()> { + //list of seeds if needed, + transaction_state: TransactionAction, + password: Option<&str>,//todo pass passwords for keys + ) -> Result<()> { match transaction_state.action() { transaction_parsing::TransactionAction::Sign { .. } => { - let mut new = transactionState.clone(); + let mut new = transaction_state.clone(); new.update_seeds(secret_seed_phrase); match password { None => {} @@ -125,6 +132,7 @@ pub fn sign_transaction(database: &sled::Db, u: checksum, stub: stub_nav, } => match transaction_signing::handle_stub(&self.db, *checksum) { + //todo check when we actually executing this actions in state machine. Not when transaction signing happening looks like Ok(()) => match stub_nav { transaction_parsing::StubNav::AddSpecs { n: network_specs_key, From 2928bcf66d77b3f103eccce95961d1b44de3675d Mon Sep 17 00:00:00 2001 From: Dmitry Borodin Date: Fri, 17 Nov 2023 12:16:54 +0300 Subject: [PATCH 3/4] added comments as during discussion 2 --- .../domain/backend/ScanFlowInteractor.kt | 2 +- .../signer/screens/scan/ScanViewModel.kt | 2 +- rust/navigator/src/lib.rs | 19 +++++++++++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/android/src/main/java/io/parity/signer/domain/backend/ScanFlowInteractor.kt b/android/src/main/java/io/parity/signer/domain/backend/ScanFlowInteractor.kt index b6ab5cba0c..a20a0b59b7 100644 --- a/android/src/main/java/io/parity/signer/domain/backend/ScanFlowInteractor.kt +++ b/android/src/main/java/io/parity/signer/domain/backend/ScanFlowInteractor.kt @@ -44,7 +44,7 @@ class ScanFlowInteractor { navigator.navigate(Action.NAVBAR_SCAN) } - suspend fun continueSigningTransaction( + suspend fun continuePerformTransaction( comment: String, seedPhrases: String ): ActionResult? { diff --git a/android/src/main/java/io/parity/signer/screens/scan/ScanViewModel.kt b/android/src/main/java/io/parity/signer/screens/scan/ScanViewModel.kt index 48be1b02f3..3d2dfe5de4 100644 --- a/android/src/main/java/io/parity/signer/screens/scan/ScanViewModel.kt +++ b/android/src/main/java/io/parity/signer/screens/scan/ScanViewModel.kt @@ -440,7 +440,7 @@ class ScanViewModel : ViewModel() { } is RepoResult.Success -> { - scanFlowInteractor.continueSigningTransaction( + scanFlowInteractor.continuePerformTransaction( comment, phrases.result, ) diff --git a/rust/navigator/src/lib.rs b/rust/navigator/src/lib.rs index a5b9a40da3..7b6ebaff63 100644 --- a/rust/navigator/src/lib.rs +++ b/rust/navigator/src/lib.rs @@ -79,20 +79,24 @@ pub fn init_navigation(db: sled::Db, seed_names: Vec) -> Result<()> { } /// Generate transaction from qr codes assembled data +/// pub fn get_transaction(database: &sled::Db, payload: &str) -> Result { //return mtransaction data??? to know which keys used to sign and transaction action Ok(TransactionState::new(database, details_str)?.action()?) } -//todo validate password for key function create +//todo create function to validate password for key function +/// sign signing type transactions or perform stub transactions +/// //todo devide into 2 - sign and perform stub /// all passwords should be validated separately before and here we just signing /// transaction, that can be bulk, and expecting that error should never ocure -pub fn sign_transaction(database: &sled::Db, - //list of seeds if needed, +pub fn perform_transaction(database: &sled::Db, + //list of seeds if needed - for sign type, transaction_state: TransactionAction, - password: Option<&str>,//todo pass passwords for keys - ) -> Result<()> { + password: Vec<&str>,//todo pass passwords for keys + ) -> Result> { + //return list of signatures match transaction_state.action() { transaction_parsing::TransactionAction::Sign { .. } => { let mut new = transaction_state.clone(); @@ -131,8 +135,7 @@ pub fn sign_transaction(database: &sled::Db, s: _, u: checksum, stub: stub_nav, - } => match transaction_signing::handle_stub(&self.db, *checksum) { - //todo check when we actually executing this actions in state machine. Not when transaction signing happening looks like + } => match transaction_signing::handle_stub(&self.db, *checksum) { //save pending transaction to DB Ok(()) => match stub_nav { transaction_parsing::StubNav::AddSpecs { n: network_specs_key, @@ -164,7 +167,7 @@ pub fn sign_transaction(database: &sled::Db, // do nothing } transaction_parsing::TransactionAction::Derivations { content: _ } => { - new_navstate = Navstate::clean_screen(Screen::SeedSelector); + // do nothing } }, From 4f07f24f947cf6eddd14405ef8680ef96c7d5884 Mon Sep 17 00:00:00 2001 From: Dmitry Borodin Date: Fri, 17 Nov 2023 12:44:29 +0300 Subject: [PATCH 4/4] added comments as during discussion 3 --- rust/navigator/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rust/navigator/src/lib.rs b/rust/navigator/src/lib.rs index 7b6ebaff63..101bae587e 100644 --- a/rust/navigator/src/lib.rs +++ b/rust/navigator/src/lib.rs @@ -78,8 +78,13 @@ pub fn init_navigation(db: sled::Db, seed_names: Vec) -> Result<()> { Ok(()) } + +///todo dmitry add function to get transaction type and validate. It exeists - it's +/// todo decode_sequence - but we need to add types from TransactionAction there +/// for Example - for banana split and dyn derivations use specific function, or get_transaction() for rest + /// Generate transaction from qr codes assembled data -/// +/// todo dmitry support all types from above todo or make many functions for each transaction type pub fn get_transaction(database: &sled::Db, payload: &str) -> Result { //return mtransaction data??? to know which keys used to sign and transaction action Ok(TransactionState::new(database, details_str)?.action()?)