Untitled diff

Created Diff never expires
89 removals
118 lines
33 additions
60 lines
pub enum WalletCommand {
pub enum WalletCommand {
Open(Config, // config
Open(Config, // config
Credentials, // credentials
Credentials, // credentials
Box<dyn Fn(IndyResult<WalletHandle>) + Send>),
Box<dyn Fn(IndyResult<WalletHandle>) + Send>),
OpenContinue(WalletHandle,
DeriveKeyResult<(MasterKey, Option<MasterKey>)>, // derive_key_result
),
DeriveKey(KeyDerivationData,
Box<dyn Fn(DeriveKeyResult<MasterKey>) + Send>),
}

macro_rules! get_cb {
($self_:ident, $e:expr) => (match $self_.pending_callbacks.borrow_mut().remove(&$e) {
Some(val) => val,
None => return error!("No pending command for id: {}", $e)
});
}
}


pub struct WalletCommandExecutor {
pub struct WalletCommandExecutor {
wallet_service: Rc<WalletService>,
wallet_service: Rc<WalletService>,
crypto_service: Rc<CryptoService>,
crypto_service: Rc<CryptoService>,
open_callbacks: RefCell<HashMap<WalletHandle, Box<dyn Fn(IndyResult<WalletHandle>) + Send>>>,
pending_callbacks: RefCell<HashMap<CallbackHandle, Box<dyn Fn(IndyResult<()>) + Send>>>
}
}


impl WalletCommandExecutor {
impl WalletCommandExecutor {
pub fn new(wallet_service: Rc<WalletService>, crypto_service: Rc<CryptoService>) -> WalletCommandExecutor {
pub fn new(wallet_service: Rc<WalletService>, crypto_service: Rc<CryptoService>) -> WalletCommandExecutor {
WalletCommandExecutor {
WalletCommandExecutor {
wallet_service,
wallet_service,
crypto_service,
crypto_service,
open_callbacks: RefCell::new(HashMap::new()),
pending_callbacks: RefCell::new(HashMap::new())
}
}
}
}


pub fn execute(&self, command: WalletCommand) {
pub async fn execute(&self, command: WalletCommand) {
match command {
match command {
WalletCommand::Open(config, credentials, cb) => {
WalletCommand::Open(config, credentials, cb) => {
debug!(target: "wallet_command_executor", "Open command received");
debug!(target: "wallet_command_executor", "Open command received");
self._open(&config, &credentials, cb);
cb(self._open(&config, &credentials).await);
}
WalletCommand::OpenContinue(wallet_handle, key_result) => {
debug!(target: "wallet_command_executor", "OpenContinue command received");
self._open_continue(wallet_handle, key_result)
}
WalletCommand::DeriveKey(key_data, cb) => {
debug!(target: "wallet_command_executor", "DeriveKey command received");
self._derive_key(key_data, cb);
}
}
};
};
}
}


fn _open(&self,
async fn _open<'a>(&'a self,
config: &Config,
config: &'a Config,
credentials: &Credentials,
credentials: &'a Credentials) -> IndyResult<WalletHandle> {
cb: Box<dyn Fn(IndyResult<WalletHandle>) + Send>) {
trace!("_open >>> config: {:?}, credentials: {:?}", config, secret!(credentials));
trace!("_open >>> config: {:?}, credentials: {:?}", config, secret!(credentials));


let (wallet_handle, key_derivation_data, rekey_data) = try_cb!(self.wallet_service.open_wallet_prepare(config, credentials), cb);
let (wallet_handle, key_derivation_data, rekey_data) = self.wallet_service.open_wallet_prepare(config, credentials)?;


self.open_callbacks.borrow_mut().insert(wallet_handle, cb);
let key = self._derive_key(key_derivation_data).await?;


CommandExecutor::instance().send(
let rekey = if let Some(rekey_data) = rekey_data {
Command::Wallet(WalletCommand::DeriveKey(
Some(self._derive_key(rekey_data).await?)
key_derivation_data,
} else {
Box::new(move |key_result| {
None
match (key_result, rekey_data.clone()) {
};
(Ok(key_result), Some(rekey_data)) => {
WalletCommandExecutor::_derive_rekey_and_continue(wallet_handle, key_result, rekey_data)
}
(key_result, _) => {
let key_result = key_result.map(|kr| (kr, None));
WalletCommandExecutor::_send_open_continue(wallet_handle, key_result)
}
}
}),
))
).unwrap();


let res = wallet_handle;
let res = self.wallet_service.open_wallet_continue(wallet_handle, (&key, rekey.as_ref()));


trace!("_open <<< res: {:?}", res);
trace!("_open <<< res: {:?}", res);
}


fn _derive_rekey_and_continue(wallet_handle: WalletHandle, key_result: MasterKey, rekey_data: KeyDerivationData) {
res
CommandExecutor::instance().send(
Command::Wallet(WalletCommand::DeriveKey(
rekey_data,
Box::new(move |rekey_result| {
let key_result = key_result.clone();
let key_result = rekey_result.map(move |rekey_result| (key_result, Some(rekey_result)));
WalletCommandExecutor::_send_open_continue(wallet_handle, key_result)
}),
))
).unwrap();
}
}


fn _send_open_continue(wallet_handle: WalletHandle, key_result: DeriveKeyResult<(MasterKey, Option<MasterKey>)>) {
async fn _derive_key(&self, key_data: KeyDerivationData) -> IndyResult<MasterKey> {
CommandExecutor::instance().send(
let (s, r) = futures::channel::oneshot::channel();
Command::Wallet(WalletCommand::OpenContinue(
crate::commands::THREADPOOL.lock().unwrap().execute(move || {
wallet_handle,
let res = key_data.calc_master_key();
key_result,
s.send(res).unwrap();
))
});
).unwrap();
r.await.unwrap()
}
}
}


fn _open_continue(&self,
wallet_handle: WalletHandle,
key_result: DeriveKeyResult<(MasterKey, Option<MasterKey>)>) {
let cb = self.open_callbacks.borrow_mut().remove(&wallet_handle).unwrap();
cb(key_result
.and_then(|(key, rekey)| self.wallet_service.open_wallet_continue(wallet_handle, (&key, rekey.as_ref()))))
}

fn _derive_key(&self, key_data: KeyDerivationData, cb: Box<dyn Fn(DeriveKeyResult<MasterKey>) + Send>){
::commands::THREADPOOL.lock().unwrap().execute(move || cb(key_data.calc_master_key()));
}
}