From b288b601ceca5850f21daff573ca172f8e1a0b7c Mon Sep 17 00:00:00 2001 From: librelois Date: Sat, 9 Jan 2021 21:12:52 +0100 Subject: [PATCH] ref(dubp):make really async & rework handle error in a more generic way --- .cargo/config.toml | 3 + Cargo.lock | 71 ++++++++++++++ native/dubp_rs/Cargo.toml | 2 + native/dubp_rs/src/async.rs | 42 +++++++++ native/dubp_rs/src/dewif.rs | 64 +++---------- native/dubp_rs/src/error.rs | 77 +++++++++++++++ native/dubp_rs/src/lib.rs | 168 ++++++++++++++++++--------------- native/dubp_rs/src/mnemonic.rs | 7 +- packages/dubp_rs/lib/dubp.dart | 31 +++--- pubspec.lock | 45 ++++----- 10 files changed, 333 insertions(+), 177 deletions(-) create mode 100644 .cargo/config.toml create mode 100644 native/dubp_rs/src/async.rs create mode 100644 native/dubp_rs/src/error.rs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..393611e --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,3 @@ +[alias] +bd = "make android-dev32" +br = "make" diff --git a/Cargo.lock b/Cargo.lock index 93595d1..2c6ad0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,6 +59,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "async-oneshot" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f4770cbbff928c30a991de67fb3976f44d8e3e202f8c79ef91b47006e04904" +dependencies = [ + "futures-micro", +] + [[package]] name = "atty" version = "0.2.14" @@ -245,6 +254,8 @@ dependencies = [ "cbindgen", "dart-bindgen", "dup-crypto", + "fast-threadpool", + "once_cell", "thiserror", ] @@ -270,6 +281,32 @@ dependencies = [ "zeroize", ] +[[package]] +name = "fast-threadpool" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccb66774e02743b4be61c19e09bf59de9058e9a7b4096040689003e7a901a3d" +dependencies = [ + "async-oneshot", + "flume", + "num_cpus", +] + +[[package]] +name = "flume" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0362ef9c4c1fa854ff95b4cb78045a86e810d804dc04937961988b45427104a9" +dependencies = [ + "spinning_top", +] + +[[package]] +name = "futures-micro" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e9325be55c5581082cd110294fa988c1f920bc573ec370ef201e33c469a95a" + [[package]] name = "generic-array" version = "0.14.4" @@ -344,6 +381,15 @@ version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +[[package]] +name = "lock_api" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.11" @@ -353,6 +399,16 @@ dependencies = [ "cfg-if 0.1.10", ] +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "once_cell" version = "1.5.2" @@ -466,6 +522,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "serde" version = "1.0.118" @@ -503,6 +565,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spinning_top" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e529d73e80d64b5f2631f9035113347c578a1c9c7774b83a2b880788459ab36" +dependencies = [ + "lock_api", +] + [[package]] name = "strsim" version = "0.8.0" diff --git a/native/dubp_rs/Cargo.toml b/native/dubp_rs/Cargo.toml index feeb05b..58d56c9 100644 --- a/native/dubp_rs/Cargo.toml +++ b/native/dubp_rs/Cargo.toml @@ -11,6 +11,8 @@ crate-type = ["rlib"] [dependencies] allo-isolate = "0.1.6" dup-crypto = { version = "0.36.0", features = ["dewif", "mnemonic", "mnemonic_french", "rand", "scrypt"] } +fast-threadpool = { version = "0.3.0", default-features = false } +once_cell = { version = "1.3.1", default-features = false, features = ["std"] } thiserror = "1.0.23" [build-dependencies] diff --git a/native/dubp_rs/src/async.rs b/native/dubp_rs/src/async.rs new file mode 100644 index 0000000..b7ce764 --- /dev/null +++ b/native/dubp_rs/src/async.rs @@ -0,0 +1,42 @@ +// Copyright (C) 2020 Éloïs SANCHEZ. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use crate::*; + +static THREAD_POOL: Lazy> = Lazy::new(|| { + ThreadPool::start(ThreadPoolConfig::low().queue_size(Some(16)), ()).into_sync_handler() +}); + +pub(crate) fn exec_async(port: i64, parse_params: F, async_job: F2) +where + P: 'static + Send + Sync, + F: FnOnce() -> Result, + F2: 'static + Send + Sync + FnOnce(P) -> R, + DartRes: From, +{ + match parse_params() { + Ok(parsed_params) => { + if THREAD_POOL + .launch(move |_| Isolate::new(port).post(DartRes::from(async_job(parsed_params)))) + .is_err() + { + Isolate::new(port).post(DartRes::err("thread pool panicked")); + } + } + Err(e) => { + Isolate::new(port).post(DartRes::err(e)); + } + } +} diff --git a/native/dubp_rs/src/dewif.rs b/native/dubp_rs/src/dewif.rs index 7d07565..6e9932c 100644 --- a/native/dubp_rs/src/dewif.rs +++ b/native/dubp_rs/src/dewif.rs @@ -35,16 +35,11 @@ pub(super) fn gen_pin10() -> Result { } pub(super) fn change_pin( - currency: *const raw::c_char, - dewif: *const raw::c_char, - old_pin: *const raw::c_char, - new_pin: *const raw::c_char, + currency: &str, + dewif: &str, + old_pin: &str, + new_pin: &str, ) -> Result { - let currency = char_ptr_to_str(currency)?; - let dewif = char_ptr_to_str(dewif)?; - let old_pin = char_ptr_to_str(old_pin)?; - let new_pin = char_ptr_to_str(new_pin)?; - let currency = parse_currency(currency)?; let mut keypairs = dup_crypto::dewif::read_dewif_file_content( ExpectedCurrency::Specific(currency), @@ -62,15 +57,11 @@ pub(super) fn change_pin( } pub(super) fn gen_dewif( - currency: *const raw::c_char, + currency: &str, language: u32, - mnemonic: *const raw::c_char, - pin: *const raw::c_char, + mnemonic: &str, + pin: &str, ) -> Result { - let currency = char_ptr_to_str(currency)?; - let mnemonic = char_ptr_to_str(mnemonic)?; - let pin = char_ptr_to_str(pin)?; - let currency = parse_currency(currency)?; let mnemonic = Mnemonic::from_phrase(mnemonic, u32_to_language(language)?) .map_err(|_| DubpError::WrongLanguage)?; @@ -81,15 +72,7 @@ pub(super) fn gen_dewif( )) } -pub(super) fn get_pubkey( - currency: *const raw::c_char, - dewif: *const raw::c_char, - pin: *const raw::c_char, -) -> Result { - let currency = char_ptr_to_str(currency)?; - let dewif = char_ptr_to_str(dewif)?; - let pin = char_ptr_to_str(pin)?; - +pub(super) fn get_pubkey(currency: &str, dewif: &str, pin: &str) -> Result { let currency = parse_currency(currency)?; let mut keypairs = dup_crypto::dewif::read_dewif_file_content( ExpectedCurrency::Specific(currency), @@ -104,17 +87,7 @@ pub(super) fn get_pubkey( } } -pub(super) fn sign( - currency: *const raw::c_char, - dewif: *const raw::c_char, - pin: *const raw::c_char, - msg: *const raw::c_char, -) -> Result { - let currency = char_ptr_to_str(currency)?; - let dewif = char_ptr_to_str(dewif)?; - let pin = char_ptr_to_str(pin)?; - let msg = char_ptr_to_str(msg)?; - +pub(super) fn sign(currency: &str, dewif: &str, pin: &str, msg: &str) -> Result { let currency = parse_currency(currency)?; let mut keypairs = dup_crypto::dewif::read_dewif_file_content( ExpectedCurrency::Specific(currency), @@ -130,22 +103,11 @@ pub(super) fn sign( } pub(super) fn sign_several( - currency: *const raw::c_char, - dewif: *const raw::c_char, - pin: *const raw::c_char, - msgs_len: usize, - msgs: *const *const raw::c_char, + currency: &str, + dewif: &str, + pin: &str, + msgs: &[&str], ) -> Result, DubpError> { - let currency = char_ptr_to_str(currency)?; - let dewif = char_ptr_to_str(dewif)?; - let pin = char_ptr_to_str(pin)?; - - let msgs_slice: &[*const raw::c_char] = unsafe { std::slice::from_raw_parts(msgs, msgs_len) }; - let mut msgs = Vec::with_capacity(msgs_len); - for ptr_c_char in msgs_slice { - msgs.push(char_ptr_to_str(*ptr_c_char)?); - } - let currency = parse_currency(currency)?; let mut keypairs = dup_crypto::dewif::read_dewif_file_content( ExpectedCurrency::Specific(currency), diff --git a/native/dubp_rs/src/error.rs b/native/dubp_rs/src/error.rs new file mode 100644 index 0000000..63bd5ec --- /dev/null +++ b/native/dubp_rs/src/error.rs @@ -0,0 +1,77 @@ +// Copyright (C) 2020 Éloïs SANCHEZ. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use crate::*; + +/// Dubp error +#[derive(Debug, Error)] +pub(crate) enum DubpError { + #[error("{0}")] + DewifReadError(DewifReadError), + #[error("I/O error: {0}")] + IoErr(io::Error), + #[error("A given parameter is null")] + NullParamErr, + #[error("fail to generate random bytes")] + RandErr, + #[error("Unknown currency name")] + UnknownCurrencyName, + #[error("Unknown language")] + UnknownLanguage, + #[error("{0}")] + Utf8Error(std::str::Utf8Error), + #[error("Wrong language")] + WrongLanguage, +} + +impl From for DubpError { + fn from(e: io::Error) -> Self { + Self::IoErr(e) + } +} + +pub(crate) struct DartRes(allo_isolate::ffi::DartCObject); +impl DartRes { + pub(crate) fn err(e: E) -> allo_isolate::ffi::DartCObject { + vec![format!("DUBP_RS_ERROR: {}", e.to_string())].into_dart() + } +} +impl IntoDart for DartRes { + fn into_dart(self) -> allo_isolate::ffi::DartCObject { + self.0.into_dart() + } +} +impl From> for DartRes +where + E: ToString, +{ + fn from(res: Result) -> Self { + match res { + Ok(string) => Self(string.into_dart()), + Err(e) => Self(format!("DUBP_RS_ERROR: {}", e.to_string()).into_dart()), + } + } +} +impl From, E>> for DartRes +where + E: ToString, +{ + fn from(res: Result, E>) -> Self { + match res { + Ok(vec_string) => Self(vec_string.into_dart()), + Err(e) => Self(vec![format!("DUBP_RS_ERROR: {}", e.to_string())].into_dart()), + } + } +} diff --git a/native/dubp_rs/src/lib.rs b/native/dubp_rs/src/lib.rs index 8d2f03a..2f29e58 100644 --- a/native/dubp_rs/src/lib.rs +++ b/native/dubp_rs/src/lib.rs @@ -15,9 +15,13 @@ #![allow(clippy::missing_safety_doc, clippy::not_unsafe_ptr_arg_deref)] +mod r#async; mod dewif; +mod error; mod mnemonic; +use crate::error::{DartRes, DubpError}; +use crate::r#async::exec_async; use allo_isolate::{IntoDart, Isolate}; use dup_crypto::{ bases::b58::ToBase58, @@ -28,65 +32,11 @@ use dup_crypto::{ }, mnemonic::{Language, Mnemonic, MnemonicType}, }; +use fast_threadpool::{ThreadPool, ThreadPoolConfig, ThreadPoolSyncHandler}; +use once_cell::sync::Lazy; use std::{ffi::CStr, io, os::raw}; use thiserror::Error; -/// Dubp error -#[derive(Debug, Error)] -pub enum DubpError { - #[error("{0}")] - DewifReadError(DewifReadError), - #[error("I/O error: {0}")] - IoErr(io::Error), - #[error("A given parameter is null")] - NullParamErr, - #[error("fail to generate random bytes")] - RandErr, - #[error("Unknown currency name")] - UnknownCurrencyName, - #[error("Unknown language")] - UnknownLanguage, - #[error("{0}")] - Utf8Error(std::str::Utf8Error), - #[error("Wrong language")] - WrongLanguage, -} - -impl From for DubpError { - fn from(e: io::Error) -> Self { - Self::IoErr(e) - } -} - -struct DartRes(allo_isolate::ffi::DartCObject); -impl IntoDart for DartRes { - fn into_dart(self) -> allo_isolate::ffi::DartCObject { - self.0.into_dart() - } -} -impl From> for DartRes -where - E: ToString, -{ - fn from(res: Result) -> Self { - match res { - Ok(string) => Self(vec![string].into_dart()), - Err(e) => Self(vec![String::from("_"), e.to_string()].into_dart()), - } - } -} -impl From, E>> for DartRes -where - E: ToString, -{ - fn from(res: Result, E>) -> Self { - match res { - Ok(vec_string) => Self(vec_string.into_dart()), - Err(e) => Self(vec![String::with_capacity(0), e.to_string()].into_dart()), - } - } -} - pub(crate) fn char_ptr_to_str<'a>(c_char_ptr: *const raw::c_char) -> Result<&'a str, DubpError> { if c_char_ptr.is_null() { Err(DubpError::NullParamErr) @@ -95,6 +45,28 @@ pub(crate) fn char_ptr_to_str<'a>(c_char_ptr: *const raw::c_char) -> Result<&'a } } +fn char_ptr_prt_to_vec_str<'a>( + char_ptr_ptr: *const *const raw::c_char, + len: u32, +) -> Result, DubpError> { + let len = len as usize; + let char_ptr_slice: &[*const raw::c_char] = + unsafe { std::slice::from_raw_parts(char_ptr_ptr, len) }; + let mut str_vec = Vec::with_capacity(len); + for char_ptr in char_ptr_slice { + str_vec.push(char_ptr_to_str(*char_ptr)?); + } + Ok(str_vec) +} + +fn u32_to_language(i: u32) -> Result { + match i { + 0 => Ok(Language::English), + 1 => Ok(Language::French), + _ => Err(DubpError::UnknownLanguage), + } +} + #[no_mangle] pub extern "C" fn change_dewif_pin( port: i64, @@ -103,9 +75,17 @@ pub extern "C" fn change_dewif_pin( old_pin: *const raw::c_char, new_pin: *const raw::c_char, ) { - Isolate::new(port).post(DartRes::from(dewif::change_pin( - currency, dewif, old_pin, new_pin, - ))); + exec_async( + port, + || { + let currency = char_ptr_to_str(currency)?; + let dewif = char_ptr_to_str(dewif)?; + let old_pin = char_ptr_to_str(old_pin)?; + let new_pin = char_ptr_to_str(new_pin)?; + Ok((currency, dewif, old_pin, new_pin)) + }, + |(currency, dewif, old_pin, new_pin)| dewif::change_pin(currency, dewif, old_pin, new_pin), + ) } #[no_mangle] @@ -116,9 +96,16 @@ pub extern "C" fn gen_dewif( mnemonic: *const raw::c_char, pin: *const raw::c_char, ) { - Isolate::new(port).post(DartRes::from(dewif::gen_dewif( - currency, language, mnemonic, pin, - ))); + exec_async( + port, + || { + let currency = char_ptr_to_str(currency)?; + let mnemonic = char_ptr_to_str(mnemonic)?; + let pin = char_ptr_to_str(pin)?; + Ok((currency, language, mnemonic, pin)) + }, + |(currency, language, mnemonic, pin)| dewif::gen_dewif(currency, language, mnemonic, pin), + ) } #[no_mangle] @@ -148,7 +135,16 @@ pub extern "C" fn get_dewif_pubkey( dewif: *const raw::c_char, pin: *const raw::c_char, ) { - Isolate::new(port).post(DartRes::from(dewif::get_pubkey(currency, dewif, pin))); + exec_async( + port, + || { + let currency = char_ptr_to_str(currency)?; + let dewif = char_ptr_to_str(dewif)?; + let pin = char_ptr_to_str(pin)?; + Ok((currency, dewif, pin)) + }, + |(currency, dewif, pin)| dewif::get_pubkey(currency, dewif, pin), + ) } #[no_mangle] @@ -157,10 +153,14 @@ pub extern "C" fn mnemonic_to_pubkey( language: u32, mnemonic_phrase: *const raw::c_char, ) { - Isolate::new(port).post(DartRes::from(mnemonic::mnemonic_to_pubkey( - language, - mnemonic_phrase, - ))); + exec_async( + port, + || { + let mnemonic_phrase = char_ptr_to_str(mnemonic_phrase)?; + Ok((language, mnemonic_phrase)) + }, + |(language, mnemonic_phrase)| mnemonic::mnemonic_to_pubkey(language, mnemonic_phrase), + ) } #[no_mangle] @@ -171,7 +171,17 @@ pub extern "C" fn sign( pin: *const raw::c_char, msg: *const raw::c_char, ) { - Isolate::new(port).post(DartRes::from(dewif::sign(currency, dewif, pin, msg))); + exec_async( + port, + || { + let currency = char_ptr_to_str(currency)?; + let dewif = char_ptr_to_str(dewif)?; + let pin = char_ptr_to_str(pin)?; + let msg = char_ptr_to_str(msg)?; + Ok((currency, dewif, pin, msg)) + }, + |(currency, dewif, pin, msg)| dewif::sign(currency, dewif, pin, msg), + ) } #[no_mangle] @@ -180,16 +190,18 @@ pub extern "C" fn sign_several( currency: *const raw::c_char, dewif: *const raw::c_char, pin: *const raw::c_char, - msgs_len: usize, + msgs_len: u32, msgs: *const *const raw::c_char, ) { - Isolate::new(port).post(dewif::sign_several(currency, dewif, pin, msgs_len, msgs)); -} - -fn u32_to_language(i: u32) -> Result { - match i { - 0 => Ok(Language::English), - 1 => Ok(Language::French), - _ => Err(DubpError::UnknownLanguage), - } + exec_async( + port, + || { + let currency = char_ptr_to_str(currency)?; + let dewif = char_ptr_to_str(dewif)?; + let pin = char_ptr_to_str(pin)?; + let msgs = char_ptr_prt_to_vec_str(msgs, msgs_len)?; + Ok((currency, dewif, pin, msgs)) + }, + |(currency, dewif, pin, msgs)| dewif::sign_several(currency, dewif, pin, &msgs), + ) } diff --git a/native/dubp_rs/src/mnemonic.rs b/native/dubp_rs/src/mnemonic.rs index ac17486..765427d 100644 --- a/native/dubp_rs/src/mnemonic.rs +++ b/native/dubp_rs/src/mnemonic.rs @@ -21,12 +21,7 @@ pub(super) fn gen_mnemonic(language: u32) -> Result { Ok(mnemonic.phrase().to_owned()) } -pub(super) fn mnemonic_to_pubkey( - language: u32, - mnemonic: *const raw::c_char, -) -> Result { - let mnemonic = char_ptr_to_str(mnemonic)?; - +pub(super) fn mnemonic_to_pubkey(language: u32, mnemonic: &str) -> Result { let mnemonic = Mnemonic::from_phrase(mnemonic, u32_to_language(language)?) .map_err(|_| DubpError::WrongLanguage)?; let seed = dup_crypto::mnemonic::mnemonic_to_seed(&mnemonic); diff --git a/packages/dubp_rs/lib/dubp.dart b/packages/dubp_rs/lib/dubp.dart index a3384e8..35b4e8a 100644 --- a/packages/dubp_rs/lib/dubp.dart +++ b/packages/dubp_rs/lib/dubp.dart @@ -55,7 +55,7 @@ class DubpRust { static Future genMnemonic({Language language = Language.english}) { final completer = Completer(); final sendPort = - singleCompletePort(completer, callback: _handleErr); + singleCompletePort(completer, callback: _handleErr); native.gen_mnemonic( sendPort.nativePort, language.index, @@ -66,7 +66,7 @@ class DubpRust { static Future _genPin(PinLength pinLength) { final completer = Completer(); final sendPort = - singleCompletePort(completer, callback: _handleErr); + singleCompletePort(completer, callback: _handleErr); switch (pinLength) { case PinLength.ten: native.gen_pin10( @@ -101,7 +101,7 @@ class DubpRust { { final completer = Completer(); final sendPort = - singleCompletePort(completer, callback: _handleErr); + singleCompletePort(completer, callback: _handleErr); native.change_dewif_pin( sendPort.nativePort, Utf8.toUtf8(currency), @@ -116,7 +116,7 @@ class DubpRust { { final completer = Completer(); final sendPort = - singleCompletePort(completer, callback: _handleErr); + singleCompletePort(completer, callback: _handleErr); native.get_dewif_pubkey( sendPort.nativePort, Utf8.toUtf8(currency), @@ -148,7 +148,7 @@ class DubpRust { { final completer = Completer(); final sendPort = - singleCompletePort(completer, callback: _handleErr); + singleCompletePort(completer, callback: _handleErr); native.mnemonic_to_pubkey( sendPort.nativePort, language.index, @@ -161,7 +161,7 @@ class DubpRust { { final completer = Completer(); final sendPort = - singleCompletePort(completer, callback: _handleErr); + singleCompletePort(completer, callback: _handleErr); native.gen_dewif( sendPort.nativePort, Utf8.toUtf8(currency), @@ -179,7 +179,7 @@ class DubpRust { {String currency = "g1", String dewif, String pin}) async { final completer = Completer(); final sendPort = - singleCompletePort(completer, callback: _handleErr); + singleCompletePort(completer, callback: _handleErr); native.get_dewif_pubkey( sendPort.nativePort, Utf8.toUtf8(currency), @@ -196,7 +196,7 @@ class DubpRust { {String currency = "g1", String dewif, String pin, String message}) { final completer = Completer(); final sendPort = - singleCompletePort(completer, callback: _handleErr); + singleCompletePort(completer, callback: _handleErr); native.sign( sendPort.nativePort, Utf8.toUtf8(currency), @@ -243,21 +243,20 @@ class DubpRust { return ptr; } - static String _handleErr(List res) { - final List arr = res.cast(); - if (arr.length == 1) { - return arr[0]; - } else { - final error = arr[1]; + static String _handleErr(String res) { + if (res.startsWith('DUBP_RS_ERROR: ')) { + final error = res; print(error); throw error; + } else { + return res; } } static List _handleErrList(List res) { final List arr = res.cast(); - if (arr.isNotEmpty && arr[0].isEmpty) { - final error = arr[1]; + if (arr.isNotEmpty && arr[0].startsWith('DUBP_RS_ERROR: ')) { + final error = arr[0]; print(error); throw error; } else { diff --git a/pubspec.lock b/pubspec.lock index 376b9d0..8446555 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,42 +21,42 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.3" + version: "2.5.0-nullsafety.1" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0-nullsafety.1" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.5" + version: "1.1.0-nullsafety.3" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0-nullsafety.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0-nullsafety.1" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.5" + version: "1.15.0-nullsafety.3" connectivity: dependency: transitive description: @@ -112,7 +112,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0-nullsafety.1" ffi: dependency: transitive description: @@ -282,27 +282,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.3" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.3-nullsafety.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.3" + version: "0.12.10-nullsafety.1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.6" + version: "1.3.0-nullsafety.3" nested: dependency: transitive description: @@ -330,7 +323,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.8.0-nullsafety.1" path_provider: dependency: "direct main" description: @@ -468,42 +461,42 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.4" + version: "1.8.0-nullsafety.2" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.6" + version: "1.10.0-nullsafety.1" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0-nullsafety.1" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0-nullsafety.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0-nullsafety.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.6" + version: "0.2.19-nullsafety.2" truncate: dependency: "direct main" description: @@ -517,7 +510,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.5" + version: "1.3.0-nullsafety.3" uuid: dependency: transitive description: @@ -538,7 +531,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.5" + version: "2.1.0-nullsafety.3" websocket: dependency: transitive description: @@ -575,5 +568,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=2.10.0-110 <2.11.0" flutter: ">=1.22.0 <2.0.0"