Skip to content

Commit

Permalink
Merge pull request #176 from dashpay/v0.8-dev
Browse files Browse the repository at this point in the history
v0.8-dev to master
  • Loading branch information
pauldelucia authored Jan 21, 2025
2 parents 590dccd + de6ec90 commit e86e838
Show file tree
Hide file tree
Showing 47 changed files with 3,593 additions and 3,557 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dash-evo-tool"
version = "0.7.1"
version = "0.8.0"
license = "MIT"
edition = "2021"
default-run = "dash-evo-tool"
Expand All @@ -25,7 +25,7 @@ strum = { version = "0.26.1", features = ["derive"] }
bs58 = "0.5.0"
base64 = "0.22.1"
copypasta = "0.10.1"
dash-sdk = { git = "https://github.com/dashpay/platform", rev = "8a000dfeb9c872c4bfedd8e8974ad1a9d2fdab78" }
dash-sdk = { git = "https://github.com/dashpay/platform", rev = "6a7016af671fcf1d1449e418b0e5aa5c943bde8d" }
thiserror = "1"
serde = "1.0.197"
serde_json = "1.0.120"
Expand Down
Binary file removed icons/withdraws.png
Binary file not shown.
104 changes: 74 additions & 30 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ use crate::database::Database;
use crate::logging::initialize_logger;
use crate::ui::contracts_documents::document_query_screen::DocumentQueryScreen;
use crate::ui::dpns::dpns_contested_names_screen::{
DPNSContestedNamesScreen, DPNSSubscreen, IndividualVoteCastingStatus,
DPNSScreen, DPNSSubscreen, ScheduledVoteCastingStatus,
};
use crate::ui::identities::identities_screen::IdentitiesScreen;
use crate::ui::network_chooser_screen::NetworkChooserScreen;
use crate::ui::tools::proof_log_screen::ProofLogScreen;
use crate::ui::tools::proof_visualizer_screen::ProofVisualizerScreen;
use crate::ui::tools::transition_visualizer_screen::TransitionVisualizerScreen;
use crate::ui::wallets::wallets_screen::WalletsBalancesScreen;
use crate::ui::withdrawal_statuses_screen::WithdrawsStatusScreen;
use crate::ui::{MessageType, RootScreenType, Screen, ScreenLike, ScreenType};
use dash_sdk::dpp::dashcore::Network;
use dash_sdk::dpp::identity::accessors::IdentityGettersV0;
Expand Down Expand Up @@ -72,13 +72,16 @@ pub enum DesiredAppAction {
SwitchNetwork(Network),
AddScreenType(ScreenType),
BackendTask(BackendTask),
BackendTasks(Vec<BackendTask>, BackendTasksExecutionMode),
Custom(String),
}

impl DesiredAppAction {
pub fn create_action(&self, app_context: &Arc<AppContext>) -> AppAction {
match self {
DesiredAppAction::None => AppAction::None,
DesiredAppAction::Refresh => AppAction::Refresh,
DesiredAppAction::Custom(message) => AppAction::Custom(message.clone()),
DesiredAppAction::PopScreen => AppAction::PopScreen,
DesiredAppAction::GoToMainScreen => AppAction::GoToMainScreen,
DesiredAppAction::AddScreenType(screen_type) => {
Expand All @@ -87,11 +90,20 @@ impl DesiredAppAction {
DesiredAppAction::BackendTask(backend_task) => {
AppAction::BackendTask(backend_task.clone())
}
DesiredAppAction::BackendTasks(tasks, mode) => {
AppAction::BackendTasks(tasks.clone(), mode.clone())
}
DesiredAppAction::SwitchNetwork(network) => AppAction::SwitchNetwork(*network),
}
}
}

#[derive(Debug, Clone, PartialEq)]
pub enum BackendTasksExecutionMode {
Sequential,
Concurrent,
}

#[derive(Debug, PartialEq)]
pub enum AppAction {
None,
Expand All @@ -105,6 +117,8 @@ pub enum AppAction {
AddScreen(Screen),
PopThenAddScreenToMainScreen(RootScreenType, Screen),
BackendTask(BackendTask),
BackendTasks(Vec<BackendTask>, BackendTasksExecutionMode),
Custom(String),
}

impl BitOrAssign for AppAction {
Expand Down Expand Up @@ -149,18 +163,18 @@ impl AppState {

let mut identities_screen = IdentitiesScreen::new(&mainnet_app_context);
let mut dpns_active_contests_screen =
DPNSContestedNamesScreen::new(&mainnet_app_context, DPNSSubscreen::Active);
DPNSScreen::new(&mainnet_app_context, DPNSSubscreen::Active);
let mut dpns_past_contests_screen =
DPNSContestedNamesScreen::new(&mainnet_app_context, DPNSSubscreen::Past);
DPNSScreen::new(&mainnet_app_context, DPNSSubscreen::Past);
let mut dpns_my_usernames_screen =
DPNSContestedNamesScreen::new(&mainnet_app_context, DPNSSubscreen::Owned);
DPNSScreen::new(&mainnet_app_context, DPNSSubscreen::Owned);
let mut dpns_scheduled_votes_screen =
DPNSContestedNamesScreen::new(&mainnet_app_context, DPNSSubscreen::ScheduledVotes);
DPNSScreen::new(&mainnet_app_context, DPNSSubscreen::ScheduledVotes);
let mut transition_visualizer_screen =
TransitionVisualizerScreen::new(&mainnet_app_context);
let mut proof_visualizer_screen = ProofVisualizerScreen::new(&mainnet_app_context);
let mut proof_log_screen = ProofLogScreen::new(&mainnet_app_context);
let mut document_query_screen = DocumentQueryScreen::new(&mainnet_app_context);
let mut withdraws_status_screen = WithdrawsStatusScreen::new(&mainnet_app_context);

let (custom_dash_qt_path, overwrite_dash_conf) = match settings.clone() {
Some((.., db_custom_dash_qt_path, db_overwrite_dash_qt)) => {
Expand All @@ -186,26 +200,24 @@ impl AppState {

let mut chosen_network = Network::Dash;

if let Some((network, screen_type, password_info, _, _)) = settings {
if let Some((network, screen_type, _, _, _)) = settings {
selected_main_screen = screen_type;
chosen_network = network;
if chosen_network == Network::Testnet && testnet_app_context.is_some() {
let testnet_app_context = testnet_app_context.as_ref().unwrap();
identities_screen = IdentitiesScreen::new(testnet_app_context);
dpns_active_contests_screen =
DPNSContestedNamesScreen::new(&testnet_app_context, DPNSSubscreen::Active);
DPNSScreen::new(&testnet_app_context, DPNSSubscreen::Active);
dpns_past_contests_screen =
DPNSContestedNamesScreen::new(&testnet_app_context, DPNSSubscreen::Past);
DPNSScreen::new(&testnet_app_context, DPNSSubscreen::Past);
dpns_my_usernames_screen =
DPNSContestedNamesScreen::new(&testnet_app_context, DPNSSubscreen::Owned);
dpns_scheduled_votes_screen = DPNSContestedNamesScreen::new(
&testnet_app_context,
DPNSSubscreen::ScheduledVotes,
);
DPNSScreen::new(&testnet_app_context, DPNSSubscreen::Owned);
dpns_scheduled_votes_screen =
DPNSScreen::new(&testnet_app_context, DPNSSubscreen::ScheduledVotes);
transition_visualizer_screen = TransitionVisualizerScreen::new(testnet_app_context);
proof_visualizer_screen = ProofVisualizerScreen::new(testnet_app_context);
document_query_screen = DocumentQueryScreen::new(testnet_app_context);
wallets_balances_screen = WalletsBalancesScreen::new(testnet_app_context);
withdraws_status_screen = WithdrawsStatusScreen::new(testnet_app_context);
proof_log_screen = ProofLogScreen::new(testnet_app_context);
}
network_chooser_screen.current_network = chosen_network;
Expand Down Expand Up @@ -249,19 +261,19 @@ impl AppState {
),
(
RootScreenType::RootScreenDPNSActiveContests,
Screen::DPNSContestedNamesScreen(dpns_active_contests_screen),
Screen::DPNSScreen(dpns_active_contests_screen),
),
(
RootScreenType::RootScreenDPNSPastContests,
Screen::DPNSContestedNamesScreen(dpns_past_contests_screen),
Screen::DPNSScreen(dpns_past_contests_screen),
),
(
RootScreenType::RootScreenDPNSOwnedNames,
Screen::DPNSContestedNamesScreen(dpns_my_usernames_screen),
Screen::DPNSScreen(dpns_my_usernames_screen),
),
(
RootScreenType::RootScreenDPNSScheduledVotes,
Screen::DPNSContestedNamesScreen(dpns_scheduled_votes_screen),
Screen::DPNSScreen(dpns_scheduled_votes_screen),
),
(
RootScreenType::RootScreenWalletsBalances,
Expand All @@ -271,6 +283,10 @@ impl AppState {
RootScreenType::RootScreenToolsTransitionVisualizerScreen,
Screen::TransitionVisualizerScreen(transition_visualizer_screen),
),
(
RootScreenType::RootScreenToolsProofVisualizerScreen,
Screen::ProofVisualizerScreen(proof_visualizer_screen),
),
(
RootScreenType::RootScreenToolsProofLogScreen,
Screen::ProofLogScreen(proof_log_screen),
Expand All @@ -279,10 +295,6 @@ impl AppState {
RootScreenType::RootScreenDocumentQuery,
Screen::DocumentQueryScreen(document_query_screen),
),
(
RootScreenType::RootScreenWithdrawsStatus,
Screen::WithdrawsStatusScreen(withdraws_status_screen),
),
(
RootScreenType::RootScreenNetworkChooser,
Screen::NetworkChooserScreen(network_chooser_screen),
Expand Down Expand Up @@ -329,6 +341,34 @@ impl AppState {
});
}

/// Handle the backend tasks and send the results through the channel
pub fn handle_backend_tasks(&self, tasks: Vec<BackendTask>, mode: BackendTasksExecutionMode) {
let sender = self.task_result_sender.clone();
let app_context = self.current_app_context().clone();

tokio::spawn(async move {
let results = match mode {
BackendTasksExecutionMode::Sequential => {
app_context
.run_backend_tasks_sequential(tasks, sender.clone())
.await
}
BackendTasksExecutionMode::Concurrent => {
app_context
.run_backend_tasks_concurrent(tasks, sender.clone())
.await
}
};

// Send the results back to the main thread
for result in results {
if let Err(e) = sender.send(result.into()).await {
eprintln!("Failed to send task result: {}", e);
}
}
});
}

pub fn active_root_screen(&self) -> &Screen {
self.main_screens
.get(&self.selected_main_screen)
Expand Down Expand Up @@ -441,6 +481,9 @@ impl App for AppState {
BackendTaskSuccessResult::SuccessfulVotes(_) => {
self.visible_screen_mut().refresh();
}
BackendTaskSuccessResult::DPNSVoteResults(_) => {
self.visible_screen_mut().display_task_result(message);
}
BackendTaskSuccessResult::CastScheduledVote(vote) => {
let _ = self
.current_app_context()
Expand All @@ -451,9 +494,6 @@ impl App for AppState {
);
self.visible_screen_mut().refresh();
}
BackendTaskSuccessResult::WithdrawalStatus(_) => {
self.visible_screen_mut().display_task_result(message);
}
BackendTaskSuccessResult::RegisteredIdentity(_) => {
self.visible_screen_mut().display_task_result(message);
}
Expand Down Expand Up @@ -569,15 +609,15 @@ impl App for AppState {
.main_screens
.get_mut(&RootScreenType::RootScreenDPNSScheduledVotes)
.unwrap();
if let Screen::DPNSContestedNamesScreen(screen) = dpns_screen {
screen.vote_cast_in_progress = true;
if let Screen::DPNSScreen(screen) = dpns_screen {
screen.scheduled_vote_cast_in_progress = true;
screen
.scheduled_votes
.lock()
.unwrap()
.iter_mut()
.find(|(v, _)| v == &vote)
.map(|(_, s)| *s = IndividualVoteCastingStatus::InProgress);
.map(|(_, s)| *s = ScheduledVoteCastingStatus::InProgress);
}
let task = BackendTask::ContestedResourceTask(
ContestedResourceTask::CastScheduledVote(vote, voter.clone()),
Expand Down Expand Up @@ -621,6 +661,9 @@ impl App for AppState {
AppAction::BackendTask(task) => {
self.handle_backend_task(task);
}
AppAction::BackendTasks(tasks, mode) => {
self.handle_backend_tasks(tasks, mode);
}
AppAction::SetMainScreen(root_screen_type) => {
self.selected_main_screen = root_screen_type;
self.active_root_screen_mut().refresh_on_arrival();
Expand Down Expand Up @@ -652,6 +695,7 @@ impl App for AppState {
.update_settings(root_screen_type)
.ok();
}
AppAction::Custom(_) => {}
}
}
}
41 changes: 35 additions & 6 deletions src/backend_task/contested_names/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ use crate::model::qualified_identity::QualifiedIdentity;
use dash_sdk::dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice;
use dash_sdk::platform::Identifier;
use dash_sdk::Sdk;
use futures::future::join_all;
use std::sync::Arc;
use tokio::sync::mpsc;

#[derive(Debug, Clone, PartialEq)]
pub(crate) enum ContestedResourceTask {
QueryDPNSContestedResources,
VoteOnDPNSName(String, ResourceVoteChoice, Vec<QualifiedIdentity>),
QueryDPNSContests,
VoteOnDPNSNames(Vec<(String, ResourceVoteChoice)>, Vec<QualifiedIdentity>),
ScheduleDPNSVotes(Vec<ScheduledDPNSVote>),
CastScheduledVote(ScheduledDPNSVote, QualifiedIdentity),
ClearAllScheduledVotes,
Expand All @@ -41,13 +42,41 @@ impl AppContext {
sender: mpsc::Sender<TaskResult>,
) -> Result<BackendTaskSuccessResult, String> {
match &task {
ContestedResourceTask::QueryDPNSContestedResources => self
ContestedResourceTask::QueryDPNSContests => self
.query_dpns_contested_resources(sdk, sender)
.await
.map(|_| BackendTaskSuccessResult::None),
ContestedResourceTask::VoteOnDPNSName(name, vote_choice, voters) => {
self.vote_on_dpns_name(name, *vote_choice, voters, sdk, sender)
.await
ContestedResourceTask::VoteOnDPNSNames(votes, all_voters) => {
// Create a vector of async closures that will vote on each name concurrently
let futures = votes
.into_iter()
.map(|(name, choice)| {
let cloned_sender = sender.clone();
let app_context = self.clone();

async move {
let result = app_context
.vote_on_dpns_name(&name, *choice, all_voters, sdk, cloned_sender)
.await;

(name, choice, result)
}
})
.collect::<Vec<_>>();

// Run all futures concurrently
let results = join_all(futures).await;

// Map them into (name, choice, Ok(())) or (name, choice, Err(String)) tuples
let final_results = results
.into_iter()
.map(|(name, choice, result)| match result {
Ok(_) => (name.clone(), choice.clone(), Ok(())),
Err(err_msg) => (name.clone(), choice.clone(), Err(err_msg)),
})
.collect::<Vec<_>>();

Ok(BackendTaskSuccessResult::DPNSVoteResults(final_results))
}
ContestedResourceTask::ScheduleDPNSVotes(scheduled_votes) => self
.insert_scheduled_votes(scheduled_votes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,15 @@ impl AppContext {

sender
.send(TaskResult::Success(BackendTaskSuccessResult::Message(
"Finished querying DPNS contested resources".to_string(),
"Successfully refreshed DPNS contests".to_string(),
)))
.await
.map_err(|e| format!("Finished querying DPNS contested resources but sender failed to send TaskResult: {}", e.to_string()))?;
.map_err(|e| {
format!(
"Successfully refreshed DPNS contests but sender failed to send TaskResult: {}",
e.to_string()
)
})?;
Ok(())
}
}
7 changes: 4 additions & 3 deletions src/backend_task/contested_names/vote_on_dpns_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ impl AppContext {
None,
)
.await
.map_err(|e| format!("Error voting: {}", e))?;
.map(|_| ())
.map_err(|e| format!("Error voting: {}", e));

strength += qualified_identity.identity_type.vote_strength();
vote_results.push(result);
vote_results.push((name.clone(), vote_choice, result));
} else {
return Err(format!(
"Error voting: No associated voter identity for qualified identity: {:?}",
Expand All @@ -98,6 +99,6 @@ impl AppContext {
)
.map_err(|e| format!("Error voting: Error updating vote count: {}", e))?;

Ok(BackendTaskSuccessResult::SuccessfulVotes(vote_results))
Ok(BackendTaskSuccessResult::DPNSVoteResults(vote_results))
}
}
2 changes: 1 addition & 1 deletion src/backend_task/identity/load_identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ impl AppContext {
.filter_map(|maybe_doc| {
maybe_doc.as_ref().and_then(|doc| {
let name = doc
.get("normalizedLabel")
.get("label")
.map(|label| label.to_str().unwrap_or_default());
let acquired_at = doc
.created_at()
Expand Down
2 changes: 1 addition & 1 deletion src/backend_task/identity/load_identity_from_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl AppContext {
.filter_map(|maybe_doc| {
maybe_doc.as_ref().and_then(|doc| {
let name = doc
.get("normalizedLabel")
.get("label")
.map(|label| label.to_str().unwrap_or_default());
let acquired_at = doc
.created_at()
Expand Down
Loading

0 comments on commit e86e838

Please sign in to comment.