From 6d63e8a8115eef15acce8fa803c2e0dad7138de9 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 00:55:01 +1300 Subject: [PATCH 01/20] ignore vscode ide/settings --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index ea8c4bf..c764265 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ + +# IDE +.vscode + +# Output /target From 657cf8419aa707e1ddaad9e35a3a11699e3bf481 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 00:55:19 +1300 Subject: [PATCH 02/20] added rust toolchain --- rust-toolchain.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 rust-toolchain.toml diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..54d1b28 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +profile = "default" # include rustfmt, clippy +channel = "1.80.0" From 3fa1b27c3af6a8e9a9a7ce0e25caec5bad11f2d4 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 00:56:07 +1300 Subject: [PATCH 03/20] fix new_at_index not printing checksum address --- src/account.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/account.rs b/src/account.rs index 6a3d6a7..46b3f49 100644 --- a/src/account.rs +++ b/src/account.rs @@ -453,18 +453,15 @@ pub(crate) fn derive_account( Ok(derive_account_unlocked(wallet_path, account_ix, password)?.lock()) } -fn new_at_index( - keystore: &EthKeystore, - wallet_path: &Path, - account_ix: usize, -) -> Result { +fn new_at_index(keystore: &EthKeystore, wallet_path: &Path, account_ix: usize) -> Result { let prompt = format!("Please enter your wallet password to derive account {account_ix}: "); let password = rpassword::prompt_password(prompt)?; let account = derive_account(wallet_path, account_ix, &password)?; let account_addr = account.address(); cache_address(&keystore.crypto.ciphertext, account_ix, account_addr)?; - println!("Wallet address: {account_addr}"); - Ok(account_addr.clone()) + let checksum_addr = checksum_encode(&Address::from(account_addr).to_string())?; + println!("Wallet address: {checksum_addr}"); + Ok(checksum_addr) } pub fn new_at_index_cli(wallet_path: &Path, account_ix: usize) -> Result<()> { From 35e29d00c86b28672480c86c46c1ed7ed583000f Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 00:56:57 +1300 Subject: [PATCH 04/20] wallet existance also checks content; handles the case if it's not a file --- src/utils.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 562d825..2e25a03 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -142,13 +142,21 @@ pub(crate) fn ensure_no_wallet_exists( force: bool, mut reader: impl BufRead, ) -> Result<()> { - if wallet_path.exists() { + let remove_wallet = || { + if wallet_path.is_dir() { + fs::remove_dir_all(wallet_path).unwrap(); + } else { + fs::remove_file(wallet_path).unwrap(); + } + }; + + if wallet_path.exists() && fs::metadata(wallet_path)?.len() > 0 { if force { println_warning(&format!( "Because the `--force` argument was supplied, the wallet at {} will be removed.", wallet_path.display(), )); - fs::remove_file(wallet_path).unwrap(); + remove_wallet(); } else { println_warning(&format!( "There is an existing wallet at {}. \ @@ -158,7 +166,7 @@ pub(crate) fn ensure_no_wallet_exists( let mut need_replace = String::new(); reader.read_line(&mut need_replace).unwrap(); if need_replace.trim() == "y" { - fs::remove_file(wallet_path).unwrap(); + remove_wallet(); } else { bail!( "Failed to create a new wallet at {} \ From 9792e74e15636d0864dbfda93733d6dec71b1cb8 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 01:38:26 +1300 Subject: [PATCH 05/20] removed redundant helper functions; replaced with tempfile dep instead --- Cargo.lock | 1 + Cargo.toml | 3 +++ src/utils.rs | 32 ++++++-------------------------- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6521f42..1ec95b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -985,6 +985,7 @@ dependencies = [ "rand", "rpassword", "serde_json", + "tempfile", "termion", "tiny-bip39", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 8c5988d..f0d6f83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,3 +39,6 @@ path = "src/lib.rs" [[bin]] name = "forc-wallet" path = "src/main.rs" + +[dev-dependencies] +tempfile = "3.13.0" diff --git a/src/utils.rs b/src/utils.rs index 2e25a03..6ae2646 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -324,35 +324,15 @@ pub(crate) mod test_utils { pub(crate) const TEST_MNEMONIC: &str = "rapid mechanic escape victory bacon switch soda math embrace frozen novel document wait motor thrive ski addict ripple bid magnet horse merge brisk exile"; pub(crate) const TEST_PASSWORD: &str = "1234"; - /// Create a tmp folder and execute the given test function `f` - pub(crate) fn with_tmp_dir(f: F) - where - F: FnOnce(&Path) + panic::UnwindSafe, - { - let tmp_dir_name = format!("forc-wallet-test-{:x}", rand::random::()); - let tmp_dir = user_fuel_dir().join(".tmp").join(tmp_dir_name); - std::fs::create_dir_all(&tmp_dir).unwrap(); - let panic = panic::catch_unwind(|| f(&tmp_dir)); - std::fs::remove_dir_all(&tmp_dir).unwrap(); - if let Err(e) = panic { - panic::resume_unwind(e); - } - } - - /// Saves a default test mnemonic to the disk - pub(crate) fn save_dummy_wallet_file(wallet_path: &Path) { - write_wallet_from_mnemonic_and_password(wallet_path, TEST_MNEMONIC, TEST_PASSWORD).unwrap(); - } - - /// The same as `with_tmp_dir`, but also provides a test wallet. + /// Creates temp dir with a temp/test wallet. pub(crate) fn with_tmp_dir_and_wallet(f: F) where F: FnOnce(&Path, &Path) + panic::UnwindSafe, { - with_tmp_dir(|dir| { - let wallet_path = dir.join("wallet.json"); - save_dummy_wallet_file(&wallet_path); - f(dir, &wallet_path); - }) + let tmp_dir = tempfile::TempDir::new().unwrap(); + let wallet_path = tmp_dir.path().join("wallet.json"); + write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) + .unwrap(); + f(&tmp_dir.path(), &wallet_path); } } From 46bfbacf9498b83bd1059889ba8499318f421ec6 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 01:39:17 +1300 Subject: [PATCH 06/20] updated create_wallet test helper func to take optional file content --- src/utils.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 6ae2646..5dbdc22 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -182,7 +182,7 @@ pub(crate) fn ensure_no_wallet_exists( #[cfg(test)] mod tests { use super::*; - use crate::utils::test_utils::{with_tmp_dir, TEST_MNEMONIC, TEST_PASSWORD}; + use crate::utils::test_utils::{TEST_MNEMONIC, TEST_PASSWORD}; // simulate input const INPUT_NOP: &[u8; 1] = b"\n"; const INPUT_YES: &[u8; 2] = b"y\n"; @@ -193,10 +193,13 @@ mod tests { fs::remove_file(wallet_path).unwrap(); } } - fn create_wallet(wallet_path: &Path) { + fn create_wallet(wallet_path: &Path, content: Option<&str>) { if !wallet_path.exists() { fs::File::create(wallet_path).unwrap(); } + if let Some(content) = content { + fs::write(wallet_path, content).unwrap(); + } } #[test] From 11e0b503a9b1962fd2cb3a1630d304d057a48228 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 01:40:10 +1300 Subject: [PATCH 07/20] existing unit tests refactored to remove nesting --- src/utils.rs | 68 +++++++++++++++++++--------------------------------- 1 file changed, 24 insertions(+), 44 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 5dbdc22..8330a7a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -204,13 +204,12 @@ mod tests { #[test] fn handle_absolute_path_argument() { - with_tmp_dir(|tmp_dir| { - let tmp_dir_abs = tmp_dir.canonicalize().unwrap(); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let tmp_dir_abs = tmp_dir.path().canonicalize().unwrap(); let wallet_path = tmp_dir_abs.join("wallet.json"); write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) .unwrap(); load_wallet(&wallet_path).unwrap(); - }) } #[test] @@ -234,88 +233,69 @@ mod tests { } #[test] fn encrypt_and_save_phrase() { - with_tmp_dir(|tmp_dir| { - let wallet_path = tmp_dir.join("wallet.json"); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let wallet_path = tmp_dir.path().join("wallet.json"); write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) .unwrap(); let phrase_recovered = eth_keystore::decrypt_key(wallet_path, TEST_PASSWORD).unwrap(); let phrase = String::from_utf8(phrase_recovered).unwrap(); assert_eq!(phrase, TEST_MNEMONIC) - }); } #[test] fn write_wallet() { - with_tmp_dir(|tmp_dir| { - let wallet_path = tmp_dir.join("wallet.json"); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let wallet_path = tmp_dir.path().join("wallet.json"); write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) .unwrap(); load_wallet(&wallet_path).unwrap(); - }) } #[test] #[should_panic] fn write_wallet_to_existing_file_should_fail() { - with_tmp_dir(|tmp_dir| { - let wallet_path = tmp_dir.join("wallet.json"); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let wallet_path = tmp_dir.path().join("wallet.json"); write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) .unwrap(); write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) .unwrap(); - }) } #[test] fn write_wallet_subdir() { - with_tmp_dir(|tmp_dir| { - let wallet_path = tmp_dir.join("path").join("to").join("wallet"); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let wallet_path = tmp_dir.path().join("path").join("to").join("wallet.json"); write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) .unwrap(); load_wallet(&wallet_path).unwrap(); - }) } #[test] fn test_ensure_no_wallet_exists_no_wallet() { - with_tmp_dir(|tmp_dir| { - let wallet_path = tmp_dir.join("wallet.json"); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let wallet_path = tmp_dir.path().join("wallet.json"); remove_wallet(&wallet_path); ensure_no_wallet_exists(&wallet_path, false, &INPUT_NOP[..]).unwrap(); - }); - } - - #[test] - #[should_panic] - fn test_ensure_no_wallet_exists_throws_err() { - with_tmp_dir(|tmp_dir| { - let wallet_path = tmp_dir.join("wallet.json"); - create_wallet(&wallet_path); - ensure_no_wallet_exists(&wallet_path, false, &INPUT_NO[..]).unwrap(); - }); } #[test] fn test_ensure_no_wallet_exists_exists_wallet() { // case: wallet path exist without --force and input[yes] - with_tmp_dir(|tmp_dir| { - let wallet_path = tmp_dir.join("wallet.json"); - create_wallet(&wallet_path); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let wallet_path = tmp_dir.path().join("wallet.json"); + create_wallet(&wallet_path, None); ensure_no_wallet_exists(&wallet_path, false, &INPUT_YES[..]).unwrap(); - }); + // case: wallet path exist with --force - with_tmp_dir(|tmp_dir| { - let wallet_path = tmp_dir.join("wallet.json"); - create_wallet(&wallet_path); - ensure_no_wallet_exists(&wallet_path, true, &INPUT_NOP[..]).unwrap(); - }); - // case: wallet path exist without --force and supply a different wallet path - with_tmp_dir(|tmp_dir| { - let wallet_path = tmp_dir.join("wallet.json"); - create_wallet(&wallet_path); - let diff_wallet_path = tmp_dir.join("custom-wallet.json"); - ensure_no_wallet_exists(&diff_wallet_path, false, &INPUT_NOP[..]).unwrap(); - }); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let wallet_path = tmp_dir.path().join("empty_wallet.json"); + create_wallet(&wallet_path, None); + + // Empty file should not trigger the replacement prompt + ensure_no_wallet_exists(&wallet_path, false, &INPUT_YES[..]).unwrap(); + assert!(wallet_path.exists(), "Empty file should remain untouched"); + } } } From 8fadf3a86583711dab1e3b0f3db113cf7be0006d Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 01:40:54 +1300 Subject: [PATCH 08/20] new unit tests for ensure_no_wallet_exists --- src/utils.rs | 79 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 22 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 8330a7a..5432c7b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -206,10 +206,10 @@ mod tests { fn handle_absolute_path_argument() { let tmp_dir = tempfile::TempDir::new().unwrap(); let tmp_dir_abs = tmp_dir.path().canonicalize().unwrap(); - let wallet_path = tmp_dir_abs.join("wallet.json"); - write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) - .unwrap(); - load_wallet(&wallet_path).unwrap(); + let wallet_path = tmp_dir_abs.join("wallet.json"); + write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) + .unwrap(); + load_wallet(&wallet_path).unwrap(); } #[test] @@ -235,20 +235,20 @@ mod tests { fn encrypt_and_save_phrase() { let tmp_dir = tempfile::TempDir::new().unwrap(); let wallet_path = tmp_dir.path().join("wallet.json"); - write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) - .unwrap(); - let phrase_recovered = eth_keystore::decrypt_key(wallet_path, TEST_PASSWORD).unwrap(); - let phrase = String::from_utf8(phrase_recovered).unwrap(); - assert_eq!(phrase, TEST_MNEMONIC) + write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) + .unwrap(); + let phrase_recovered = eth_keystore::decrypt_key(wallet_path, TEST_PASSWORD).unwrap(); + let phrase = String::from_utf8(phrase_recovered).unwrap(); + assert_eq!(phrase, TEST_MNEMONIC) } #[test] fn write_wallet() { let tmp_dir = tempfile::TempDir::new().unwrap(); let wallet_path = tmp_dir.path().join("wallet.json"); - write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) - .unwrap(); - load_wallet(&wallet_path).unwrap(); + write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) + .unwrap(); + load_wallet(&wallet_path).unwrap(); } #[test] @@ -256,27 +256,27 @@ mod tests { fn write_wallet_to_existing_file_should_fail() { let tmp_dir = tempfile::TempDir::new().unwrap(); let wallet_path = tmp_dir.path().join("wallet.json"); - write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) - .unwrap(); - write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) - .unwrap(); + write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) + .unwrap(); + write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) + .unwrap(); } #[test] fn write_wallet_subdir() { let tmp_dir = tempfile::TempDir::new().unwrap(); let wallet_path = tmp_dir.path().join("path").join("to").join("wallet.json"); - write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) - .unwrap(); - load_wallet(&wallet_path).unwrap(); + write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) + .unwrap(); + load_wallet(&wallet_path).unwrap(); } #[test] fn test_ensure_no_wallet_exists_no_wallet() { let tmp_dir = tempfile::TempDir::new().unwrap(); let wallet_path = tmp_dir.path().join("wallet.json"); - remove_wallet(&wallet_path); - ensure_no_wallet_exists(&wallet_path, false, &INPUT_NOP[..]).unwrap(); + remove_wallet(&wallet_path); + ensure_no_wallet_exists(&wallet_path, false, &INPUT_NOP[..]).unwrap(); } #[test] @@ -285,7 +285,7 @@ mod tests { let tmp_dir = tempfile::TempDir::new().unwrap(); let wallet_path = tmp_dir.path().join("wallet.json"); create_wallet(&wallet_path, None); - ensure_no_wallet_exists(&wallet_path, false, &INPUT_YES[..]).unwrap(); + ensure_no_wallet_exists(&wallet_path, false, &INPUT_YES[..]).unwrap(); // case: wallet path exist with --force let tmp_dir = tempfile::TempDir::new().unwrap(); @@ -296,6 +296,41 @@ mod tests { ensure_no_wallet_exists(&wallet_path, false, &INPUT_YES[..]).unwrap(); assert!(wallet_path.exists(), "Empty file should remain untouched"); } + + #[test] + fn test_ensure_no_wallet_exists_nonempty_file() { + let tmp_dir = tempfile::TempDir::new().unwrap(); + let wallet_path = tmp_dir.path().join("nonempty_wallet.json"); + + // Create non-empty file + create_wallet(&wallet_path, Some("some wallet content")); + + // Test with --force flag + ensure_no_wallet_exists(&wallet_path, true, &INPUT_NO[..]).unwrap(); + assert!( + !wallet_path.exists(), + "File should be removed with --force flag" + ); + + // Test with user confirmation (yes) + create_wallet(&wallet_path, Some("some wallet content")); + ensure_no_wallet_exists(&wallet_path, false, &INPUT_YES[..]).unwrap(); + assert!( + !wallet_path.exists(), + "File should be removed after user confirmation" + ); + + // Test with user rejection (no) + create_wallet(&wallet_path, Some("some wallet content")); + let result = ensure_no_wallet_exists(&wallet_path, false, &INPUT_NO[..]); + assert!( + result.is_err(), + "Should error when user rejects file removal" + ); + assert!( + wallet_path.exists(), + "File should remain when user rejects removal" + ); } } From 9632374c8699cfad7606e81818ae5ac8a06d0573 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 01:48:44 +1300 Subject: [PATCH 09/20] updated CI toolchain to match rust-toolchain.toml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e6f58d2..7052f34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ env: CARGO_TERM_COLOR: always RUSTFLAGS: -D warnings REGISTRY: ghcr.io - RUST_VERSION_COV: nightly-2024-06-05 + RUST_VERSION_COV: stable-2024-07-21 jobs: cancel-previous-runs: From ab3e98d7ef275f216669809e3fc809abe42af1d0 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 01:58:43 +1300 Subject: [PATCH 10/20] github actions checkoutv4 and nodev4 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/markdown-lint.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7052f34..3f9a8d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: permissions: # Write access to push changes to pages contents: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install latest Rust uses: dtolnay/rust-toolchain@master with: @@ -39,7 +39,7 @@ jobs: uses: taiki-e/install-action@cargo-llvm-cov - name: Code coverage report - run: cargo +${{ env.RUST_VERSION_COV }} llvm-cov --all-features --lcov --branch --output-path lcov.info + run: cargo +${{ env.RUST_VERSION_COV }} llvm-cov --all-features --lcov --branch --output-path lcov.info - name: Setup LCOV uses: hrishikesh-kadam/setup-lcov@v1 diff --git a/.github/workflows/markdown-lint.yml b/.github/workflows/markdown-lint.yml index b4aa28e..1276bac 100644 --- a/.github/workflows/markdown-lint.yml +++ b/.github/workflows/markdown-lint.yml @@ -13,8 +13,8 @@ jobs: name: Markdown Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: 18 - run: | From 6e6af2ecf4f95334fc923635e71dc42171707090 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 02:00:11 +1300 Subject: [PATCH 11/20] ci update to use semver rust version --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f9a8d0..bbebd88 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ env: CARGO_TERM_COLOR: always RUSTFLAGS: -D warnings REGISTRY: ghcr.io - RUST_VERSION_COV: stable-2024-07-21 + RUST_VERSION: 1.80.0 jobs: cancel-previous-runs: @@ -33,13 +33,13 @@ jobs: - name: Install latest Rust uses: dtolnay/rust-toolchain@master with: - toolchain: ${{ env.RUST_VERSION_COV }} + toolchain: ${{ env.RUST_VERSION }} - name: Install cargo-llvm-codecov uses: taiki-e/install-action@cargo-llvm-cov - name: Code coverage report - run: cargo +${{ env.RUST_VERSION_COV }} llvm-cov --all-features --lcov --branch --output-path lcov.info + run: cargo +${{ env.RUST_VERSION }} llvm-cov --all-features --lcov --branch --output-path lcov.info - name: Setup LCOV uses: hrishikesh-kadam/setup-lcov@v1 From 8f9c6d09cb91bfdb247149d71f0c78df69276814 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 02:03:35 +1300 Subject: [PATCH 12/20] fixed CI nightly version for code cov --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbebd88..b795f6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,7 @@ env: RUSTFLAGS: -D warnings REGISTRY: ghcr.io RUST_VERSION: 1.80.0 + NIGHTLY_RUST_VERSION: nightly-2024-07-21 jobs: cancel-previous-runs: @@ -39,7 +40,7 @@ jobs: uses: taiki-e/install-action@cargo-llvm-cov - name: Code coverage report - run: cargo +${{ env.RUST_VERSION }} llvm-cov --all-features --lcov --branch --output-path lcov.info + run: cargo +${{ env.NIGHTLY_RUST_VERSION }} llvm-cov --all-features --lcov --branch --output-path lcov.info - name: Setup LCOV uses: hrishikesh-kadam/setup-lcov@v1 From eaf5301fb9fe01be62ff16182a0e3d41742da40e Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 02:10:35 +1300 Subject: [PATCH 13/20] reverting CI and toolchain to use original nightly version --- .github/workflows/ci.yml | 5 ++--- rust-toolchain.toml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b795f6f..a71783b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,7 @@ env: CARGO_TERM_COLOR: always RUSTFLAGS: -D warnings REGISTRY: ghcr.io - RUST_VERSION: 1.80.0 - NIGHTLY_RUST_VERSION: nightly-2024-07-21 + NIGHTLY_RUST_VERSION: nightly-2024-07-15 jobs: cancel-previous-runs: @@ -34,7 +33,7 @@ jobs: - name: Install latest Rust uses: dtolnay/rust-toolchain@master with: - toolchain: ${{ env.RUST_VERSION }} + toolchain: ${{ env.NIGHTLY_RUST_VERSION }} - name: Install cargo-llvm-codecov uses: taiki-e/install-action@cargo-llvm-cov diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 54d1b28..854f1c3 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] profile = "default" # include rustfmt, clippy -channel = "1.80.0" +channel = "nightly-2024-07-15" From 78511f81c7ab583d9d1876f4c6f17ea2595a0adc Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 02:15:53 +1300 Subject: [PATCH 14/20] fixed cargo clippy errors --- src/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.rs b/src/utils.rs index 5432c7b..2ee9d5e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -351,6 +351,6 @@ pub(crate) mod test_utils { let wallet_path = tmp_dir.path().join("wallet.json"); write_wallet_from_mnemonic_and_password(&wallet_path, TEST_MNEMONIC, TEST_PASSWORD) .unwrap(); - f(&tmp_dir.path(), &wallet_path); + f(tmp_dir.path(), &wallet_path); } } From 762405c5440eb03627cad5b99c258cdd21dfc422 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 10:42:32 +1300 Subject: [PATCH 15/20] Revert "reverting CI and toolchain to use original nightly version" This reverts commit eaf5301fb9fe01be62ff16182a0e3d41742da40e. --- .github/workflows/ci.yml | 5 +++-- rust-toolchain.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a71783b..b795f6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,8 @@ env: CARGO_TERM_COLOR: always RUSTFLAGS: -D warnings REGISTRY: ghcr.io - NIGHTLY_RUST_VERSION: nightly-2024-07-15 + RUST_VERSION: 1.80.0 + NIGHTLY_RUST_VERSION: nightly-2024-07-21 jobs: cancel-previous-runs: @@ -33,7 +34,7 @@ jobs: - name: Install latest Rust uses: dtolnay/rust-toolchain@master with: - toolchain: ${{ env.NIGHTLY_RUST_VERSION }} + toolchain: ${{ env.RUST_VERSION }} - name: Install cargo-llvm-codecov uses: taiki-e/install-action@cargo-llvm-cov diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 854f1c3..54d1b28 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] profile = "default" # include rustfmt, clippy -channel = "nightly-2024-07-15" +channel = "1.80.0" From 3ac5970040bfcc4ed1070595fb24868b530baa3e Mon Sep 17 00:00:00 2001 From: Kaya Gokalp Date: Tue, 29 Oct 2024 15:33:49 -0700 Subject: [PATCH 16/20] ci: install nightly version for code-cov --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b795f6f..0d120e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: - name: Install latest Rust uses: dtolnay/rust-toolchain@master with: - toolchain: ${{ env.RUST_VERSION }} + toolchain: ${{ env.NIGHTLY_RUST_VERSION }} - name: Install cargo-llvm-codecov uses: taiki-e/install-action@cargo-llvm-cov From 6b82bc411fae728da93b8f11d3ee393c26625eb3 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 11:52:59 +1300 Subject: [PATCH 17/20] updated rust toolchain to stable 1.82.0; nightly to nightly-2024-10-28 for coverage --- .github/workflows/ci.yml | 4 ++-- rust-toolchain.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d120e0..3e3ba2e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,8 @@ env: CARGO_TERM_COLOR: always RUSTFLAGS: -D warnings REGISTRY: ghcr.io - RUST_VERSION: 1.80.0 - NIGHTLY_RUST_VERSION: nightly-2024-07-21 + RUST_VERSION: 1.82.0 + NIGHTLY_RUST_VERSION: nightly-2024-10-28 jobs: cancel-previous-runs: diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 54d1b28..c69cff7 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] profile = "default" # include rustfmt, clippy -channel = "1.80.0" +channel = "1.82.0" From 0306d8382bb3adfa32acbcea368385601e23b00b Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 11:54:24 +1300 Subject: [PATCH 18/20] create_wallet added description --- src/utils.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/utils.rs b/src/utils.rs index 2ee9d5e..22b21ea 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -193,6 +193,9 @@ mod tests { fs::remove_file(wallet_path).unwrap(); } } + + /// Create a wallet file with optional wallet content. + /// Creates empty wallet file if content is None. fn create_wallet(wallet_path: &Path, content: Option<&str>) { if !wallet_path.exists() { fs::File::create(wallet_path).unwrap(); From f8124e8d4e100bcfdfd7a44d6af5d91bf318b68f Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 12:09:49 +1300 Subject: [PATCH 19/20] create_wallet updated param name; content -> data; updated description --- src/utils.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 22b21ea..b49bbf6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -194,14 +194,14 @@ mod tests { } } - /// Create a wallet file with optional wallet content. - /// Creates empty wallet file if content is None. - fn create_wallet(wallet_path: &Path, content: Option<&str>) { + /// Create a wallet file with optional wallet data; the data is written to the file if provided. + /// The data does not have to be a valid JSON. + fn create_wallet(wallet_path: &Path, data: Option<&str>) { if !wallet_path.exists() { fs::File::create(wallet_path).unwrap(); } - if let Some(content) = content { - fs::write(wallet_path, content).unwrap(); + if let Some(data) = data { + fs::write(wallet_path, data).unwrap(); } } From 9abc8adee156e34b1b1d2446d13da3c9a9f63203 Mon Sep 17 00:00:00 2001 From: zees-dev Date: Wed, 30 Oct 2024 12:54:43 +1300 Subject: [PATCH 20/20] create_wallet -> serialize_wallet_to_file; using an enum with variant for data persistence --- src/utils.rs | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index b49bbf6..f0f6e96 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -188,23 +188,33 @@ mod tests { const INPUT_YES: &[u8; 2] = b"y\n"; const INPUT_NO: &[u8; 2] = b"n\n"; - fn remove_wallet(wallet_path: &Path) { - if wallet_path.exists() { - fs::remove_file(wallet_path).unwrap(); - } + /// Represents the possible serialized states of a wallet. + /// Used primarily for simulating wallet creation and serialization processes. + enum WalletSerializedState { + Empty, + WithData(String), } - /// Create a wallet file with optional wallet data; the data is written to the file if provided. - /// The data does not have to be a valid JSON. - fn create_wallet(wallet_path: &Path, data: Option<&str>) { + /// Simulates the serialization of a wallet to a file, optionally including dummy data. + /// Primarily used to test if checks for wallet file existence are functioning correctly. + fn serialize_wallet_to_file(wallet_path: &Path, state: WalletSerializedState) { + // Create the wallet file if it does not exist. if !wallet_path.exists() { fs::File::create(wallet_path).unwrap(); } - if let Some(data) = data { + + // Write content to the wallet file based on the specified state. + if let WalletSerializedState::WithData(data) = state { fs::write(wallet_path, data).unwrap(); } } + fn remove_wallet(wallet_path: &Path) { + if wallet_path.exists() { + fs::remove_file(wallet_path).unwrap(); + } + } + #[test] fn handle_absolute_path_argument() { let tmp_dir = tempfile::TempDir::new().unwrap(); @@ -287,13 +297,13 @@ mod tests { // case: wallet path exist without --force and input[yes] let tmp_dir = tempfile::TempDir::new().unwrap(); let wallet_path = tmp_dir.path().join("wallet.json"); - create_wallet(&wallet_path, None); + serialize_wallet_to_file(&wallet_path, WalletSerializedState::Empty); ensure_no_wallet_exists(&wallet_path, false, &INPUT_YES[..]).unwrap(); // case: wallet path exist with --force let tmp_dir = tempfile::TempDir::new().unwrap(); let wallet_path = tmp_dir.path().join("empty_wallet.json"); - create_wallet(&wallet_path, None); + serialize_wallet_to_file(&wallet_path, WalletSerializedState::Empty); // Empty file should not trigger the replacement prompt ensure_no_wallet_exists(&wallet_path, false, &INPUT_YES[..]).unwrap(); @@ -306,7 +316,10 @@ mod tests { let wallet_path = tmp_dir.path().join("nonempty_wallet.json"); // Create non-empty file - create_wallet(&wallet_path, Some("some wallet content")); + serialize_wallet_to_file( + &wallet_path, + WalletSerializedState::WithData("some wallet content".to_string()), + ); // Test with --force flag ensure_no_wallet_exists(&wallet_path, true, &INPUT_NO[..]).unwrap(); @@ -316,7 +329,10 @@ mod tests { ); // Test with user confirmation (yes) - create_wallet(&wallet_path, Some("some wallet content")); + serialize_wallet_to_file( + &wallet_path, + WalletSerializedState::WithData("some wallet content".to_string()), + ); ensure_no_wallet_exists(&wallet_path, false, &INPUT_YES[..]).unwrap(); assert!( !wallet_path.exists(), @@ -324,7 +340,10 @@ mod tests { ); // Test with user rejection (no) - create_wallet(&wallet_path, Some("some wallet content")); + serialize_wallet_to_file( + &wallet_path, + WalletSerializedState::WithData("some wallet content".to_string()), + ); let result = ensure_no_wallet_exists(&wallet_path, false, &INPUT_NO[..]); assert!( result.is_err(),