diff --git a/Cargo.lock b/Cargo.lock index 613be354e..719b22dbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1877,7 +1877,7 @@ dependencies = [ [[package]] name = "dapi-grpc" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "dash-platform-macros", "futures-core", @@ -1979,19 +1979,17 @@ dependencies = [ [[package]] name = "dash-async" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ - "futures", "thiserror 2.0.18", "tokio", - "tokio-util", "tracing", ] [[package]] name = "dash-context-provider" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "dash-async", "dpp", @@ -2083,7 +2081,7 @@ dependencies = [ [[package]] name = "dash-network" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" dependencies = [ "bincode 2.0.1", "bincode_derive", @@ -2094,7 +2092,7 @@ dependencies = [ [[package]] name = "dash-network-seeds" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" dependencies = [ "dash-network", ] @@ -2102,7 +2100,7 @@ dependencies = [ [[package]] name = "dash-platform-macros" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "heck", "quote", @@ -2112,7 +2110,7 @@ dependencies = [ [[package]] name = "dash-sdk" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "arc-swap", "async-trait", @@ -2150,7 +2148,7 @@ dependencies = [ [[package]] name = "dash-spv" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" dependencies = [ "async-trait", "chrono", @@ -2179,7 +2177,7 @@ dependencies = [ [[package]] name = "dashcore" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" dependencies = [ "anyhow", "base64-compat", @@ -2205,12 +2203,12 @@ dependencies = [ [[package]] name = "dashcore-private" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" [[package]] name = "dashcore-rpc" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" dependencies = [ "dashcore-rpc-json", "hex", @@ -2223,7 +2221,7 @@ dependencies = [ [[package]] name = "dashcore-rpc-json" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" dependencies = [ "bincode 2.0.1", "dashcore", @@ -2238,7 +2236,7 @@ dependencies = [ [[package]] name = "dashcore_hashes" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" dependencies = [ "bincode 2.0.1", "dashcore-private", @@ -2249,7 +2247,7 @@ dependencies = [ [[package]] name = "dashpay-contract" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "platform-value", "platform-version", @@ -2260,7 +2258,7 @@ dependencies = [ [[package]] name = "data-contracts" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "dashpay-contract", "dpns-contract", @@ -2546,7 +2544,7 @@ checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" [[package]] name = "dpns-contract" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "platform-value", "platform-version", @@ -2557,7 +2555,7 @@ dependencies = [ [[package]] name = "dpp" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "anyhow", "async-trait", @@ -2607,7 +2605,7 @@ dependencies = [ [[package]] name = "dpp-json-convertible-derive" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "proc-macro2", "quote", @@ -2617,7 +2615,7 @@ dependencies = [ [[package]] name = "drive" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "bincode 2.0.1", "byteorder", @@ -2642,7 +2640,7 @@ dependencies = [ [[package]] name = "drive-proof-verifier" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "bincode 2.0.1", "dapi-grpc", @@ -3665,7 +3663,7 @@ dependencies = [ [[package]] name = "git-state" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" [[package]] name = "gl_generator" @@ -4989,7 +4987,7 @@ dependencies = [ [[package]] name = "key-wallet" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" dependencies = [ "async-trait", "base58ck", @@ -5012,7 +5010,7 @@ dependencies = [ [[package]] name = "key-wallet-manager" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff#48a07d3fcd2f8d37e109f969eb5da0a8bbbb9aff" +source = "git+https://github.com/dashpay/rust-dashcore?rev=b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5#b3fb82445a3a0ac1a9c1ff6f8c18c7201d08c1e5" dependencies = [ "async-trait", "dashcore", @@ -5036,7 +5034,7 @@ dependencies = [ [[package]] name = "keyword-search-contract" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "platform-value", "platform-version", @@ -5249,7 +5247,7 @@ dependencies = [ [[package]] name = "masternode-reward-shares-contract" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "platform-value", "platform-version", @@ -6461,7 +6459,7 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "platform-encryption" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "aes", "cbc", @@ -6474,7 +6472,7 @@ dependencies = [ [[package]] name = "platform-serialization" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "bincode 2.0.1", "platform-version", @@ -6483,7 +6481,7 @@ dependencies = [ [[package]] name = "platform-serialization-derive" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "proc-macro2", "quote", @@ -6494,7 +6492,7 @@ dependencies = [ [[package]] name = "platform-value" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "base64 0.22.1", "bincode 2.0.1", @@ -6514,7 +6512,7 @@ dependencies = [ [[package]] name = "platform-version" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "bincode 2.0.1", "grovedb-version 5.0.0", @@ -6525,7 +6523,7 @@ dependencies = [ [[package]] name = "platform-versioning" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "proc-macro2", "quote", @@ -6535,13 +6533,12 @@ dependencies = [ [[package]] name = "platform-wallet" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "arc-swap", "async-trait", "bimap", "bs58", - "dash-async", "dash-sdk", "dash-spv", "dashcore", @@ -6568,7 +6565,7 @@ dependencies = [ [[package]] name = "platform-wallet-storage" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "apple-native-keyring-store", "argon2", @@ -7565,7 +7562,7 @@ dependencies = [ [[package]] name = "rs-dapi-client" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "backon", "chrono", @@ -7591,7 +7588,7 @@ dependencies = [ [[package]] name = "rs-sdk-trusted-context-provider" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "arc-swap", "dash-async", @@ -8833,7 +8830,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "token-history-contract" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "platform-value", "platform-version", @@ -9678,7 +9675,7 @@ dependencies = [ [[package]] name = "wallet-utils-contract" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "platform-value", "platform-version", @@ -10934,7 +10931,7 @@ dependencies = [ [[package]] name = "withdrawals-contract" version = "4.0.0" -source = "git+https://github.com/dashpay/platform?branch=dash-evo-tool#44c20e35f572800d62e95ac9fcaa50697c25d1bd" +source = "git+https://github.com/dashpay/platform?rev=93b967f9c7ab0164b47fe825d2bae58b3974625c#93b967f9c7ab0164b47fe825d2bae58b3974625c" dependencies = [ "num_enum 0.5.11", "platform-value", diff --git a/Cargo.toml b/Cargo.toml index bd7d3f9cf..a4b485422 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ qrcode = "0.14.1" nix = { version = "0.31.1", features = ["signal"] } eframe = { version = "0.35.0", features = ["persistence", "wgpu"] } base64 = "0.22.1" -dash-sdk = { git = "https://github.com/dashpay/platform", branch = "dash-evo-tool", features = [ +dash-sdk = { git = "https://github.com/dashpay/platform", rev = "93b967f9c7ab0164b47fe825d2bae58b3974625c", features = [ "core_key_wallet", "core_key_wallet_manager", "core_bincode", @@ -28,12 +28,12 @@ dash-sdk = { git = "https://github.com/dashpay/platform", branch = "dash-evo-too "core_spv", "shielded", ] } -rs-sdk-trusted-context-provider = { git = "https://github.com/dashpay/platform", branch = "dash-evo-tool" } -platform-wallet = { git = "https://github.com/dashpay/platform", branch = "dash-evo-tool", features = [ +rs-sdk-trusted-context-provider = { git = "https://github.com/dashpay/platform", rev = "93b967f9c7ab0164b47fe825d2bae58b3974625c" } +platform-wallet = { git = "https://github.com/dashpay/platform", rev = "93b967f9c7ab0164b47fe825d2bae58b3974625c", features = [ "serde", "shielded", ] } -platform-wallet-storage = { git = "https://github.com/dashpay/platform", branch = "dash-evo-tool", features = [ +platform-wallet-storage = { git = "https://github.com/dashpay/platform", rev = "93b967f9c7ab0164b47fe825d2bae58b3974625c", features = [ "shielded", ] } zip32 = "0.2.0" diff --git a/src/wallet_backend/event_bridge.rs b/src/wallet_backend/event_bridge.rs index 8d8fe4416..179965f45 100644 --- a/src/wallet_backend/event_bridge.rs +++ b/src/wallet_backend/event_bridge.rs @@ -422,20 +422,6 @@ impl PlatformEventHandler for EventBridge { self.nudge_refresh(); } - fn on_wallet_skipped_on_load( - &self, - wallet_id: platform_wallet::wallet::platform_wallet::WalletId, - reason: &platform_wallet::manager::load_outcome::SkipReason, - ) { - // Public wallet id + structural reason only; never a secret. The - // user-facing banner is raised in `register_persisted_wallets`. - tracing::warn!( - wallet_id = %hex::encode(wallet_id), - %reason, - "A saved wallet was skipped on load because its stored data is corrupt" - ); - } - fn on_shielded_sync_progress(&self, cumulative_scanned: u64, block_height: u64) { // Downloaded-notes progress for an in-flight pass — drives the // shielded tab's "scanning" indicator. Network-scoped (one pass covers diff --git a/src/wallet_backend/loader.rs b/src/wallet_backend/loader.rs index 715a65b9f..e57ff4eff 100644 --- a/src/wallet_backend/loader.rs +++ b/src/wallet_backend/loader.rs @@ -19,42 +19,21 @@ //! the load brings back nothing — exactly the funds-invisible state the //! W1/W2 writers exist to prevent. //! -//! The outcome types here are DET-opaque: [`LoadedWallets`] carries only -//! DET's [`WalletSeedHash`] keys and a DET-side [`PersistedLoadSkip`] -//! reason — no `platform_wallet` / `key_wallet` type crosses the seam. +//! The outcome type here is DET-opaque: [`LoadedWallets`] carries only +//! DET's [`WalletSeedHash`] keys — no `platform_wallet` / `key_wallet` +//! type crosses the seam. use crate::model::wallet::WalletSeedHash; /// Outcome of a persisted-wallet load pass, mapped to DET-opaque types. /// -/// Carries no upstream `platform-wallet` type. A non-empty `skipped` -/// list is still a **success**: a single corrupt persisted row is -/// reported and the remaining wallets load. A whole-load failure is a -/// `TaskError` from [`WalletBackend::load_from_persistor_seedless`], not -/// a populated `skipped`. +/// Carries no upstream `platform-wallet` type. Any load failure is a +/// `TaskError` from [`WalletBackend::load_from_persistor_seedless`] — the +/// upstream load either rebuilds every persisted wallet or fails whole. /// /// [`WalletBackend::load_from_persistor_seedless`]: super::WalletBackend::load_from_persistor_seedless #[derive(Debug, Default, Clone, PartialEq, Eq)] pub struct LoadedWallets { /// Wallets now registered with the backend, keyed by DET's seed hash. pub loaded: Vec, - /// Wallets present on disk but skipped because their persisted row - /// was unusable. The [`WalletSeedHash`] is present only when the - /// skipped wallet could be matched to a DET sidecar entry; an - /// unmatched skip carries `None`. - pub skipped: Vec<(Option, PersistedLoadSkip)>, -} - -/// DET-opaque reason a persisted wallet row was skipped during load. -/// -/// Mirrors the upstream corrupt-row families without leaking the -/// upstream `CorruptKind` type or any row-derived bytes. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum PersistedLoadSkip { - /// The wallet row has no usable account manifest to rebuild from. - MissingManifest, - /// The persisted account xpub failed to parse. - MalformedXpub, - /// Any other structural decode/projection failure on the row. - DecodeError, } diff --git a/src/wallet_backend/mod.rs b/src/wallet_backend/mod.rs index 36eb3827c..7bf8bf426 100644 --- a/src/wallet_backend/mod.rs +++ b/src/wallet_backend/mod.rs @@ -94,7 +94,7 @@ pub use contact_profile_cache::{CachedContactProfile, ContactProfileCacheView}; pub use event_bridge::EventBridge; pub(crate) use kv::network_prefix; pub use kv::{DetKv, DetScope, KvAdapterError, SCHEMA_VERSION as KV_SCHEMA_VERSION}; -pub use loader::{LoadedWallets, PersistedLoadSkip}; +pub use loader::LoadedWallets; pub use single_key::SingleKeyView; use snapshot::SnapshotStore; pub use snapshot::{DetUtxo, DetWalletBalance, WalletSnapshot}; @@ -124,8 +124,6 @@ use crate::context::connection_status::ConnectionStatus; use crate::model::selected_identity::SelectedIdentity; use crate::model::selected_wallet::SelectedWallet; use crate::model::wallet::{PlatformAddressEntry, WalletSeedHash}; -use crate::ui::MessageType; -use crate::ui::components::message_banner::{BannerHandle, OptionBannerExt}; use crate::utils::egui_mpsc::SenderAsync; /// The upstream persister DET consumes. Authored upstream (PR #3625) — DET @@ -238,13 +236,6 @@ struct Inner { /// dispatch is user-initiated and rare relative to lock acquisition /// cost. dashpay_address_index_lock: std::sync::Mutex<()>, - /// Handle to the warning banner raised when persisted wallets are skipped - /// on load. A re-entrant load pass (via [`WalletBackend::ensure_wallets_registered`]) - /// supersedes this banner rather than stacking a second, possibly - /// contradictory one. Interior mutability because the backend is - /// `Arc`-shared and `register_persisted_wallets` runs on `&self`. See - /// [`raise_skipped_wallets_banner`]. - skipped_wallets_banner: std::sync::Mutex>, /// Encrypted secret vault. Holds imported single-key WIFs /// (`single_key_priv.*` labels, see [`single_key`]) and HD-wallet /// BIP-39 seeds (`envelope.v1` labels under `WalletId(seed_hash)`, see @@ -390,7 +381,6 @@ impl WalletBackend { network, spv_storage_dir, dashpay_address_index_lock: std::sync::Mutex::new(()), - skipped_wallets_banner: std::sync::Mutex::new(None), secret_store, single_key_index: std::sync::RwLock::new(std::collections::BTreeMap::new()), app_kv, @@ -477,24 +467,8 @@ impl WalletBackend { let outcome = self.load_from_persistor_seedless(ctx).await?; tracing::info!( loaded = outcome.loaded.len(), - skipped = outcome.skipped.len(), "Persisted-wallet load pass complete" ); - for (seed_hash, reason) in &outcome.skipped { - tracing::warn!( - wallet = ?seed_hash.map(hex::encode), - ?reason, - "Skipped a corrupt persisted wallet row on load" - ); - } - { - let mut handle = self - .inner - .skipped_wallets_banner - .lock() - .unwrap_or_else(|e| e.into_inner()); - raise_skipped_wallets_banner(ctx.egui_ctx(), outcome.skipped.len(), &mut handle); - } // `load()` rebuilds `IdentityRegistration` from the manifest, but // per-index `IdentityTopUp{registration_index}` enters the manifest @@ -555,25 +529,20 @@ impl WalletBackend { .map(|(seed_hash, meta)| (meta.xpub_encoded, seed_hash)) .collect(); - // 2. One persister load pass, only when the manager is empty. - // A non-empty `skipped` is success; `Err` is reserved for - // whole-load failures. On a re-run the manager already holds - // the wallets, so the upstream load (which rejects duplicates) - // is skipped and only the resolution below runs. - let skipped = if self.inner.pwm.wallet_ids().await.is_empty() { - let outcome = self.inner.pwm.load_from_persistor().await.map_err(|e| { - TaskError::WalletBackend { + // 2. One persister load pass, only when the manager is empty. Any + // load failure is fatal: the upstream API returns `Result<(), _>`, + // so `Err` is the only failure signal. On a re-run the manager + // already holds the wallets, so the upstream load (which rejects + // duplicates) is skipped and only the resolution below runs. + if self.inner.pwm.wallet_ids().await.is_empty() { + self.inner + .pwm + .load_from_persistor() + .await + .map_err(|e| TaskError::WalletBackend { source: Box::new(e), - } - })?; - outcome - .skipped() - .iter() - .map(|(_wallet_id, reason)| (None, persisted_load_skip_from_upstream(reason))) - .collect() - } else { - Vec::new() - }; + })?; + } // 3. Resolve every currently-registered wallet to its DET seed // hash via the fund-routing gate, registering it in the @@ -616,7 +585,7 @@ impl WalletBackend { loaded.push(seed_hash); } - Ok(LoadedWallets { loaded, skipped }) + Ok(LoadedWallets { loaded }) } /// `ExtendedPubKey::encode()` bytes of the loaded watch-only wallet's @@ -1184,16 +1153,22 @@ impl WalletBackend { } // `pwm.shutdown()` quiesces the periodic coordinators — draining any // in-flight pass and its persister / host-callback fan-out — then drains - // the wallet-event adapter task. Best-effort: a non-clean report flags a - // still-live worker or orphan, which teardown proceeds past regardless — - // log it rather than surface it. - let report = self.inner.pwm.shutdown().await; - if !report.all_clean() { - tracing::warn!( - ?report, - "Wallet manager shutdown did not complete cleanly; continuing teardown" - ); - } + // the wallet-event adapter task. Best-effort: a non-clean report used to + // flag a still-live worker or orphan, which teardown proceeds past + // regardless — log it rather than surface it. + // + // TODO(platform-pr3968): `shutdown()` returns `()` at this rev (no + // clean-shutdown report type yet) — the report check below is + // commented out rather than dropped outright; restore once platform + // re-adds the report type. User-confirmed removal of the + // shutdown-failure warning log for this rev. + self.inner.pwm.shutdown().await; + // if !report.all_clean() { + // tracing::warn!( + // ?report, + // "Wallet manager shutdown did not complete cleanly; continuing teardown" + // ); + // } } /// Stop chain sync **in place**, keeping this backend (and its @@ -2302,8 +2277,13 @@ fn map_shielded_op_error(e: platform_wallet::error::PlatformWalletError) -> Task }, // Every remaining variant → generic WalletBackend wrapper. + // + // TODO(platform-pr3968): `ShieldedShutdownIncomplete` doesn't exist on + // `PlatformWalletError` at this rev; it belongs in this bucket once + // platform re-adds it. other @ (P::WalletCreation(_) - | P::RehydrationTopologyUnsupported { .. } + | P::PersisterLoad(_) + | P::AddressNonceMismatch { .. } | P::WalletNotFound(_) | P::WalletAlreadyExists(_) | P::IdentityAlreadyExists(_) @@ -2328,9 +2308,6 @@ fn map_shielded_op_error(e: platform_wallet::error::PlatformWalletError) -> Task | P::InputSumOverflow | P::AddressNotFound(_) | P::KeyDerivation(_) - | P::RehydrationPoolMismatch { .. } - | P::RehydrationPoolTypeMismatch { .. } - | P::PersisterLoad(_) | P::Persistence(_) | P::SeedMismatch { .. } | P::WalletLocked @@ -2348,9 +2325,7 @@ fn map_shielded_op_error(e: platform_wallet::error::PlatformWalletError) -> Task | P::ShieldedTreeUpdateFailed(_) | P::ShieldedStoreError(_) | P::ShieldedMerkleWitnessUnavailable(_) - | P::ShieldedKeyDerivation(_) - | P::AddressNonceMismatch { .. } - | P::ShieldedShutdownIncomplete { .. }) => TaskError::WalletBackend { + | P::ShieldedKeyDerivation(_)) => TaskError::WalletBackend { source: Box::new(other), }, } @@ -2447,64 +2422,6 @@ fn map_platform_address_fund_error(e: platform_wallet::error::PlatformWalletErro } } -/// Map an upstream load-skip reason to its DET-opaque equivalent, -/// dropping any row-derived string so no upstream detail crosses the -/// seam. -fn persisted_load_skip_from_upstream( - reason: &platform_wallet::manager::load_outcome::SkipReason, -) -> PersistedLoadSkip { - use platform_wallet::manager::load_outcome::{CorruptKind, SkipReason}; - match reason { - SkipReason::CorruptPersistedRow { kind } => match kind { - CorruptKind::MissingManifest => PersistedLoadSkip::MissingManifest, - CorruptKind::MalformedXpub => PersistedLoadSkip::MalformedXpub, - CorruptKind::DecodeError(_) => PersistedLoadSkip::DecodeError, - // `CorruptKind` is `#[non_exhaustive]`: a future structural - // family folds into the generic decode-failure bucket so no - // upstream detail crosses the seam. - _ => PersistedLoadSkip::DecodeError, - }, - // `SkipReason` is `#[non_exhaustive]`: any future skip reason - // surfaces as a generic decode failure rather than breaking the - // build or leaking row-derived detail across the seam. - _ => PersistedLoadSkip::DecodeError, - } -} - -/// Builds the calm, user-facing banner text for wallets skipped on -/// persisted load, or `None` if nothing was skipped. Never includes -/// row-derived detail (seed hashes, upstream reason strings) — those -/// stay in the logs. -pub fn skipped_wallets_banner_text(skipped: usize) -> Option { - match skipped { - 0 => None, - 1 => Some( - "1 saved wallet couldn't be opened. Re-add it from its recovery phrase to restore it." - .to_string(), - ), - n => Some(format!( - "{n} saved wallets couldn't be opened. Re-add them from their recovery phrases to restore them." - )), - } -} - -/// Raise the skipped-persisted-wallets warning banner for this load pass, -/// superseding any banner a previous pass left behind so a re-entrant call -/// (e.g. via [`WalletBackend::ensure_wallets_registered`]) with a different -/// skip count never stacks a second, contradictory banner alongside the -/// first. A pass with zero skips clears a stale banner from an earlier pass -/// rather than leaving it stuck. -fn raise_skipped_wallets_banner( - ctx: &egui::Context, - skipped_count: usize, - banner_handle: &mut Option, -) { - match skipped_wallets_banner_text(skipped_count) { - Some(text) => banner_handle.raise_persistent(ctx, text, MessageType::Warning), - None => banner_handle.take_and_clear(), - } -} - /// Bucket for `PlatformWalletError`s coming out of identity register / top-up. enum IdentityOpErrorKind { /// Network or broadcast rejected the submission (SDK error or asset-lock @@ -2581,23 +2498,19 @@ fn identity_op_error_kind(e: &platform_wallet::error::PlatformWalletError) -> Id | P::PersisterLoad(_) | P::Persistence(_) | P::SeedMismatch { .. } + // Address nonce desync is a precondition/state fault unrelated to + // identity registration; bucket as Other. + | P::AddressNonceMismatch { .. } // Broadcast was accepted but its execution result is unconfirmed — the // op may already be on chain, so it is neither a rejection nor a // finality timeout. Bucket as Other; the upstream contract says the // caller must not re-submit (the next sync reconciles). | P::TransactionBroadcastUnconfirmed(_) | P::ShieldedBroadcastUnconfirmed { .. } - | P::ShieldedSpendUnconfirmed { .. } - | P::RehydrationTopologyUnsupported { .. } - | P::RehydrationPoolMismatch { .. } - // A rehydration structural invariant broke (a discovery probe and its - // real address pool disagreed on chain order); fail-closed as a - // precondition, unrelated to identity registration. Bucket as Other. - | P::RehydrationPoolTypeMismatch { .. } - // Address nonce desync and an incomplete shielded-worker shutdown are - // both precondition/state faults unrelated to identity registration. - | P::AddressNonceMismatch { .. } - | P::ShieldedShutdownIncomplete { .. } => IdentityOpErrorKind::Other, + | P::ShieldedSpendUnconfirmed { .. } => IdentityOpErrorKind::Other, + // TODO(platform-pr3968): `ShieldedShutdownIncomplete` doesn't exist on + // `PlatformWalletError` at this rev; it belongs in the `Other` bucket + // once platform re-adds it. } } @@ -2961,107 +2874,6 @@ mod tests { ); } - /// No skips yields no banner; one or many skips yields singular/plural - /// text with no row-derived detail. - #[test] - fn skipped_wallets_banner_text_singular_plural_and_none() { - assert_eq!(skipped_wallets_banner_text(0), None); - assert_eq!( - skipped_wallets_banner_text(1), - Some( - "1 saved wallet couldn't be opened. Re-add it from its recovery phrase to restore it." - .to_string() - ) - ); - assert_eq!( - skipped_wallets_banner_text(3), - Some( - "3 saved wallets couldn't be opened. Re-add them from their recovery phrases to restore them." - .to_string() - ) - ); - } - - /// A re-entrant load pass supersedes the previous skipped-wallets banner - /// instead of stacking a second one, and a zero-skip pass clears it. Drives - /// [`raise_skipped_wallets_banner`] directly (no `WalletBackend`/`AppContext`) - /// and asserts against the rendered banner so a regression that drops the - /// call, swaps the Warning type, reads the wrong count, or stacks banners - /// fails here. - #[test] - fn raise_skipped_wallets_banner_replaces_and_clears() { - use crate::ui::components::MessageBanner; - use egui_kittest::Harness; - use egui_kittest::kittest::Queryable; - - let singular = skipped_wallets_banner_text(1).expect("one skip yields text"); - let plural = skipped_wallets_banner_text(3).expect("three skips yield text"); - let mut handle: Option = None; - - let mut harness = Harness::builder() - .with_size(egui::vec2(600.0, 200.0)) - .build_ui(MessageBanner::show_global); - - // Pass 1: one skip → singular copy under the Warning icon. - raise_skipped_wallets_banner(&harness.ctx, 1, &mut handle); - harness.run(); - assert!( - harness.query_by_label(singular.as_str()).is_some(), - "first pass must render the singular skip copy", - ); - assert!( - harness.query_by_label("\u{26A0}").is_some(), - "skip banner must carry the Warning icon, not another type", - ); - - // Pass 2: re-entrant call with a different count must replace, not stack. - raise_skipped_wallets_banner(&harness.ctx, 3, &mut handle); - harness.run(); - assert!( - harness.query_by_label(plural.as_str()).is_some(), - "second pass must render the new plural copy", - ); - assert!( - harness.query_by_label(singular.as_str()).is_none(), - "the superseded singular banner must be gone, not stacked", - ); - - // Pass 3: zero skips clears the banner. - raise_skipped_wallets_banner(&harness.ctx, 0, &mut handle); - harness.run(); - assert!( - harness.query_by_label(plural.as_str()).is_none(), - "a zero-skip pass must clear the banner", - ); - assert!( - harness.query_by_label("\u{26A0}").is_none(), - "no Warning icon must remain after clearing", - ); - } - - /// The upstream load-skip families map 1:1 onto the DET-opaque - /// [`PersistedLoadSkip`] and drop the row-derived string so no - /// upstream detail crosses the seam. - #[test] - fn skip_reason_maps_to_det_opaque_variants() { - use platform_wallet::manager::load_outcome::{CorruptKind, SkipReason}; - let cases = [ - ( - CorruptKind::MissingManifest, - PersistedLoadSkip::MissingManifest, - ), - (CorruptKind::MalformedXpub, PersistedLoadSkip::MalformedXpub), - ( - CorruptKind::DecodeError("secret-ish detail".into()), - PersistedLoadSkip::DecodeError, - ), - ]; - for (kind, expected) in cases { - let reason = SkipReason::CorruptPersistedRow { kind }; - assert_eq!(persisted_load_skip_from_upstream(&reason), expected); - } - } - /// The seedless bridge keys off the BIP44 account xpub. The DET /// account xpub (`Wallet::new_from_seed`) must equal the upstream /// account xpub for the SAME seed, so the watch-only wallet rebuilt diff --git a/tests/kittest/main.rs b/tests/kittest/main.rs index 20bdfc19f..620a3a6d2 100644 --- a/tests/kittest/main.rs +++ b/tests/kittest/main.rs @@ -22,7 +22,6 @@ mod progress_overlay; mod register_dpns_name_screen; mod restore_single_key; mod secret_prompt; -mod skipped_wallets_banner; mod startup; mod support; mod tokens_screen; diff --git a/tests/kittest/skipped_wallets_banner.rs b/tests/kittest/skipped_wallets_banner.rs deleted file mode 100644 index d30fe7c53..000000000 --- a/tests/kittest/skipped_wallets_banner.rs +++ /dev/null @@ -1,86 +0,0 @@ -//! kittest coverage for the persisted-wallet load-skip banner seam. -//! -//! `WalletBackend::register_persisted_wallets` raises the banner via -//! `MessageBanner::set_global(ctx.egui_ctx(), skipped_wallets_banner_text(n), -//! MessageType::Warning)`. The async/`AppContext` wrapper can't be booted in a -//! unit test, so these drive the exact copy + banner type the app emits -//! through the public `MessageBanner` surface — the same seam the app loop -//! uses — so a regression in the copy or the Warning type fails here. - -use dash_evo_tool::ui::MessageType; -use dash_evo_tool::ui::components::MessageBanner; -use dash_evo_tool::wallet_backend::skipped_wallets_banner_text; -use egui_kittest::Harness; -use egui_kittest::kittest::Queryable; - -/// A non-empty skip count renders a Warning-typed banner carrying the -/// singular copy verbatim, alongside the ⚠ icon and a dismiss control. -#[test] -fn skipped_banner_renders_warning_with_singular_copy() { - let label = skipped_wallets_banner_text(1).expect("one skip yields banner text"); - - let mut harness = Harness::builder() - .with_size(egui::vec2(600.0, 200.0)) - .build_ui(move |ui| { - MessageBanner::set_global(ui.ctx(), &label, MessageType::Warning); - MessageBanner::show_global(ui); - }); - harness.run(); - - assert!( - harness - .query_by_label( - "1 saved wallet couldn't be opened. Re-add it from its recovery phrase to restore it." - ) - .is_some(), - "skip banner must render the singular copy verbatim", - ); - // Warning icon (color is not the only signal) + dismiss control present. - assert!( - harness.query_by_label("\u{26A0}").is_some(), - "warning icon must render alongside text", - ); - assert!(harness.query_by_label("\u{274C}").is_some()); -} - -/// A skip count above one renders the plural copy with the count. -#[test] -fn skipped_banner_renders_plural_copy() { - let label = skipped_wallets_banner_text(3).expect("three skips yield banner text"); - - let mut harness = Harness::builder() - .with_size(egui::vec2(600.0, 200.0)) - .build_ui(move |ui| { - MessageBanner::set_global(ui.ctx(), &label, MessageType::Warning); - MessageBanner::show_global(ui); - }); - harness.run(); - - assert!( - harness - .query_by_label( - "3 saved wallets couldn't be opened. Re-add them from their recovery phrases to restore them." - ) - .is_some(), - "skip banner must render the plural copy verbatim", - ); -} - -/// Zero skips yields no banner text, so no warning banner is rendered. -#[test] -fn no_skips_renders_no_banner() { - let mut harness = Harness::builder() - .with_size(egui::vec2(600.0, 200.0)) - .build_ui(|ui| { - if let Some(text) = skipped_wallets_banner_text(0) { - MessageBanner::set_global(ui.ctx(), text, MessageType::Warning); - } - MessageBanner::show_global(ui); - }); - harness.run(); - - assert!( - harness.query_by_label("\u{26A0}").is_none(), - "zero skips must not render a warning banner", - ); -}