ci: merge backend-e2e workflow into tests workflow#727
Conversation
Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>
|
@claude we need to add another step that will run cleanup_test_wallets(). Do required changes in the rust code. I guess it will be enough to add some noop test and run only this one test, as the test setup should do the cleanup as first step, but check this. |
|
Claude finished @lklimek's task in 10m 21s —— View job Completed: added cleanup_only noop test
What was doneConfirmed that Created Run with: cargo test --test backend-e2e --all-features -- --ignored --nocapture cleanup_onlyCI workflow step (manual action needed)I cannot modify - name: Cleanup E2E test wallets
if: always() && secrets.E2E_WALLET_MNEMONIC != ''
run: cargo test --test backend-e2e --all-features -- --ignored --nocapture cleanup_only
env:
E2E_WALLET_MNEMONIC: ${{ secrets.E2E_WALLET_MNEMONIC }}Note the |
Add a standalone test that triggers BackendTestContext initialization, which runs cleanup_test_wallets() as its final step. This can be run as a dedicated CI step after the E2E suite to sweep orphaned wallet funds back to the framework wallet. Run with: cargo test --test backend-e2e --all-features -- --ignored --nocapture cleanup_only Co-authored-by: lklimek <lklimek@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added a cleanup step for E2E test wallets in the workflow.
Removed conditional checks for E2E_WALLET_MNEMONIC in test steps.
* docs: add unified message display design documents Add UX specification, technical architecture, and HTML mockup for the MessageBanner component that will replace the ~50 ad-hoc error/message display implementations across screens with a single reusable component. Key design decisions: - Per-screen MessageBanner with show()/set_message() API - All colors via DashColors (zero hardcoded Color32 values) - 4 severity levels: Error, Warning, Success, Info - Auto-dismiss for Success/Info (5s), persistent for Error/Warning - Follows Component Design Pattern conventions (private fields, builder, show) - No changes to BackendTask/TaskResult/AppState architecture Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add MessageType::Warning * chore: initial implementation * chore: docs * chore: self review * refactor(context): replace RwLock<Sdk> with ArcSwap<Sdk> (#600) * refactor(context): replace RwLock<Sdk> with ArcSwap<Sdk> Sdk is internally thread-safe (Arc, ArcSwapOption, atomics) and all methods take &self. The RwLock was adding unnecessary contention across backend tasks. Using ArcSwap instead of plain Sdk because reinit_core_client_and_sdk() needs to atomically swap the entire Sdk instance when config changes. ArcSwap provides lock-free reads with atomic swap for the rare write. Suggested-by: lklimek * fix: address CodeRabbit review findings for ArcSwap migration - Fix import ordering: move arc_swap::ArcSwap before crossbeam_channel - Remove redundant SDK loads in load_identity_from_wallet, register_dpns_name, and load_identity — use the sdk parameter already passed to these functions - Fix stale TODO referencing removed sdk.read().unwrap() API - Rename sdk_guard → sdk in transfer, withdraw_from_identity, and refresh_loaded_identities_dpns_names (no longer lock guards) - Pass &sdk to run_platform_info_task from dispatch site instead of reloading internally - Fix leftover sdk.write() call in context_provider.rs (RwLock remnant) - Add missing Color32 import in wallets dialogs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: address remaining CodeRabbit review feedback on ArcSwap migration - Move SDK load outside for loop in refresh_loaded_identities_dpns_names.rs so it's loaded once for the batch instead of on each iteration - Update stale TODO comment in default_platform_version() to reflect that this is a free function with no sdk access Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: consolidate double read-lock on spv_context_provider Clone the SPV provider in a single lock acquisition, then bind app context on the clone instead of locking twice. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * refactor: remove unused Insight API and show_in_ui config fields (#597) * refactor: remove unused Insight API references The `insight_api_url` field in `NetworkConfig` and its associated `insight_api_uri()` method were never used in production code (both marked `#[allow(dead_code)]`). Remove the field, method, config entries, env example lines, and related tests. https://claude.ai/code/session_01HWPmCJHT8KTZGP9bFiksjn * refactor: remove unused `show_in_ui` field from NetworkConfig The `show_in_ui` field was defined on `NetworkConfig` and serialized in `save()`, but never read by any production code to control network visibility. Remove the field, its serialization, env example lines, and test references. https://claude.ai/code/session_01HWPmCJHT8KTZGP9bFiksjn * fix: add missing `Color32` import in wallet dialogs https://claude.ai/code/session_01HWPmCJHT8KTZGP9bFiksjn --------- Co-authored-by: Claude <noreply@anthropic.com> * build: add Flatpak packaging and CI workflow (#589) * build: remove snap version * build: add Flatpak packaging and CI workflow Add Flatpak build manifest, desktop entry, AppStream metadata, and GitHub Actions workflow for building and distributing Flatpak bundles. Uses freedesktop 25.08 runtime with rust-stable and llvm21 extensions. No application source code changes required - works in SPV mode by default. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * build: address review findings for Flatpak packaging - Pin GitHub Actions to commit SHAs for supply chain security - Upgrade softprops/action-gh-release from v1 to v2.2.2 - Remove redundant --socket=x11 (fallback-x11 suffices) - Remove duplicate tag trigger preventing double builds on release - Remove duplicate env vars inherited from top-level build-options - Add Flatpak build artifacts to .gitignore - Add bugtracker URL to AppStream metainfo - Remove deprecated <categories> from metainfo (use .desktop instead) - Add Terminal=false and Keywords to desktop entry - Add disk space check after SDK install in CI - Rename artifact to include architecture suffix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * build: simplify CI workflows for Linux-only releases - Remove "Free disk space" step from flatpak and release workflows - Remove Windows and macOS builds from release workflow - Use "ubuntu" runner image instead of pinned versions - Clean up unused matrix.ext references Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * build: attach to existing releases instead of creating new ones - Replace release-creating job with attach-to-release (only on release event) - Add 14-day retention for build artifacts - On tag push or workflow_dispatch, only upload artifacts (no release) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * revert: restore release.yml to original v1.0-dev version The release workflow changes were out of scope for the Flatpak PR. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address CodeRabbit review comments - Fix CRLF line endings in Flatpak manifest (convert to LF) - Set app_id on ViewportBuilder to match desktop StartupWMClass - Use --locked flag for reproducible cargo builds in Flatpak - Rename --repo=repo to --repo=flatpak-repo to match .gitignore - Add architecture note for protoc x86_64 binary Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add Flatpak install instructions to README Add a dedicated section for installing via Flatpak on Linux, clarify that prerequisites are only needed for building from source, and rename "Installation" to "Build from Source" for clarity. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: match StartupWMClass to Flatpak app_id Use reverse-DNS format org.dash.DashEvoTool to match the Wayland app_id set via ViewportBuilder::with_app_id(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use ** glob for branch trigger to match feat/flatpak Single * doesn't match path separators in GitHub Actions branch filters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add aarch64 Flatpak build and caching to CI - Add matrix strategy for parallel x86_64 and aarch64 builds - Patch protoc URL/sha256 per architecture at build time - Cache .flatpak-builder directory keyed on arch + manifest + lockfile - Pin actions/cache to SHA Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: convert desktop and metainfo files to LF line endings Flatpak builder validates desktop files and rejects CRLF line endings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * build: cancel in-progress Flatpak builds on new push Add concurrency group keyed on git ref so a new push cancels any running build for the same branch or release. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address PR review findings for Flatpak packaging - Remove unnecessary --filesystem=xdg-config/dash-evo-tool:create (Flatpak already redirects XDG_CONFIG_HOME to sandbox) - Add categories and keywords to AppStream metainfo for discoverability - Update README with both x86_64/aarch64 install commands, uninstall instructions, and Flatpak data path note - Clarify aarch64 comment in manifest to reference CI sed patching Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: workflow timeout and perms * fix: move permissions to job level in Flatpak workflow Step-level permissions are not valid in GitHub Actions. Move contents: write to the job level where it is needed for release attachment. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * build: cache Cargo registry and target in Flatpak CI Bind-mount host-side cargo-cache and cargo-target directories into the Flatpak build sandbox so CARGO_HOME and target/ persist across builds. Uses split restore/save with cleanup of incremental and registry/src (similar to Swatinem/rust-cache). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: scope cargo cache bind-mount sed to build-args only The previous sed matched --share=network in both finish-args and build-args, corrupting finish-args. Use a sed range to only target the build-args section. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply suggestions from code review --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * chore: fix build * chore: use new error handling everywhere - not self reviewed * chore: use message banner to show progress * fix: start elapsed counter at 1s instead of 0s Aligns elapsed display with the countdown timer which already adds 1 to avoid showing "0s" immediately. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: rabbit review * Update src/app.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * chore: peer review * chore: fix build errors * fix(ui): make MessageBanner::set_global truly idempotent set_global() no longer resets timestamps, auto-dismiss timer, or logged flag when a banner with identical text already exists. This makes it safe to call every frame without log spam or timer restarts. Cherry-picked from origin/fix/spv-peer-timeout (08e3b3b). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): address code review findings R01, R03, R06, R09, R10 - R01: Replace expect("No key selected") with graceful match + error banner in 11 token screens to prevent panics on missing signing key - R03: Remove dead backend_message field from AddExistingIdentityScreen - R06: Replace is_some() + unwrap() with idiomatic if-let-Some pattern in 10 token screens; use is_some_and() in structs.rs - R09: Add use imports for MessageBanner in 5 dashpay screens, replacing 22 fully-qualified crate::ui::components::MessageBanner:: calls - R10: Replace custom_dash_qt_error_message inline rendering with MessageBanner::set_global in network_chooser_screen Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): address review findings SEC-08, SEC-09, RUST-015, SEC-05, SEC-07 - SEC-08: Restore safe if-let-Some pattern in WithdrawalScreen::refresh() to prevent double unwrap() panic on DB error or deleted identity - SEC-09: Restore original DB lookup in SendPaymentScreen::load_contact_info() replacing hardcoded "alice.dash" mock data - RUST-015: Revert unimplemented!() back to ui.label() in update_token_config MarketplaceTradeMode arm - SEC-05: Add success banners for contact request accept/reject in ContactRequests::display_task_result - SEC-07: Add MessageBanner::clear_all_global() and call it from AppState::change_network() to prevent stale banners leaking across network switches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: update coding conventions and message display guidance Add fallible constructor rule (Result<Self, ...> when they can fail), rename section to "General rules", and document MessageBanner idempotency (no guard needed for set_global). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): replace expect/panic with graceful error handling (SEC-10) Replace all expect() calls in token screen constructors and confirmation handlers with MessageBanner error display. Constructors handle errors internally and return Self with degraded state, keeping create_screen() clean. refresh() methods now show errors via MessageBanner instead of tracing-only logging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(ui): accept impl Display/Debug in MessageBanner API Change MessageBanner public methods to accept `impl Display` for message text and `impl Debug` for details, instead of `&str`. Remove needless `&format!(...)` borrows across 27 call sites. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): remove error Failed to get best chain lock for mainnet, testnet, devnet, and local Fixes #633 * feat(ui): add automatic connection status banners Display persistent MessageBanner notifications based on network connection state transitions. Mode-aware messages guide users toward the right recovery action (RPC vs SPV). - Disconnected (RPC): "Disconnected — check that Dash Core is running" - Disconnected (SPV): "Disconnected — check your internet connection" - Syncing (RPC): "Syncing with Dash Core…" - Syncing (SPV): "SPV sync in progress…" - Synced: banner cleared Uses Option<OverallConnectionState> for change detection, with None as initial/post-network-switch sentinel to force first evaluation. Closes #667 (partial — action links deferred to follow-up) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): pass TaskError directly to with_details() to avoid double-formatting The previous code used `format!("{err:?}")` which produced a String, then `with_details()` applied `{:#?}` again — wrapping the output in quotes and escaping inner characters. Passing `&err` directly lets Debug format once. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): correct copy-paste error messages in token screens Replace "Burning" error messages that were copy-pasted from burn screen into freeze, destroy, and resume token screens with contextually correct messages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): restore lost success/error messages in 5 screens Replace display_message() calls with MessageBanner::set_global() in screens where display_message() is now a side-effect-only handler and no longer displays messages directly. Affected screens: create_asset_lock_screen, wallets_screen (MineBlocks), address_table (export error), profile_screen (validation), contact_details. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): replace unwrap/expect with graceful error handling Replace double unwrap in transfer_screen refresh() with unwrap_or_else + MessageBanner error display, matching the pattern from withdraw_screen. SEC-002 tokens_screen skipped: the .expect() calls are only on compile-time embedded image data (include_bytes!) which is safe. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(ui): migrate masternode_list_diff_screen to global MessageBanner Replace ~15 local ui_state.message assignments and custom render_message_banner() with MessageBanner::set_global() via the display_message() trait method. Remove the message field from UiState and the unused Color32 import. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): improve banner eviction logging and atomics - Upgrade BANNER_KEY_COUNTER from Relaxed to SeqCst ordering for future-proofing against multi-threaded usage - Log evicted banners at warn level in set_global() and replace_global() - Add comment explaining why show_global() always writes back Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: remove resolved TODO.md All items tracked in the unified message display TODO have been addressed or moved to the review findings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs(ui): add INTENTIONAL markers and API documentation - Document why with_details() accepts Debug (not Display): structured error context is more useful in diagnostic details panes - Document replace_global() fallback-to-add behavior as intentional - Add INTENTIONAL(SEC-003) marker for developer mode error details - Add INTENTIONAL(SEC-004) marker for BannerHandle Send+Sync safety Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(ui): extract shared token validation and fix ordering - Add validate_signing_key() helper in tokens/mod.rs to eliminate duplicated signing key validation across 12 token screens - Move signing key validation BEFORE WaitingForResult state transition so users see immediate errors instead of loading spinner then error - Replace is_err()/unwrap() anti-pattern with idiomatic let-else blocks in freeze, mint, transfer, destroy_frozen_funds, unfreeze screens Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(ui): return Result from get_selected_wallet Replace &mut Option<String> error out-parameter with idiomatic Result<Option<Arc<RwLock<Wallet>>>, String>. Update 26+ callsites across identity, token, DashPay, and contract screens. Callsite patterns: unwrap_or_else with MessageBanner for user-visible errors, unwrap_or(None) where errors were previously silently ignored. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): resolve duplicate imports and clippy warnings Remove duplicate MessageBanner imports in create_asset_lock_screen and wallets_screen/mod. Fix needless_borrows_for_generic_args clippy lints in profile_screen, transfer_screen, and wallets_screen. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: reorder imports in masternode_list_diff_screen Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): address review findings from MessageBanner migration audit Apply 13 triaged review fixes plus 1 bug fix across 22 files: - Remove dead error state fields (backend_message, error_message, Error variant) - Replace .expect() panics with graceful fallback + MessageBanner in token screens - Fix missing MessageBanner::show_global() on contracts documents screen - Migrate DocumentActionScreen inline errors to MessageBanner - Replace unwrap_or(None) with error-reporting fallback in DashPay screens - Fix replace_global idempotency and use relaxed atomic ordering in banner - Extract shared set_error_banner helper for 8 token screens - Restore correct Some(0) wallet index semantics - Document BannerHandle lifecycle in CLAUDE.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: validate token description length before sending to Platform (#530) * fix: validate token description length before sending to Platform Descriptions must be either empty or 3-100 characters long. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): validate token description by char count, not byte length String::len() counts UTF-8 bytes, causing multi-byte characters (CJK, emoji) to be miscounted against the 3–100 limit. Switch to chars().count() and update all UI labels to surface the minimum. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Lukasz Klimek <842586+lklimek@users.noreply.github.com> * refactor(ui): consolidate banner extension traits into message_banner Move BannerHandleExt and ResultBannerExt from banner_ext.rs into message_banner.rs where they belong. Merge take_and_clear() into OptionBannerExt trait (impl for Option<BannerHandle>) alongside or_show_error() for Option. Remove the separate banner_ext module and Clearable helper trait for simplicity. Apply review findings: DRY patterns (take_and_clear, or_show_error, load_identities_with_banner), fix .expect() panics in constructors, restore known_identities in refresh(), narrow pub field visibility, add ScreenLike doc comments, and update CLAUDE.md conventions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * doc(tmp): review guide for pr 604 * fix(ui): address review findings from grumpy-review iteration 1 - Replace .expect() panics in TransferTokensScreen and ClaimTokensScreen constructors with graceful degradation via Option<QualifiedIdentity> and MessageBanner error display (PROJ-001 HIGH) - Fix CLAUDE.md referencing non-existent BannerHandleExt trait name, corrected to OptionBannerExt (PROJ-002 MEDIUM) - Update set_global to preserve message_type when same text appears with different severity (RUST-001 MEDIUM) - Standardize display_message to handle both Error and Warning across all 11 token screens (RUST-002 MEDIUM) - Replace 21 manual take().clear() patterns with take_and_clear() across 6 files (RUST-003 MEDIUM) - Remove unused OptionBannerExt::or_show_error method (RUST-004 MEDIUM) - Migrate update_token_config from old error_message pattern to set_error_banner closure (RUST-005 MEDIUM) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * perf(ui): replace per-frame QualifiedIdentity clone with borrow Use .as_ref() instead of .clone() in the ui() identity guard of TransferTokensScreen and ClaimTokensScreen. QualifiedIdentity (Identity + KeyStorage + BTreeMap + Vec) was being cloned 60x/sec; now only borrowed for display, with clones deferred to button-click paths that actually need ownership. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(ui): add OptionResultExt::or_show_error for Option<T> Mirrors ResultBannerExt::or_show_error but for Option<T>: if None, displays a global error banner with the given message. Enables concise patterns like: identities.first().cloned().or_show_error(ctx, "No identities loaded") Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): address review findings from grumpy-review iteration 2 - Standardize display_message to handle both Error and Warning across 13 non-token screens that were missed in iteration 1 (PROJ-001 MEDIUM) - Replace .expect() panic in AddKeyScreen::refresh() with graceful or_show_error() + unwrap_or_default() (PROJ-002 MEDIUM) - Rename OptionResultExt to OptionBannerShowExt to avoid confusion with ResultBannerExt (RUST-001 MEDIUM) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): handle Warning in add_new_identity_screen display_message Missed in the previous sweep — standardize display_message to handle both Error and Warning, matching all other screens. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): standardize display_message side-effect patterns across screens Guard side effects with Error|Warning match, use take_and_clear(), and remove redundant MessageBanner::set_global() call in 4 screens. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(deps): update dashpay/platform to rev 570e3af0 Adapt to breaking changes in rust-dashcore (a05d256f → 2824e52a): - Replace removed FeeLevel enum with FeeRate::normal() direct calls - Replace removed WalletManager::create_unsigned_payment_transaction() with TransactionBuilder + WalletManager::get_change_address() - Replace removed DashSpvClientInterface/DashSpvClientCommand with direct Arc<SpvClient> for quorum lookups via get_quorum_at_height() - Replace removed start()+monitor_network() with client.run(token) - Add .await to now-async subscribe_sync/network/progress methods - Replace removed SyncState::Initializing with SyncState::WaitForEvents Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: log backtrace on panic * fix: panic in asset locks * fix(ui): address PR #604 review comments (CMT-001, CMT-002, CMT-003) - Fix QR scanner form reset matching wrong result type (CMT-001) - Remove dangerous identity fallback in token transfer screen (CMT-002) - Add fee-aware validation before credit transfers (CMT-003) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(spv): replace AsyncRwLock with ArcSwapOption for SPV client reference The SPV client reference only needs atomic set/clear (on start/stop) and wait-free reads (quorum lookups). ArcSwapOption is a better fit than AsyncRwLock<Option<Arc<...>>> — no lock contention, no async in blocking context, and consistent with how AppContext already uses ArcSwap for the SDK. Also fixes stale doc comment referencing removed DashSpvClientInterface. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ui): address PR #604 review comments iteration 2 (transfer_tokens_screen) - Remove duplicate conflicting banner on missing identity (CMT-003) - Use generic banner messages with with_details() for errors (CMT-002) - Fix refresh to match specific token by contract+position (CMT-001) - Document error banner pattern in CLAUDE.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * [claudesquad] update from 'testing research' on 02 Mar 26 13:25 CET (paused) * test: add backend E2E test harness and SPV wallet test Add test-only accessors (db(), wallets()) on AppContext gated behind cfg(test/testing), fix compilation errors in the backend-e2e test (private field access, unused import), and apply nightly rustfmt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add DASH_EVO_DATA_DIR env var to override app data directory Allows tests and CI to redirect all app data (database, SPV chain state, .env config) to a temp directory. The backend-e2e test harness now uses this to achieve full data isolation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add backend E2E test framework with shared state and funded wallets Evolve the prototype backend E2E test harness into a reusable framework: - LazyLock shared BackendTestContext with persistent workdir, SPV, and framework wallet (funded via E2E_WALLET_MNEMONIC or testnet faucet) - Task runner wrapper, polling wait helpers, faucet HTTP client - Identity key derivation helpers for wallet-funded registration - Six test scenarios: SPV wallet, identity create, identity withdraw, send/receive funds, fetch contracts, register DPNS name - Move default_identity_key_specs() from UI to backend_task::identity (domain logic, not UI concern) and make IdentityKeys fields pub - Add dashpay_contract_id() test accessor to AppContext Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(test): use tokio::sync::OnceCell instead of LazyLock for async init LazyLock triggers synchronously inside the #[tokio::test] runtime, causing "Cannot start a runtime from within a runtime" when the init function calls block_on(). Switch to tokio::sync::OnceCell with an async init() method so shared state initialization runs cooperatively within the existing tokio runtime. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(test): handle persistent DB and SPV balance sync in E2E harness - Wait for SPV to sync existing wallet balance before checking if faucet funding is needed (pre-funded wallets need time to discover on-chain UTXOs) - Handle "already imported" error gracefully when framework wallet exists in persistent DB from a previous run Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(test): wait for spendable balance and retry sends in E2E harness The SPV wallet reports total balance (including unconfirmed) but only confirmed/IS-locked UTXOs are available for transaction building. This caused "Insufficient funds" errors when tests tried to spend immediately after receiving funds. - Add wait_for_spendable_balance() that checks confirmed_balance_duffs() and triggers reconcile_spv_wallets() on each poll iteration - Add retry logic (5 attempts, 10s backoff) to create_funded_test_wallet() for sends that fail with InsufficientFunds - Wait for framework wallet change output to become spendable after each send so subsequent calls don't fail - Add wait_for_spendable_balance() before identity registration in all identity/DPNS tests - Add send_with_retry() helper in send_funds test - Add developer-facing README.md for the test framework Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(test): use tokio-shared-rt for shared runtime and sweep orphaned wallets Replace per-test tokio runtimes with tokio-shared-rt's global shared runtime to prevent SPV background tasks from dying between test functions. Add automatic orphaned wallet fund recovery during setup — wallets persist in DB, so on next run the harness sweeps funds back to the framework wallet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: handle OverallConnectionState::Error in connection banner Semantic merge conflict from v1.0-dev: PR #650 added an Error variant to OverallConnectionState, which our connection banner match didn't cover. Show an error banner when SPV sync enters the error state. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs(test): improve backend-e2e documentation and funding UX - Add backend E2E section to CLAUDE.md pointing to the full README - Document .env file handling (project root vs workdir) and precedence - Fix test attribute in README: tokio::test → tokio_shared_rt::test(shared) - Update init sequence to reflect current code (spendable wait, orphan sweep) - Document automatic cleanup-on-init of orphaned test wallets - Raise minimum balance threshold from 1 to 10 tDASH - Always panic with receive address when faucet fails and balance is below minimum (previously only panicked on zero balance) - Show receive address in spendable-balance timeout warning Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: patch SPV UTXO spendability flags before coin selection Upstream key-wallet-manager (rust-dashcore) never sets is_confirmed or is_instantlocked on UTXOs, but CoinSelector requires one of them. This caused "No UTXOs available for selection" errors despite having balance. Workaround infers status from block inclusion (height > 0 → confirmed, height == 0 → IS-locked). Ref: dashpay/rust-dashcore#514 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: harden backend E2E tests with retry logic and calibrated amounts - Increase funding amounts to avoid insufficient-funds flakes - Add 3-attempt retry for identity registration (chain height sync) - Retry on "No UTXOs" in send_with_retry alongside "Insufficient" - Wait for spendable balance in create_funded_test_wallet before return - Add CI workflow for backend E2E tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update test command in backend E2E workflow * ci: merge backend-e2e workflow into tests workflow (#727) * Initial plan * ci: merge backend-e2e workflow into tests workflow as an additional step Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com> * test: add cleanup_only noop test to sweep orphaned wallets Add a standalone test that triggers BackendTestContext initialization, which runs cleanup_test_wallets() as its final step. This can be run as a dedicated CI step after the E2E suite to sweep orphaned wallet funds back to the framework wallet. Run with: cargo test --test backend-e2e --all-features -- --ignored --nocapture cleanup_only Co-authored-by: lklimek <lklimek@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add cleanup step for E2E test wallets Added a cleanup step for E2E test wallets in the workflow. * Simplify E2E test workflow conditions Removed conditional checks for E2E_WALLET_MNEMONIC in test steps. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: lklimek <lklimek@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * fix: address PR #673 review comments from triage Production code: - Extract patch_utxo_spendability_flags() helper to deduplicate workaround in estimate_fallback_amount and build_unsigned_payment_tx - Add IdentityKeys::new() constructor - Make wallet+address persistence atomic via store_wallet_with_addresses() - Add pending_wallet_selection after wallet creation Test code: - Add DPNS registration retry for identity propagation delay - Use u64 hex for DPNS name uniqueness (CMT-023) - Calibrate test funding amounts per reviewer feedback - Add fragility note on string-match wallet detection (CMT-006) - Add TODO for identity fund withdrawal in cleanup (CMT-032) - Add INTENTIONAL comment for bounded channel design (CMT-017) - Add balance assertion for return leg in send_funds test - Log reconcile_spv_wallets errors in wait helpers - Use is_ok_and for clarity in spv_wallet test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: remove UTXO spendability workaround, update platform dep Remove `patch_utxo_spendability_flags()` that faked IS-locked status on mempool UTXOs. Wait for upstream fix (dashpay/rust-dashcore#514) to properly set is_confirmed/is_instantlocked flags on UTXOs. Also: - Update dashpay/platform rev to aa86b74f7e2 - Adapt to upstream API: FeeLevel→FeeRate, remove NetworkExt import - Fix retry to catch "No UTXOs" errors in test harness Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: deduplicate default_identity_key_specs Move the single canonical copy to backend_task::identity::mod and have the UI screen import it, eliminating ~240 lines of duplicated function and tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * ci: temporarily disable backend E2E tests in CI The backend E2E tests need updates after the TaskError migration (#739) changed AppContext field visibility. Commenting out the CI steps until the tests are adapted. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: type-safe wallet creation and identity key visibility - Restrict IdentityKeys fields to pub(crate) to prevent private key exposure outside the crate - Change register_wallet() to return TaskError instead of String, using proper rusqlite error matching via is_unique_constraint_violation() and a new WalletAlreadyImported variant - Change Wallet::new_from_seed() to accept Option<&Secret> for password instead of Option<&str>, keeping sensitive data in the Secret wrapper - Change Wallet::new_from_seed() to return TaskError instead of String, with a new WalletKeyDerivationFailed variant for derivation errors - Move build_identity_registration() and get_receive_address() from test helpers to production code in src/backend_task/identity/mod.rs - Extract is_unique_constraint_violation() to src/database/mod.rs as a shared pub(crate) utility, removing the duplicate in import_mnemonic_screen - Update all callers in add_new_wallet_screen and import_mnemonic_screen Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: address PR #673 review comments for E2E test framework - Move framework modules (harness, task_runner, wait, funding, cleanup, identity_helpers) into tests/backend-e2e/framework/ subdirectory - Make E2E_WALLET_MNEMONIC required (panic with instructions if unset) - Remove auto-faucet from initialization flow (keep as helper) - Remove retry loops in identity_create and identity_withdraw tests - Remove unnecessary wait_for_spendable_balance calls (already done by create_funded_test_wallet) - Replace all println!/eprintln! with tracing macros - Initialize tracing subscriber in harness init - Add "No spendable funds" and "spendable" to send retry conditions - Remove stale "other agent" NOTE comments from identity_helpers - Consolidate funding logic (harness delegates to funding module) - Update README for required mnemonic and new directory structure Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: reconcile production and test code after type-safe refactor Adapt test framework to production API changes: - Use IdentityKeys::new() constructor (fields now pub(crate)) - Match TaskError::WalletAlreadyImported variant instead of string - Allow dead_code on faucet helpers (kept but not auto-called) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: thread data_dir as explicit parameter to eliminate env var dependency Add `data_dir: PathBuf` field to `AppContext` and thread it through `Config::load_from()`, `Config::save()`, `SpvManager::new()`, `start_dash_qt()`, and `create_dash_core_config_if_not_exists()`. This enables E2E tests to specify their data directory without mutating process-wide environment variables, making parallel test execution safe. The `DASH_EVO_DATA_DIR` env var is still checked in production via `app_user_data_dir_path()`, but the resolved path is threaded through as a value rather than re-read from env on every call. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(test): simplify funded wallet creation and make spendable balance check reliable - Remove retry loop from create_funded_test_wallet; wait for full amount_duffs instead of 1 duff in spendable balance check - Add Wallet::spv_confirmed_balance() that returns None when SPV hasn't synced yet (no max_balance fallback) - Use spv_confirmed_balance() in wait_for_spendable_balance so the wait never gets false positives from the fallback - Remove --test-threads=1 requirement from README (unsafe set_var was the only reason; data_dir is now threaded explicitly) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove send retry loop, handle PRIMARY KEY constraints, isolate SPV test dirs - Remove send_with_retry() from send_funds.rs; use wait_for_spendable_balance before each send instead - Add SQLITE_CONSTRAINT_PRIMARYKEY (1555) to uniqueness check alongside SQLITE_CONSTRAINT_UNIQUE (2067) - Use tempfile::TempDir in SPV tests instead of fixed /tmp/spv-test path to prevent state leaks and support concurrent test runs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Pasta Lil Claw <pasta+claw@dashboost.org> Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Paul DeLucia <69597248+pauldelucia@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: lklimek <lklimek@users.noreply.github.com>
backend-e2e.ymlwas a separate workflow that duplicated the full dependency build (checkout, toolchain, system deps, protoc, cargo registry cache) already performed bytests.yml, causing a complete rebuild for E2E tests.Changes
.github/workflows/backend-e2e.ymltests.yml: Addedtests/backend-e2e/**to path triggers; appended a "Run backend E2E tests" step at the end of the existingtestjobBecause the E2E step runs in the same job, it reuses the already-compiled
target/artifacts from the precedingcargo teststep — no rebuild. The step is a no-op whenE2E_WALLET_MNEMONICis not set.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.