Skip to content

feat: choose mn to vote with#8

Merged
QuantumExplorer merged 7 commits into
masterfrom
feat/chose-mn-to-vote-with
Oct 20, 2024
Merged

feat: choose mn to vote with#8
QuantumExplorer merged 7 commits into
masterfrom
feat/chose-mn-to-vote-with

Conversation

@pauldelucia
Copy link
Copy Markdown
Member

@pauldelucia pauldelucia commented Oct 18, 2024

When voting on dpns usernames, you can now select which mn to vote with, or select "all" to vote with all loaded mns.

Summary by CodeRabbit

  • New Features

    • Expanded voting functionality for contested names, allowing multiple qualified identities to participate in the voting process.
    • Enhanced user interface for voting, including a new "All" button for collective voting and improved feedback for voting actions.
    • Added new methods for retrieving local identities based on specific criteria.
  • Bug Fixes

    • Improved error handling for voter identities lacking associations.
  • Refactor

    • Renamed and updated methods to improve clarity and functionality in the voting process.
    • Updated data structures to better manage identities and their associated public keys.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 18, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The changes primarily involve updates to the DocumentQueryScreen and DPNSContestedNamesScreen to enhance the functionality related to voting and identity management. Key modifications include the addition of new parameters in various methods, updates to method signatures, and the introduction of new fields in the respective structs. The Cargo.toml file has also been updated to include a feature for the dash-sdk dependency. Overall, these changes improve the handling of contested names and voting processes within the application.

Changes

File Path Change Summary
src/ui/document_query_screen.rs Modified new, refresh, and show_contested_name_details methods to use all_contested_names(). Updated sort_contested_names to change ending_time to end_time.
src/ui/dpns_contested_names_screen.rs Added fields voting_identities and user_identities. Renamed show_vote_popup to show_vote_popup_info. Updated methods to utilize new fields and improved error handling for loading contested names.
Cargo.toml Updated dash-sdk dependency to include the tokio-sleep feature.
src/app.rs Expanded update method to handle new BackendTaskSuccessResult::SuccessfulVotes(_) case and modified handling for BackendTaskSuccessResult::None.
src/context.rs Removed load_contested_names method, added all_contested_names and ongoing_contested_names methods.
src/database/contested_names.rs Renamed get_contested_names to get_all_contested_names, added get_ongoing_contested_names, and updated SQL queries and logic for contest state handling.
src/database/identities.rs Modified get_local_qualified_identities to select only the data column and added methods to retrieve local voting and user identities.
src/database/initialization.rs Updated database schema for contested_name and contestant tables, including new constraints and indexes.
src/logging.rs Enhanced error handling for logger initialization and adjusted logging levels to reduce verbosity.
src/model/contested_name.rs Introduced ContestState enum and updated ContestedName struct to include a new state field.
src/model/qualified_identity.rs Added Evonode variant to IdentityType enum and methods for displaying identity information.
src/platform/contested_names/mod.rs Updated ContestedResourceTask::VoteOnDPNSName to include Vec<QualifiedIdentity> and modified return type of run_contested_resource_task.
src/platform/contested_names/vote_on_dpns_name.rs Updated vote_on_dpns_name method to accept Vec<QualifiedIdentity> and enhanced internal logic for processing votes.
src/platform/mod.rs Added SuccessfulVotes(Vec<Vote>) variant to BackendTaskSuccessResult enum and refined control flow in run_backend_task.
src/ui/identities/add_existing_identity_screen.rs Made identity_type field public and simplified display_message logic.
src/ui/identities/register_dpns_name_screen.rs Updated fields to hold tuples of QualifiedIdentity and Vec<IdentityPublicKey>, enhancing identity management.
src/ui/mod.rs Added refresh_on_arrival method to ScreenLike trait and updated display_task_result method to automatically display success messages.

Possibly related PRs

Poem

In a meadow where bunnies play,
Voting's now a brighter day!
With identities, we hop and cheer,
For every vote, our voices clear.
So gather round, let's make it right,
Together we’ll vote, with all our might! 🐰✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (9)
src/platform/contested_names/vote_on_dpns_name.rs (2)

23-25: LGTM: Method signature updated to include voters parameter

The addition of the voters: Vec<QualifiedIdentity> parameter aligns with the PR objective of allowing users to select specific masternodes for voting. This change enhances the flexibility of the voting process.

However, I noticed that the sender parameter has been renamed to _sender, indicating it's no longer used in the method body. Consider removing this parameter if it's truly unused to keep the method signature clean.

Would you like me to propose a modification to remove the unused _sender parameter?


Line range hint 37-74: LGTM: Method implementation updated to use provided voters

The changes in the method body correctly implement the new functionality of using the provided voters parameter. The iteration over voters, creation of votes, and submission to the platform are well-structured and align with the PR objective.

The error handling for cases where a voter doesn't have an associated voter identity is a good practice and enhances the robustness of the code.

One minor suggestion:

Consider adding a comment explaining the purpose of the hardcoded values for DPNS at lines 37-38. This would improve code readability and maintainability.

+ // Hardcoded values for DPNS: "dash" is the parent domain, and `name` is the subdomain being voted on
let index_values = [Value::from("dash"), Value::Text(name.clone())];
src/platform/contested_names/mod.rs (1)

36-38: LGTM: Updated match arm for VoteOnDPNSName

The match arm for VoteOnDPNSName has been correctly updated to handle the new Vec<QualifiedIdentity> parameter. This change is consistent with the enum variant update and aligns with the PR objectives.

Consider removing the .to_vec() call if voters is already a Vec<QualifiedIdentity>:

- self.vote_on_dpns_name(name, *vote_choice, voters.to_vec(), sdk, sender)
+ self.vote_on_dpns_name(name, *vote_choice, voters.clone(), sdk, sender)

This avoids creating an unnecessary new vector if voters is already owned. If voters needs to be a slice or other iterable type, then the current implementation is correct.

src/ui/dpns_contested_names_screen.rs (6)

159-165: Simplify filtering of voting identities

You can simplify the filtering of voting_identities by using .filter() instead of filter_map(). This enhances code readability and conciseness.

Apply this diff to simplify the filter:

-let voting_identities = local_qualified_identities
-    .iter()
-    .filter_map(|id| {
-        if id.associated_voter_identity.is_some() {
-            Some(id)
-        } else {
-            None
-        }
-    })
-    .collect_vec();
+let voting_identities = local_qualified_identities
+    .iter()
+    .filter(|id| id.associated_voter_identity.is_some())
+    .collect_vec();

179-183: Avoid unnecessary cloning when constructing button labels

When constructing the button label, cloning identity.alias is unnecessary. You can use as_ref() to borrow the value, avoiding the clone.

Apply this diff to optimize the code:

 let button_label = format!(
     "{}",
     identity
-        .alias
-        .clone()
+        .alias
+        .as_ref()
         .unwrap_or(identity.identity.id().to_string(Encoding::Base58))
 );

185-186: Remove redundant cloning of identity

On line 186, identity.clone().clone() is redundant. A single clone() is sufficient.

Apply this diff to correct the cloning:

 if ui.button(button_label).clicked() {
     // Add the selected identity to the `voters` field
-    voters.push(identity.clone().clone());
+    voters.push(identity.clone());

206-207: Eliminate redundant cloning in 'All' button logic

In the "All" button logic, identity.clone().clone() is used unnecessarily. One clone() call is enough.

Apply this diff to streamline the cloning:

 for identity in voting_identities.iter() {
-    voters.push(identity.clone().clone());
+    voters.push(identity.clone());
 }

169-174: Consider borrowing action instead of cloning

Cloning action in the if let pattern may be unnecessary if you can borrow it instead. This can improve performance by avoiding unnecessary copies.

Here's how you might modify the code:

-if let ContestedResourceTask::VoteOnDPNSName(
-    contested_name,
-    vote_choice,
-    mut voters,
-) = action
+if let ContestedResourceTask::VoteOnDPNSName(
+    ref contested_name,
+    ref vote_choice,
+    ref mut voters,
+) = &mut action

Adjust the rest of the code within the block accordingly to work with references.


Line range hint 405-417: Maintain consistent messaging in vote confirmation popups

Ensure that the messages in your vote confirmation popups are clear and consistent. This enhances the user experience by providing clear instructions.

Review the messages at lines 405 and 417 to confirm they align with the application's messaging standards.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 601d405 and ff42fe0.

📒 Files selected for processing (4)
  • src/platform/contested_names/mod.rs (3 hunks)
  • src/platform/contested_names/vote_on_dpns_name.rs (3 hunks)
  • src/ui/document_query_screen.rs (1 hunks)
  • src/ui/dpns_contested_names_screen.rs (8 hunks)
🧰 Additional context used
🔇 Additional comments (7)
src/platform/contested_names/vote_on_dpns_name.rs (2)

3-3: LGTM: Import statement added for QualifiedIdentity

The addition of the import statement for QualifiedIdentity is consistent with the changes in the method signature and implementation. This import is necessary for the new voters parameter.


Line range hint 1-78: LGTM: Successfully implemented voting with selected masternodes

The changes in this file successfully implement the feature of allowing users to select specific masternodes for voting on DPNS usernames. The modifications are well-structured, consistent with the PR objectives, and maintain good code quality. Here's a summary of the key changes:

  1. Added a new voters parameter to the vote_on_dpns_name method.
  2. Updated the method implementation to iterate over the provided voters.
  3. Implemented vote creation and submission for each valid voter.
  4. Added appropriate error handling for invalid voters.

These changes enhance the flexibility of the voting process while maintaining code clarity and robustness.

src/platform/contested_names/mod.rs (3)

8-8: LGTM: Import added for QualifiedIdentity

The import for QualifiedIdentity is correctly added and is necessary for the updated enum variant.


Line range hint 1-38: Overall: Implementation aligns with PR objectives

The changes in this file successfully implement the feature to allow users to select specific masternodes or "all" when voting on DPNS usernames. The code is well-structured and consistent with the existing codebase. The main changes include:

  1. Adding an import for QualifiedIdentity.
  2. Updating the VoteOnDPNSName variant in the ContestedResourceTask enum.
  3. Modifying the corresponding match arm in the run_contested_resource_task method.

These changes effectively support the new functionality while maintaining code quality. A minor optimization suggestion was made regarding vector creation, but overall, the implementation is sound and meets the PR objectives.


18-18: LGTM: Updated VoteOnDPNSName variant to include multiple voters

The VoteOnDPNSName variant has been correctly updated to include a Vec<QualifiedIdentity>, allowing for multiple voters. This change aligns with the PR objectives and enables the selection of specific masternodes or "all" for voting.

To ensure consistency across the codebase, please run the following script to check for any locations that might need updates due to this change:

Please review the output and ensure that all occurrences of VoteOnDPNSName are updated to include the new Vec<QualifiedIdentity> parameter.

✅ Verification successful

Verified: All VoteOnDPNSName usages correctly include Vec<QualifiedIdentity>

The verification confirms that every instance of VoteOnDPNSName has been updated to include the Vec<QualifiedIdentity> parameter. No additional changes are required.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usages of VoteOnDPNSName that might need updates

# Search for VoteOnDPNSName usage
echo "Searching for VoteOnDPNSName usage:"
rg --type rust "VoteOnDPNSName\s*\(" -C 3

# Search for pattern matching on VoteOnDPNSName
echo "\nSearching for pattern matching on VoteOnDPNSName:"
rg --type rust "VoteOnDPNSName\s*\([^)]+\)" -C 3

Length of output: 9693

src/ui/dpns_contested_names_screen.rs (2)

308-308: Ensure vote popup is properly displayed

At line 308, you check if self.show_vote_popup_info.is_some(). Ensure that this condition correctly reflects when the vote popup should be displayed, especially after updates to show_vote_popup_info.


81-88: Ensure correct contestant ID is used when voting

When setting ResourceVoteChoice::TowardsIdentity(contestant.id), confirm that contestant.id is the correct identity for voting. This ensures votes are attributed accurately.

You can run the following script to verify the contestant IDs:

This script extracts contestant IDs from the code and lists them to help you verify their correctness.

ContestedResourceTask::VoteOnDPNSName(
contested_name.normalized_contested_name.clone(),
ResourceVoteChoice::Abstain,
vec![],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Masternode selection UI is not implemented.

The addition of vec![] as the third parameter to ContestedResourceTask::VoteOnDPNSName suggests that masternode selection functionality is intended. However, no UI components for selecting masternodes were found in the codebase. This may result in users being unable to select specific masternodes for voting as intended.

  • Implement the UI for masternode selection to enable users to choose specific masternodes.
  • Ensure that the selection process populates the vector passed to VoteOnDPNSName.
🔗 Analysis chain

Verify the implementation of masternode selection for voting.

The addition of vec![] as the third parameter to ContestedResourceTask::VoteOnDPNSName aligns with the PR objective of allowing users to select specific masternodes for voting. However, there are a few points to consider:

  1. The empty vector suggests that no masternodes are selected by default. Is this the intended behavior?
  2. There's no visible UI element in this file for selecting masternodes. Ensure that the masternode selection is implemented correctly in the relevant UI component.

Consider the following improvements:

  • If a default selection is desired, populate the vector with appropriate default values.
  • Add a comment explaining the purpose of this parameter for better code readability.
  • Verify that the masternode selection UI is properly integrated with this voting action.

To ensure the feature is fully implemented, let's check for the presence of masternode selection UI and its integration:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for UI components related to masternode selection
rg --type rust "fn.*select.*masternode" src
# Check for updates to the ContestedResourceTask enum
rg --type rust "enum ContestedResourceTask" src
# Verify the usage of VoteOnDPNSName with the new parameter
rg --type rust "VoteOnDPNSName.*vec!" src

Length of output: 999

Comment thread src/ui/dpns_contested_names_screen.rs Outdated
Comment on lines +147 to +230
if let Some((message, action)) = self.show_vote_popup_info.clone() {
ui.label(message);

let local_qualified_identities = self
.app_context
.db
.get_local_qualified_identities(&self.app_context)
.unwrap_or_default();

let voting_identities = local_qualified_identities
.iter()
.filter_map(|id| {
if id.associated_voter_identity.is_some() {
Some(id)
} else {
None
}
})
.collect_vec();

ui.horizontal(|ui| {
if ui.button("Vote Immediate").clicked() {
app_action = AppAction::BackendTask(BackendTask::ContestedResourceTask(action));
self.show_vote_popup = None;
} else if ui.button("Vote Deferred").clicked() {
app_action = AppAction::BackendTask(BackendTask::ContestedResourceTask(action));
self.show_vote_popup = None;
} else if ui.button("Cancel").clicked() {
self.show_vote_popup = None;
// Only modify `voters` if `action` is `VoteOnDPNSName`
if let ContestedResourceTask::VoteOnDPNSName(
contested_name,
vote_choice,
mut voters,
) = action
{
// Iterate over the voting identities and create a button for each one
for identity in voting_identities.iter() {
let button_label = format!(
"{}",
identity
.alias
.clone()
.unwrap_or(identity.identity.id().to_string(Encoding::Base58))
);
if ui.button(button_label).clicked() {
// Add the selected identity to the `voters` field
voters.push(identity.clone().clone());

// Create a new `VoteOnDPNSName` task with updated voters
let updated_action = ContestedResourceTask::VoteOnDPNSName(
contested_name.clone(),
vote_choice.clone(),
voters.clone(), // Updated voters
);

// Pass updated action to BackendTask
app_action = AppAction::BackendTask(
BackendTask::ContestedResourceTask(updated_action),
);
self.show_vote_popup_info = None;
}
}

// Vote with all identities
if ui.button("All").clicked() {
for identity in voting_identities.iter() {
voters.push(identity.clone().clone());
}

// Create a new `VoteOnDPNSName` task with all voters
let updated_action = ContestedResourceTask::VoteOnDPNSName(
contested_name.clone(),
vote_choice.clone(),
voters.clone(), // Updated voters
);

// Pass updated action to BackendTask
app_action = AppAction::BackendTask(BackendTask::ContestedResourceTask(
updated_action,
));
self.show_vote_popup_info = None;
}
}

// Add the "Cancel" button
if ui.button("Cancel").clicked() {
self.show_vote_popup_info = None;
}
});
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Check for empty voting identities and handle accordingly

If voting_identities is empty, the UI will not display any buttons for the user to select an identity, potentially causing confusion.

Consider adding a message to inform the user when no voting identities are available:

if voting_identities.is_empty() {
    ui.label("No voting identities available to vote with.");
} else {
    // Existing code to display voting buttons
}

Comment thread src/ui/dpns_contested_names_screen.rs Outdated
Comment on lines +150 to +155
let local_qualified_identities = self
.app_context
.db
.get_local_qualified_identities(&self.app_context)
.unwrap_or_default();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle potential errors when fetching local qualified identities

Currently, errors from get_local_qualified_identities are ignored with unwrap_or_default(), which may mask underlying issues. Consider handling the Result properly to ensure robustness.

Here's a suggested change:

 let local_qualified_identities = self
     .app_context
     .db
     .get_local_qualified_identities(&self.app_context)
-    .unwrap_or_default();
+    .unwrap_or_else(|err| {
+        // Handle the error, e.g., log it or display a message
+        eprintln!("Error fetching identities: {:?}", err);
+        Vec::new()
+    });

You might also consider displaying an error message to the user if fetching identities fails.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let local_qualified_identities = self
.app_context
.db
.get_local_qualified_identities(&self.app_context)
.unwrap_or_default();
let local_qualified_identities = self
.app_context
.db
.get_local_qualified_identities(&self.app_context)
.unwrap_or_else(|err| {
// Handle the error, e.g., log it or display a message
eprintln!("Error fetching identities: {:?}", err);
Vec::new()
});

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
src/platform/contested_names/vote_on_dpns_name.rs (2)

22-26: Approve signature change and suggest removing unused parameter

The updated method signature correctly includes the new voters parameter, which aligns with the PR objective of allowing users to select specific masternodes for voting.

However, the _sender parameter appears to be unused (prefixed with an underscore). Consider removing this parameter if it's no longer needed in the function body.

 pub(super) async fn vote_on_dpns_name(
     self: &Arc<Self>,
     name: &String,
     vote_choice: ResourceVoteChoice,
     voters: Vec<QualifiedIdentity>,
     sdk: Sdk,
-    _sender: mpsc::Sender<TaskResult>,
 ) -> Result<(), String> {

Line range hint 27-77: Consider refactoring for improved code organization

While the code is well-structured and follows consistent conventions, the vote_on_dpns_name function is quite long and handles multiple responsibilities. Consider refactoring it into smaller, more focused functions to improve readability and maintainability. For example:

  1. Extract the DPNS contract and document type fetching logic into a separate function.
  2. Create a helper function for creating and submitting a vote for a single qualified identity.

This refactoring would make the main function more concise and easier to understand at a glance.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between ff42fe0 and 1823522.

📒 Files selected for processing (1)
  • src/platform/contested_names/vote_on_dpns_name.rs (3 hunks)
🧰 Additional context used
🔇 Additional comments (3)
src/platform/contested_names/vote_on_dpns_name.rs (3)

3-3: LGTM: New import for QualifiedIdentity

The new import for QualifiedIdentity is correctly added and necessary for the updated method signature.


Line range hint 48-74: LGTM: Implementation changes for voting with selected masternodes

The updated implementation correctly iterates over the provided voters, allowing for more flexible voting as per the PR objectives. The error handling for missing associated voter identities is appropriate and provides a clear error message. The code is well-structured and includes helpful comments explaining the purpose of different sections.


68-72: LGTM: Improved error handling for missing voter identities

The new error handling for cases where a qualified identity doesn't have an associated voter identity is well-implemented. The error message is clear and includes the identity ID, which will be helpful for debugging.

@QuantumExplorer QuantumExplorer merged commit babefae into master Oct 20, 2024
@QuantumExplorer QuantumExplorer deleted the feat/chose-mn-to-vote-with branch October 20, 2024 17:05
@coderabbitai coderabbitai Bot mentioned this pull request Oct 23, 2024
thepastaclaw added a commit to thepastaclaw/dash-evo-tool that referenced this pull request Feb 17, 2026
1. CRITICAL: Fix BitOrAssign dropping tasks in fetch_unresolved_profiles()
   - Changed from action |= AppAction::BackendTask(task) loop (which only
     kept the last task) to collecting all tasks into a Vec and dispatching
     via AppAction::BackendTasks with Concurrent execution mode.

2. HIGH: Remove dummy [0x02; 33] pubkey in load_payment_history()
   - Changed PaymentRecord.to_address from Address to Option<Address>
   - Historical records loaded from DB now use None instead of generating
     a fake-but-valid P2PKH address from a dummy public key.

3. HIGH: Fix i64 as u64 wrapping for amounts (payments.rs and dashpay.rs)
   - Added bounds checking with warning logs for negative amounts,
     clamping to 0 instead of silently wrapping.

4. MEDIUM: Eliminate duplicate payment history logic in dashpay.rs
   - LoadPaymentHistory task handler now calls the shared
     payments::load_payment_history() and converts results, instead of
     reimplementing the same logic with different return types.

5. MEDIUM: Fix N+1 database queries in resolve_names_from_local_cache()
   - Pre-load all contacts once before the loop and build a HashMap
     for O(1) lookups instead of calling load_dashpay_contacts() and
     load_dashpay_profile() per request inside the loop.

6. MEDIUM: Fix created_at: None breaking filters in contacts_list.rs
   - Contacts from DashPayContactsWithInfo results now get current
     timestamp as fallback instead of None, so they work with
     'Recent' filter and 'Date added' sort.

7. LOW: Fix 'failed' as failure reason in payment status
   - Changed PaymentStatus::Failed to use descriptive 'Transaction failed'
     string instead of echoing the literal status column value 'failed'.

8. LOW: Fix i64 as u64 for timestamps in payments.rs
   - Added bounds checking with warning for negative timestamps,
     consistent with the amount fix.

9. LOW: Both i64 as u64 locations fixed (dashpay.rs duplicate removed
   entirely by fix dashpay#4, payments.rs fixed by fixes dashpay#3/dashpay#8).
shumkov added a commit that referenced this pull request Apr 13, 2026
HIGH #6: Add tracing::warn to 7 silent identity_id decode continues.
  All `Err(_) => continue` in load() now log before skipping. Matches
  the existing pattern for account_type/txid decode failures.

HIGH #7: payment_type/status catch-all masks corruption.
  Unknown payment_type no longer defaults to Received — skips row
  with tracing::warn. Unknown status no longer defaults to Pending —
  same treatment. Explicitly matches "pending"/"sent"/"received"/
  "confirmed"/"failed".

HIGH #8: created_at type mismatch (write i64, load u64).
  Load now reads as Option<i64> (matching the write cast), clamps
  negative values to 0 via .max(0), converts explicitly to u64.

HIGH #9: Proof decode failure silently degrades asset lock status.
  When proof_data was present but decode failed AND no legacy
  fallback columns (islock_data, chain_height) exist, skip the
  entire row with tracing::error instead of loading a degraded
  entry with Broadcast status.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants