chore(dash-spv): refresh masternode seed files#695
Merged
Conversation
xdustinface
approved these changes
Apr 28, 2026
3 tasks
QuantumExplorer
added a commit
that referenced
this pull request
Apr 28, 2026
* chore(dash-spv): refresh masternode seed files (#695) Co-authored-by: QuantumExplorer <11468583+QuantumExplorer@users.noreply.github.com> * feat: make wallet events atomic (#696) * feat: make wallet events atomic Reshape `WalletEvent` so each variant carries the records or context needed to persist a wallet update atomically off a single event, alongside the post-change balance. The variant set is now: - `TransactionReceived { wallet_id, record, balance }`. Fires when the wallet first sees an off-chain transaction. - `TransactionStatusChanged { wallet_id, txid, context, balance }`. Fires when a known off-chain transaction has its state change. Currently fires only for InstantSend locks. - `BlockUpdate { wallet_id, height, inserted, updated, matured, balance }`. Carries records bucketed by what happened to them in the block, plus the post-block balance. - `SyncHeightUpdate { wallet_id, height }`. Marks a filter-batch checkpoint. `TransactionRecord` carries `account_type` directly, identifying the owning account. `WalletInfoInterface` gains a `matured_coinbase_records` method that enumerates coinbase records crossing the maturity threshold during a height advance, populating `BlockUpdate.matured`. The FFI groups the flattened account-discriminator fields into an `FFIAccountType` struct and renames the prior discriminant enum to `FFIAccountKind`. * fix: record balance before bumping `block_processed_wallet_count` Tests wait on `block_processed_wallet_count` and then read `last_confirmed`/`last_unconfirmed`. Bumping the counter before storing the balance snapshot left those reads racey. Reorder so the balance is recorded first. Addresses CodeRabbit review comment on PR #696 #696 (comment) * fix: place `IdentityTopUp.registration_index` in `index_secondary` The `FFIAccountType` doc states `index_secondary` carries `registration_index` for `IdentityTopUp` and `index = 0` for variants without a meaningful primary index, matching the parallel encoding in `FFIAccountKind::from_account_type`. The `From<&AccountType>` impl wrote `registration_index` into `index` instead, breaking the documented FFI contract. Addresses CodeRabbit review comment on PR #696 #696 (comment) * fix: route confirmation backfills to `new_records` `is_new` is wallet-wide (set on the first matching account, then breaks), so the per-account `else` branch can run for an account that did not previously hold the record. `confirm_transaction` backfills via `record_transaction` in that case, but the post-call record was always pushed onto `updated_records`, breaking the atomic `inserted`/`updated` contract consumed by `WalletEvent::BlockUpdate`. Capture `existed_before` per account and route to `new_records` when the record was just created. Addresses CodeRabbit review comment on PR #696 #696 (comment) * refactor(key-wallet-manager): extract `finalize_block_advance` helper `process_block` and `update_last_processed_height` duplicated the entire balance-snapshot, prior-heights collection, matured-coinbase window, height advance, and per-wallet `BlockUpdate` emission. Extract the shared tail into a private `WalletManager::finalize_block_advance` helper that takes the inserted/updated maps. `update_last_processed_height` becomes a one-line call with empty maps; `process_block` keeps only its txdata loop before delegating. * refactor: rename wallet events for clearer semantics Rename `WalletEvent` variants and the matching FFI callbacks to past-participle names that say what happened, replacing vague "Update" suffixes: - `TransactionReceived` -> `TransactionDetected`. "Received" implied incoming funds, but the event fires for any first-time off-chain sighting (incoming or outgoing). - `TransactionStatusChanged` -> `TransactionInstantLocked`. The event only ever fires for an InstantSend lock applied to a known mempool tx, so name it for what it actually is. Drop the `status: TransactionContext` field and carry the `InstantLock` directly. - `BlockUpdate` -> `BlockProcessed`. Mirrors `process_block` and matches the past-participle pattern. - `SyncHeightUpdate` -> `SyncHeightAdvanced`. Conveys monotonic forward motion. FFI rename mirrors the Rust side: the IS callback now takes `islock_data: *const u8` + `islock_len: usize` instead of an `FFITransactionContext`, removing a discriminant that was always `InstantSend`. The wallet-side `OnBlockProcessedCallback` becomes `OnWalletBlockProcessedCallback` to disambiguate from the existing sync-event type with the same name. * fix: record balance before bumping IS-locked counter in test callback Addresses CodeRabbit review comment on PR #696 #696 (review) The instant_locked callback bumped `transaction_instant_send_locked_count` before calling `record_balance`. Tests that wait on the counter and then read `last_confirmed`/`last_unconfirmed` could observe the previous balance snapshot. Match the ordering used by the other callbacks: store the balance first, then bump the counter. * fix: backfill missing transaction record in InstantSend path Addresses CodeRabbit review comment on PR #696 #696 (review) The IS-lock branch in `WalletTransactionChecker::check_core_transaction` only updated accounts that already held a `TransactionRecord` for the txid. When wallet-level `is_new` was `false` (because at least one account had the record) but another matched account did not, the latter was silently skipped: no record was created and `mark_utxos_instant_send` ran against an empty UTXO set on that account. Mirror the confirmation path: when the affected account lacks the record, call `record_transaction` to register the record and its UTXOs, then mark them IS-locked. This ordering ensures the freshly registered UTXOs receive the IS-lock flag too. The backfilled record is pushed into `new_records` to match the existing convention from commit 659a6d5. Add `test_instantsend_backfills_missing_record_in_other_account` covering the multi-account scenario. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: QuantumExplorer <11468583+QuantumExplorer@users.noreply.github.com> Co-authored-by: Kevin Rombach <35775977+xdustinface@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
QuantumExplorer
added a commit
that referenced
this pull request
Apr 28, 2026
* feat: per-wallet filter scan and runtime wallet catch-up Filter matching and block processing now operate per wallet, so a wallet added at runtime catches up without forcing the already-synced wallets to reprocess anything. - `WalletInterface` restructured around per-wallet ops: `process_block_for_wallets`, `wallets_behind`, `monitored_addresses_for`, `wallet_synced_height`, and monotonic per-wallet height updates. Aggregate heights are derived (min of `synced_height`, max of `last_processed_height`) rather than stored. - `FiltersManager::scan_batch` matches each behind wallet's addresses only against filter heights it hasn't yet covered; already-synced wallets are skipped entirely. Matched blocks flow through `BlocksNeeded` carrying the per-block wallet set so `BlocksManager` processes each block only against the wallets whose filters matched. `FiltersBatch` records the scanned-wallet set so commit advances only their `synced_height`. - `FiltersManager::tick` detects when a wallet's `synced_height` sits below the current `committed_height` (a runtime add behind scan progress), clears in-flight pipeline state, lowers `committed_height` to the new aggregate floor, and re-enters `start_download` on the next 100ms tick. Runs in `Syncing`, `Synced`, and `WaitForEvents`. Based on: - #689 * chore: merge v0.42-dev into feat/per-wallet-filter-scan (#698) * chore(dash-spv): refresh masternode seed files (#695) Co-authored-by: QuantumExplorer <11468583+QuantumExplorer@users.noreply.github.com> * feat: make wallet events atomic (#696) * feat: make wallet events atomic Reshape `WalletEvent` so each variant carries the records or context needed to persist a wallet update atomically off a single event, alongside the post-change balance. The variant set is now: - `TransactionReceived { wallet_id, record, balance }`. Fires when the wallet first sees an off-chain transaction. - `TransactionStatusChanged { wallet_id, txid, context, balance }`. Fires when a known off-chain transaction has its state change. Currently fires only for InstantSend locks. - `BlockUpdate { wallet_id, height, inserted, updated, matured, balance }`. Carries records bucketed by what happened to them in the block, plus the post-block balance. - `SyncHeightUpdate { wallet_id, height }`. Marks a filter-batch checkpoint. `TransactionRecord` carries `account_type` directly, identifying the owning account. `WalletInfoInterface` gains a `matured_coinbase_records` method that enumerates coinbase records crossing the maturity threshold during a height advance, populating `BlockUpdate.matured`. The FFI groups the flattened account-discriminator fields into an `FFIAccountType` struct and renames the prior discriminant enum to `FFIAccountKind`. * fix: record balance before bumping `block_processed_wallet_count` Tests wait on `block_processed_wallet_count` and then read `last_confirmed`/`last_unconfirmed`. Bumping the counter before storing the balance snapshot left those reads racey. Reorder so the balance is recorded first. Addresses CodeRabbit review comment on PR #696 #696 (comment) * fix: place `IdentityTopUp.registration_index` in `index_secondary` The `FFIAccountType` doc states `index_secondary` carries `registration_index` for `IdentityTopUp` and `index = 0` for variants without a meaningful primary index, matching the parallel encoding in `FFIAccountKind::from_account_type`. The `From<&AccountType>` impl wrote `registration_index` into `index` instead, breaking the documented FFI contract. Addresses CodeRabbit review comment on PR #696 #696 (comment) * fix: route confirmation backfills to `new_records` `is_new` is wallet-wide (set on the first matching account, then breaks), so the per-account `else` branch can run for an account that did not previously hold the record. `confirm_transaction` backfills via `record_transaction` in that case, but the post-call record was always pushed onto `updated_records`, breaking the atomic `inserted`/`updated` contract consumed by `WalletEvent::BlockUpdate`. Capture `existed_before` per account and route to `new_records` when the record was just created. Addresses CodeRabbit review comment on PR #696 #696 (comment) * refactor(key-wallet-manager): extract `finalize_block_advance` helper `process_block` and `update_last_processed_height` duplicated the entire balance-snapshot, prior-heights collection, matured-coinbase window, height advance, and per-wallet `BlockUpdate` emission. Extract the shared tail into a private `WalletManager::finalize_block_advance` helper that takes the inserted/updated maps. `update_last_processed_height` becomes a one-line call with empty maps; `process_block` keeps only its txdata loop before delegating. * refactor: rename wallet events for clearer semantics Rename `WalletEvent` variants and the matching FFI callbacks to past-participle names that say what happened, replacing vague "Update" suffixes: - `TransactionReceived` -> `TransactionDetected`. "Received" implied incoming funds, but the event fires for any first-time off-chain sighting (incoming or outgoing). - `TransactionStatusChanged` -> `TransactionInstantLocked`. The event only ever fires for an InstantSend lock applied to a known mempool tx, so name it for what it actually is. Drop the `status: TransactionContext` field and carry the `InstantLock` directly. - `BlockUpdate` -> `BlockProcessed`. Mirrors `process_block` and matches the past-participle pattern. - `SyncHeightUpdate` -> `SyncHeightAdvanced`. Conveys monotonic forward motion. FFI rename mirrors the Rust side: the IS callback now takes `islock_data: *const u8` + `islock_len: usize` instead of an `FFITransactionContext`, removing a discriminant that was always `InstantSend`. The wallet-side `OnBlockProcessedCallback` becomes `OnWalletBlockProcessedCallback` to disambiguate from the existing sync-event type with the same name. * fix: record balance before bumping IS-locked counter in test callback Addresses CodeRabbit review comment on PR #696 #696 (review) The instant_locked callback bumped `transaction_instant_send_locked_count` before calling `record_balance`. Tests that wait on the counter and then read `last_confirmed`/`last_unconfirmed` could observe the previous balance snapshot. Match the ordering used by the other callbacks: store the balance first, then bump the counter. * fix: backfill missing transaction record in InstantSend path Addresses CodeRabbit review comment on PR #696 #696 (review) The IS-lock branch in `WalletTransactionChecker::check_core_transaction` only updated accounts that already held a `TransactionRecord` for the txid. When wallet-level `is_new` was `false` (because at least one account had the record) but another matched account did not, the latter was silently skipped: no record was created and `mark_utxos_instant_send` ran against an empty UTXO set on that account. Mirror the confirmation path: when the affected account lacks the record, call `record_transaction` to register the record and its UTXOs, then mark them IS-locked. This ordering ensures the freshly registered UTXOs receive the IS-lock flag too. The backfilled record is pushed into `new_records` to match the existing convention from commit 659a6d5. Add `test_instantsend_backfills_missing_record_in_other_account` covering the multi-account scenario. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: QuantumExplorer <11468583+QuantumExplorer@users.noreply.github.com> Co-authored-by: Kevin Rombach <35775977+xdustinface@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: QuantumExplorer <quantum@dash.org> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: QuantumExplorer <11468583+QuantumExplorer@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Weekly automated refresh of the hardcoded masternode IP lists
embedded in
dash-spv(dash-network-seeds/seeds/mainnet.txt,dash-network-seeds/seeds/testnet.txt).Generated by
.github/workflows/update-masternode-seeds.ymlvia the
masternode-seeds-fetchercrate, which fetches thecurrent masternode list from the Dash P2P network using a
getmnlistdrequest against a peer discovered through DNSseeds and the existing seed files.