Skip to content

Commit

Permalink
Write to snapshot only once
Browse files Browse the repository at this point in the history
  • Loading branch information
Thoralf-M committed Aug 21, 2023
1 parent 3081901 commit 7305229
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 11 deletions.
13 changes: 13 additions & 0 deletions src/account_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,19 @@ impl AccountManager {
// revert to original storage_path
account.set_storage_path(self.storage_path.clone());
}
if crate::stronghold::PASSWORD_STORE
.get_or_init(crate::stronghold::default_password_store)
.lock()
.await
.get(&stronghold_storage_path)
.is_some()
{
let mut runtime = crate::stronghold::actor_runtime().lock().await;
runtime
.loaded_client_paths
.insert(crate::stronghold::records_client_path());
crate::stronghold::save_snapshot(&mut runtime, &stronghold_storage_path).await?;
}
self.storage_folder.join(STRONGHOLD_FILENAME)
};

Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ mod test_utils {
crate::signing::set_signer(signer_type.clone(), TestSigner::default()).await;
manager.store_mnemonic(signer_type, None).await.unwrap();

#[cfg(feature = "stronghold")]
iota_stronghold::engine::snapshot::try_set_encrypt_work_factor(0).unwrap();
#[cfg(feature = "stronghold")]
manager.set_stronghold_password("password").await.unwrap();

Expand Down Expand Up @@ -351,6 +353,8 @@ mod test_utils {

let manager = manager_builder.with_skip_polling().finish().await.unwrap();

#[cfg(feature = "stronghold")]
iota_stronghold::engine::snapshot::try_set_encrypt_work_factor(0).unwrap();
#[cfg(feature = "stronghold")]
manager.set_stronghold_password("password").await.unwrap();

Expand Down
25 changes: 14 additions & 11 deletions src/stronghold/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ use tokio::{
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};

#[derive(PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
struct Password(Zeroizing<Vec<u8>>);
pub(crate) struct Password(Zeroizing<Vec<u8>>);

type SnapshotToPasswordMap = HashMap<PathBuf, Arc<Password>>;
static PASSWORD_STORE: OnceCell<Arc<Mutex<SnapshotToPasswordMap>>> = OnceCell::new();
pub(crate) static PASSWORD_STORE: OnceCell<Arc<Mutex<SnapshotToPasswordMap>>> = OnceCell::new();
static STRONGHOLD_ACCESS_STORE: OnceCell<Arc<Mutex<HashMap<PathBuf, Instant>>>> = OnceCell::new();
static CURRENT_SNAPSHOT_PATH: OnceCell<Arc<Mutex<Option<PathBuf>>>> = OnceCell::new();
static PASSWORD_CLEAR_INTERVAL: OnceCell<Arc<Mutex<Duration>>> = OnceCell::new();
Expand All @@ -51,7 +51,7 @@ const SECRET_VAULT_PATH: &str = "iota-wallet-secret";
const SEED_RECORD_PATH: &str = "iota-wallet-seed";
const DERIVE_OUTPUT_RECORD_PATH: &str = "iota-wallet-derived";

fn records_client_path() -> Vec<u8> {
pub(crate) fn records_client_path() -> Vec<u8> {
b"iota-wallet-records".to_vec()
}

Expand Down Expand Up @@ -211,7 +211,7 @@ pub async fn get_status(snapshot_path: &Path) -> Status {
}
}

fn default_password_store() -> Arc<Mutex<HashMap<PathBuf, Arc<Password>>>> {
pub(crate) fn default_password_store() -> Arc<Mutex<HashMap<PathBuf, Arc<Password>>>> {
thread::spawn(|| {
crate::spawn(async {
loop {
Expand Down Expand Up @@ -330,7 +330,7 @@ pub type Result<T> = std::result::Result<T, Error>;
pub struct ActorRuntime {
pub stronghold: Stronghold,
spawned_client_paths: HashSet<Vec<u8>>,
loaded_client_paths: HashSet<Vec<u8>>,
pub(crate) loaded_client_paths: HashSet<Vec<u8>>,
}

pub fn actor_runtime() -> &'static Arc<Mutex<ActorRuntime>> {
Expand Down Expand Up @@ -406,7 +406,7 @@ async fn check_snapshot(
}

// saves the snapshot to the file system.
async fn save_snapshot(runtime: &mut ActorRuntime, snapshot_path: &Path) -> Result<()> {
pub(crate) async fn save_snapshot(runtime: &mut ActorRuntime, snapshot_path: &Path) -> Result<()> {
stronghold_response_to_result(
runtime
.stronghold
Expand Down Expand Up @@ -718,9 +718,6 @@ pub async fn store_record(snapshot_path: &Path, key: &str, record: String) -> Re
.write_to_store(Location::generic(key, key), record.as_bytes().to_vec(), None)
.await,
)?;

save_snapshot(&mut runtime, snapshot_path).await?;

Ok(())
}

Expand All @@ -730,8 +727,7 @@ pub async fn remove_record(snapshot_path: &Path, key: &str) -> Result<()> {

load_records_actor(&mut runtime, snapshot_path, None).await?;
stronghold_response_to_result(runtime.stronghold.delete_from_store(Location::generic(key, key)).await)?;

save_snapshot(&mut runtime, snapshot_path).await
Ok(())
}

#[cfg(test)]
Expand All @@ -744,6 +740,7 @@ mod tests {
rusty_fork_test! {
#[test]
fn password_expires() {
iota_stronghold::engine::snapshot::try_set_encrypt_work_factor(0).unwrap();
let runtime = tokio::runtime::Runtime::new().unwrap();
runtime.block_on(async {
let interval = 500;
Expand Down Expand Up @@ -772,6 +769,7 @@ mod tests {
rusty_fork_test! {
#[test]
fn action_keeps_password() {
iota_stronghold::engine::snapshot::try_set_encrypt_work_factor(0).unwrap();
let runtime = tokio::runtime::Runtime::new().unwrap();
runtime.block_on(async {
let interval = Duration::from_millis(3000);
Expand Down Expand Up @@ -827,6 +825,7 @@ mod tests {

#[tokio::test]
async fn write_and_read() -> super::Result<()> {
iota_stronghold::engine::snapshot::try_set_encrypt_work_factor(0).unwrap();
let snapshot_path: String = thread_rng()
.sample_iter(&Alphanumeric)
.map(char::from)
Expand All @@ -847,6 +846,7 @@ mod tests {

#[tokio::test]
async fn write_and_delete() -> super::Result<()> {
iota_stronghold::engine::snapshot::try_set_encrypt_work_factor(0).unwrap();
let snapshot_path: String = thread_rng()
.sample_iter(&Alphanumeric)
.map(char::from)
Expand All @@ -866,6 +866,7 @@ mod tests {

#[tokio::test]
async fn write_and_read_multiple_snapshots() {
iota_stronghold::engine::snapshot::try_set_encrypt_work_factor(0).unwrap();
let mut snapshot_saves = vec![];

for i in 1..3 {
Expand Down Expand Up @@ -902,6 +903,7 @@ mod tests {

#[tokio::test]
async fn change_password() -> super::Result<()> {
iota_stronghold::engine::snapshot::try_set_encrypt_work_factor(0).unwrap();
let snapshot_path: String = thread_rng()
.sample_iter(&Alphanumeric)
.map(char::from)
Expand All @@ -925,6 +927,7 @@ mod tests {

#[tokio::test]
async fn change_password_invalid() -> super::Result<()> {
iota_stronghold::engine::snapshot::try_set_encrypt_work_factor(0).unwrap();
let snapshot_path: String = thread_rng()
.sample_iter(&Alphanumeric)
.map(char::from)
Expand Down

0 comments on commit 7305229

Please sign in to comment.