refactor(lite): remove dead parallel refresh/readiness scaffolding (~3.1k lines)

The lite-wallet tree carried a second, unused refresh+readiness architecture
that never reached the shipping binary — exactly the churn CLAUDE.md warns
against. The live refresh path is controller -> gateway.refresh ->
mapLiteWalletRefreshResult -> applyLiteRefreshModelToWalletState; this parallel
stack was dead weight.

Verified unused (their public types/functions are referenced only within the
cluster), then deleted (8 files / 16 incl. headers):
- lite_wallet_refresh_service            (LiteWalletRefreshService + gateway adapters)
- lite_wallet_app_refresh_coordinator
- lite_wallet_app_refresh_orchestrator
- lite_wallet_refresh_readiness_policy
- lite_wallet_state_apply_plan
- lite_wallet_state_apply_executor
- lite_wallet_sync_app_refresh_integration
- lite_wallet_sync_execution_readiness

Severed three thin couplings into the cluster from live files:
- state_mapper: dropped the dead mapLiteWalletRefreshServiceResult and switched
  its include from refresh_service.h to gateway.h (where the live
  LiteWalletRefreshResult/Bundle DTOs actually live).
- server_lifecycle_readiness: dropped the unused syncLifecycleInput member +
  converter and the sync_app_refresh_integration include.
- artifact_resolver: relocated the three LIVE artifact-input structs
  (LiteWalletSdxlArtifact{Symbols,}Input, LiteWalletLinkedBackendReadinessInput)
  out of sync_execution_readiness.h — their only real consumers — into
  artifact_resolver.h, then dropped the include.

Also removed the dead DRAGONX_LONG_LITE_BATCH CMake machinery (its source var
was empty; on Windows it generated a broken lite_batch90_receipt_plan.cpp that
#included an empty path) and the stale .cpp/.h entries in CMakeLists.

Lite source files: 44 -> 30. Lite + full-node configure, both targets build,
test suite passes, source-hygiene clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 12:25:02 -05:00
parent 6a4e98b7ed
commit 6611d57147
22 changed files with 33 additions and 3141 deletions

View File

@@ -377,26 +377,6 @@ set(QRCODE_SOURCES
# Application Sources # Application Sources
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# MinGW writes .obj.d dependency files, so this overlong generated source name
# needs a short wrapper to stay under the Windows filename component limit.
set(DRAGONX_LONG_LITE_BATCH_SOURCE
)
set(DRAGONX_LONG_LITE_BATCH_COMPILE_SOURCE ${DRAGONX_LONG_LITE_BATCH_SOURCE})
if(WIN32)
set(DRAGONX_LONG_LITE_BATCH_COMPILE_SOURCE
${CMAKE_BINARY_DIR}/generated/short_sources/lite_batch90_receipt_plan.cpp
)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/generated/short_sources)
file(WRITE ${DRAGONX_LONG_LITE_BATCH_COMPILE_SOURCE}
"#include \"${CMAKE_SOURCE_DIR}/${DRAGONX_LONG_LITE_BATCH_SOURCE}\"\n"
)
set_source_files_properties(${DRAGONX_LONG_LITE_BATCH_COMPILE_SOURCE}
PROPERTIES
GENERATED TRUE
OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/${DRAGONX_LONG_LITE_BATCH_SOURCE}
)
endif()
set(APP_SOURCES set(APP_SOURCES
src/main.cpp src/main.cpp
src/app.cpp src/app.cpp
@@ -418,17 +398,8 @@ set(APP_SOURCES
src/wallet/lite_result_parsers.cpp src/wallet/lite_result_parsers.cpp
src/wallet/lite_sync_service.cpp src/wallet/lite_sync_service.cpp
src/wallet/lite_wallet_gateway.cpp src/wallet/lite_wallet_gateway.cpp
src/wallet/lite_wallet_refresh_service.cpp
src/wallet/lite_wallet_state_mapper.cpp src/wallet/lite_wallet_state_mapper.cpp
src/wallet/lite_wallet_state_apply_plan.cpp
src/wallet/lite_wallet_state_apply_executor.cpp
src/wallet/lite_wallet_app_refresh_coordinator.cpp
src/wallet/lite_wallet_refresh_readiness_policy.cpp
src/wallet/lite_wallet_app_refresh_orchestrator.cpp
src/wallet/lite_wallet_sync_app_refresh_integration.cpp
src/wallet/lite_wallet_sync_execution_readiness.cpp
src/wallet/lite_wallet_lifecycle_ui_adapter.cpp src/wallet/lite_wallet_lifecycle_ui_adapter.cpp
${DRAGONX_LONG_LITE_BATCH_COMPILE_SOURCE}
src/wallet/lite_wallet_server_selection_adapter.cpp src/wallet/lite_wallet_server_selection_adapter.cpp
src/wallet/lite_wallet_server_lifecycle_readiness.cpp src/wallet/lite_wallet_server_lifecycle_readiness.cpp
src/wallet/lite_wallet_lifecycle_service.cpp src/wallet/lite_wallet_lifecycle_service.cpp
@@ -542,15 +513,7 @@ set(APP_HEADERS
src/wallet/lite_result_parsers.h src/wallet/lite_result_parsers.h
src/wallet/lite_sync_service.h src/wallet/lite_sync_service.h
src/wallet/lite_wallet_gateway.h src/wallet/lite_wallet_gateway.h
src/wallet/lite_wallet_refresh_service.h
src/wallet/lite_wallet_state_mapper.h src/wallet/lite_wallet_state_mapper.h
src/wallet/lite_wallet_state_apply_plan.h
src/wallet/lite_wallet_state_apply_executor.h
src/wallet/lite_wallet_app_refresh_coordinator.h
src/wallet/lite_wallet_refresh_readiness_policy.h
src/wallet/lite_wallet_app_refresh_orchestrator.h
src/wallet/lite_wallet_sync_app_refresh_integration.h
src/wallet/lite_wallet_sync_execution_readiness.h
src/wallet/lite_wallet_lifecycle_ui_adapter.h src/wallet/lite_wallet_lifecycle_ui_adapter.h
src/wallet/lite_wallet_server_selection_adapter.h src/wallet/lite_wallet_server_selection_adapter.h
src/wallet/lite_wallet_server_lifecycle_readiness.h src/wallet/lite_wallet_server_lifecycle_readiness.h
@@ -985,17 +948,8 @@ if(BUILD_TESTING)
src/wallet/lite_result_parsers.cpp src/wallet/lite_result_parsers.cpp
src/wallet/lite_sync_service.cpp src/wallet/lite_sync_service.cpp
src/wallet/lite_wallet_gateway.cpp src/wallet/lite_wallet_gateway.cpp
src/wallet/lite_wallet_refresh_service.cpp
src/wallet/lite_wallet_state_mapper.cpp src/wallet/lite_wallet_state_mapper.cpp
src/wallet/lite_wallet_state_apply_plan.cpp
src/wallet/lite_wallet_state_apply_executor.cpp
src/wallet/lite_wallet_app_refresh_coordinator.cpp
src/wallet/lite_wallet_refresh_readiness_policy.cpp
src/wallet/lite_wallet_app_refresh_orchestrator.cpp
src/wallet/lite_wallet_sync_app_refresh_integration.cpp
src/wallet/lite_wallet_sync_execution_readiness.cpp
src/wallet/lite_wallet_lifecycle_ui_adapter.cpp src/wallet/lite_wallet_lifecycle_ui_adapter.cpp
${DRAGONX_LONG_LITE_BATCH_COMPILE_SOURCE}
src/wallet/lite_wallet_server_selection_adapter.cpp src/wallet/lite_wallet_server_selection_adapter.cpp
src/wallet/lite_wallet_server_lifecycle_readiness.cpp src/wallet/lite_wallet_server_lifecycle_readiness.cpp
src/wallet/lite_wallet_lifecycle_service.cpp src/wallet/lite_wallet_lifecycle_service.cpp

View File

@@ -1,7 +1,6 @@
#pragma once #pragma once
#include "lite_connection_service.h" #include "lite_connection_service.h" // pulls wallet_backend.h (WalletBackendStatus)
#include "lite_wallet_sync_execution_readiness.h"
#include <cstddef> #include <cstddef>
#include <string> #include <string>
@@ -9,6 +8,37 @@
namespace dragonx::wallet { namespace dragonx::wallet {
// Validated-artifact inputs for the linked-backend resolver/contract. (Previously these lived in
// lite_wallet_sync_execution_readiness.h alongside a parallel, unused sync-readiness planner;
// they were relocated here — their only live home — when that scaffolding was removed.)
struct LiteWalletSdxlArtifactSymbolsInput {
bool walletExists = false;
bool initializeNew = false;
bool initializeNewFromPhrase = false;
bool initializeExisting = false;
bool execute = false;
bool freeString = false;
bool checkServerOnline = false;
bool shutdown = false;
};
struct LiteWalletSdxlArtifactInput {
bool pathConfigured = false;
bool exists = false;
bool readable = false;
bool sdxlCompatible = false;
std::string artifactPath;
std::string versionLabel;
LiteWalletSdxlArtifactSymbolsInput symbols;
};
struct LiteWalletLinkedBackendReadinessInput {
bool linked = false;
bool bridgeAvailable = false;
WalletBackendStatus status;
std::string bridgeUnavailableReason;
};
enum class LiteBackendArtifactPlatform { enum class LiteBackendArtifactPlatform {
Current, Current,
Linux, Linux,

View File

@@ -1,172 +0,0 @@
#include "wallet/lite_wallet_app_refresh_coordinator.h"
#include <utility>
namespace dragonx::wallet {
namespace {
void addIssue(LiteWalletAppRefreshCoordinationResult& result,
LiteWalletAppRefreshCoordinationIssue issue,
std::string message)
{
result.issues.push_back(LiteWalletAppRefreshCoordinationIssueInfo{issue, std::move(message)});
}
std::string refreshFailureMessage(const LiteWalletRefreshServiceResult& refreshResult)
{
if (!refreshResult.error.empty()) return refreshResult.error;
if (!refreshResult.status.message.empty()) return refreshResult.status.message;
return "lite wallet refresh service result is not successful";
}
void copyExecutionSummary(LiteWalletAppRefreshCoordinationResult& result)
{
result.stateMutationRequested = result.executionResult.stateMutationRequested;
result.stateMutationAllowed = result.applyPlan.stateMutationAllowed ||
result.executionResult.stateMutationAllowed;
result.stateMutated = result.executionResult.stateMutated;
result.walletStateWritten = result.stateMutated;
result.dryRunOnly = result.applyPlan.dryRunOnly && result.executionResult.dryRunOnly;
result.noNetwork = result.executionResult.noNetwork;
result.fieldPlanCount = result.executionResult.fieldPlanCount;
result.collectionPlanCount = result.executionResult.collectionPlanCount;
result.plannedChangeCount = result.executionResult.plannedChangeCount;
result.planIssueCount = result.executionResult.planIssueCount;
result.executionIssueCount = result.executionResult.issues.size();
}
} // namespace
const char* liteWalletAppRefreshCoordinationStatusName(
LiteWalletAppRefreshCoordinationStatus status)
{
switch (status) {
case LiteWalletAppRefreshCoordinationStatus::DryRunReported: return "DryRunReported";
case LiteWalletAppRefreshCoordinationStatus::Rejected: return "Rejected";
case LiteWalletAppRefreshCoordinationStatus::ApplyUnavailable: return "ApplyUnavailable";
}
return "Unknown";
}
const char* liteWalletAppRefreshCoordinationIssueName(
LiteWalletAppRefreshCoordinationIssue issue)
{
switch (issue) {
case LiteWalletAppRefreshCoordinationIssue::RefreshResultFailed: return "RefreshResultFailed";
case LiteWalletAppRefreshCoordinationIssue::FullNodeRefreshDelegated: return "FullNodeRefreshDelegated";
case LiteWalletAppRefreshCoordinationIssue::MappingFailed: return "MappingFailed";
case LiteWalletAppRefreshCoordinationIssue::ApplyPlanFailed: return "ApplyPlanFailed";
case LiteWalletAppRefreshCoordinationIssue::ApplyExecutionRejected: return "ApplyExecutionRejected";
case LiteWalletAppRefreshCoordinationIssue::StateMutationDisabled: return "StateMutationDisabled";
case LiteWalletAppRefreshCoordinationIssue::StateMutationImplementationMissing: return "StateMutationImplementationMissing";
}
return "Unknown";
}
LiteWalletAppRefreshCoordinationResult coordinateLiteWalletAppRefresh(
const LiteWalletRefreshServiceResult& refreshResult,
const dragonx::WalletState& walletState,
LiteWalletAppRefreshCoordinatorOptions options)
{
LiteWalletAppRefreshCoordinationResult result;
result.route = refreshResult.plan.route;
result.refreshStatus = refreshResult.status;
result.refreshAttempted = refreshResult.attempted;
result.fullNodeRefreshDelegated = refreshResult.fullNodeRefreshDelegated;
result.liteGatewayCalled = refreshResult.liteGatewayCalled;
result.stateMutationRequested = options.executorOptions.requestStateMutation;
if (refreshResult.fullNodeRefreshDelegated) {
addIssue(result,
LiteWalletAppRefreshCoordinationIssue::FullNodeRefreshDelegated,
"full-node refresh remains delegated; lite app refresh coordinator did not run");
result.error = result.issues.back().message;
return result;
}
if (!refreshResult.ok) {
addIssue(result,
LiteWalletAppRefreshCoordinationIssue::RefreshResultFailed,
refreshFailureMessage(refreshResult));
result.error = result.issues.back().message;
return result;
}
result.refreshAccepted = true;
result.mapResult = mapLiteWalletRefreshServiceResult(refreshResult);
result.mapIssueCount = result.mapResult.issues.size();
if (!result.mapResult.ok) {
addIssue(result,
LiteWalletAppRefreshCoordinationIssue::MappingFailed,
result.mapResult.error.empty()
? "lite wallet refresh service result could not be mapped"
: result.mapResult.error);
result.error = result.issues.back().message;
return result;
}
result.mapped = true;
result.successfulCommandCount = result.mapResult.model.successfulCommandCount;
result.applyPlan = planLiteWalletStateApply(result.mapResult.model, walletState);
if (!result.applyPlan.ok) {
result.fieldPlanCount = result.applyPlan.fieldPlans.size();
result.collectionPlanCount = result.applyPlan.collectionPlans.size();
result.planIssueCount = result.applyPlan.issues.size();
addIssue(result,
LiteWalletAppRefreshCoordinationIssue::ApplyPlanFailed,
result.applyPlan.error.empty()
? "lite WalletState apply plan could not be built"
: result.applyPlan.error);
result.error = result.issues.back().message;
return result;
}
result.planned = true;
LiteWalletStateApplyExecutor executor(options.executorOptions);
result.executionResult = executor.execute(result.applyPlan);
result.executionReported = true;
copyExecutionSummary(result);
if (!result.executionResult.ok) {
result.error = result.executionResult.error;
if (result.executionResult.status == LiteWalletStateApplyExecutionStatus::ImplementationMissing) {
result.status = LiteWalletAppRefreshCoordinationStatus::ApplyUnavailable;
addIssue(result,
LiteWalletAppRefreshCoordinationIssue::StateMutationImplementationMissing,
result.executionResult.error.empty()
? "real lite WalletState application requires a future explicit implementation"
: result.executionResult.error);
} else {
result.status = LiteWalletAppRefreshCoordinationStatus::Rejected;
addIssue(result,
LiteWalletAppRefreshCoordinationIssue::ApplyExecutionRejected,
result.executionResult.error.empty()
? "lite WalletState apply execution report was rejected"
: result.executionResult.error);
}
if (result.error.empty()) result.error = result.issues.back().message;
return result;
}
result.ok = true;
result.status = LiteWalletAppRefreshCoordinationStatus::DryRunReported;
addIssue(result,
LiteWalletAppRefreshCoordinationIssue::StateMutationDisabled,
"lite app refresh coordinator produced a dry-run report only; WalletState was not written");
return result;
}
LiteWalletAppRefreshCoordinator::LiteWalletAppRefreshCoordinator(
LiteWalletAppRefreshCoordinatorOptions options)
: options_(options)
{
}
LiteWalletAppRefreshCoordinationResult LiteWalletAppRefreshCoordinator::coordinate(
const LiteWalletRefreshServiceResult& refreshResult,
const dragonx::WalletState& walletState) const
{
return coordinateLiteWalletAppRefresh(refreshResult, walletState, options_);
}
} // namespace dragonx::wallet

View File

@@ -1,96 +0,0 @@
#pragma once
#include "data/wallet_state.h"
#include "lite_wallet_refresh_service.h"
#include "lite_wallet_state_apply_executor.h"
#include "lite_wallet_state_mapper.h"
#include <cstddef>
#include <string>
#include <vector>
namespace dragonx::wallet {
enum class LiteWalletAppRefreshCoordinationStatus {
DryRunReported,
Rejected,
ApplyUnavailable,
};
enum class LiteWalletAppRefreshCoordinationIssue {
RefreshResultFailed,
FullNodeRefreshDelegated,
MappingFailed,
ApplyPlanFailed,
ApplyExecutionRejected,
StateMutationDisabled,
StateMutationImplementationMissing,
};
struct LiteWalletAppRefreshCoordinatorOptions {
LiteWalletStateApplyExecutorOptions executorOptions;
};
struct LiteWalletAppRefreshCoordinationIssueInfo {
LiteWalletAppRefreshCoordinationIssue issue = LiteWalletAppRefreshCoordinationIssue::StateMutationDisabled;
std::string message;
};
struct LiteWalletAppRefreshCoordinationResult {
bool ok = false;
bool refreshAccepted = false;
bool refreshAttempted = false;
bool fullNodeRefreshDelegated = false;
bool liteGatewayCalled = false;
bool mapped = false;
bool planned = false;
bool executionReported = false;
bool dryRunOnly = true;
bool noNetwork = true;
bool stateMutationRequested = false;
bool stateMutationAllowed = false;
bool stateMutated = false;
bool walletStateWritten = false;
LiteWalletAppRefreshCoordinationStatus status = LiteWalletAppRefreshCoordinationStatus::Rejected;
LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
WalletBackendStatus refreshStatus;
std::size_t successfulCommandCount = 0;
std::size_t mapIssueCount = 0;
std::size_t fieldPlanCount = 0;
std::size_t collectionPlanCount = 0;
std::size_t plannedChangeCount = 0;
std::size_t planIssueCount = 0;
std::size_t executionIssueCount = 0;
LiteWalletStateMapResult mapResult;
LiteWalletStateApplyPlan applyPlan;
LiteWalletStateApplyExecutionResult executionResult;
std::vector<LiteWalletAppRefreshCoordinationIssueInfo> issues;
std::string error;
};
const char* liteWalletAppRefreshCoordinationStatusName(
LiteWalletAppRefreshCoordinationStatus status);
const char* liteWalletAppRefreshCoordinationIssueName(
LiteWalletAppRefreshCoordinationIssue issue);
LiteWalletAppRefreshCoordinationResult coordinateLiteWalletAppRefresh(
const LiteWalletRefreshServiceResult& refreshResult,
const dragonx::WalletState& walletState,
LiteWalletAppRefreshCoordinatorOptions options = {});
class LiteWalletAppRefreshCoordinator {
public:
explicit LiteWalletAppRefreshCoordinator(LiteWalletAppRefreshCoordinatorOptions options = {});
LiteWalletAppRefreshCoordinationResult coordinate(
const LiteWalletRefreshServiceResult& refreshResult,
const dragonx::WalletState& walletState) const;
private:
LiteWalletAppRefreshCoordinatorOptions options_;
};
} // namespace dragonx::wallet

View File

@@ -1,197 +0,0 @@
#include "wallet/lite_wallet_app_refresh_orchestrator.h"
#include <utility>
namespace dragonx::wallet {
namespace {
void addIssue(LiteWalletAppRefreshOrchestrationResult& result,
LiteWalletAppRefreshOrchestrationIssue issue,
std::string message)
{
result.issues.push_back(LiteWalletAppRefreshOrchestrationIssueInfo{issue, std::move(message)});
}
bool readinessReportIsUnsafe(const LiteWalletRefreshReadinessResult& readiness)
{
return !readiness.dryRunOnly ||
!readiness.noNetwork ||
readiness.stateMutationRequested ||
readiness.stateMutationAllowed ||
readiness.stateMutated ||
readiness.walletStateWritten;
}
std::string readinessErrorOrDefault(const LiteWalletRefreshReadinessResult& readiness)
{
return readiness.error.empty()
? "lite refresh readiness report is not eligible"
: readiness.error;
}
LiteWalletAppRefreshOrchestrationResult blockedResult(
LiteWalletAppRefreshOrchestrationResult result,
LiteWalletAppRefreshOrchestrationIssue issue,
std::string message)
{
result.status = LiteWalletAppRefreshOrchestrationStatus::Blocked;
result.blocked = true;
addIssue(result, issue, std::move(message));
result.error = result.issues.back().message;
return result;
}
LiteWalletAppRefreshOrchestrationResult skippedResult(
LiteWalletAppRefreshOrchestrationResult result,
LiteWalletAppRefreshOrchestrationIssue issue,
std::string message)
{
result.ok = true;
result.status = LiteWalletAppRefreshOrchestrationStatus::Skipped;
result.skipped = true;
addIssue(result, issue, std::move(message));
return result;
}
std::size_t effectiveMaxQueueDepth(const LiteWalletAppRefreshScheduleInput& schedule,
const LiteWalletAppRefreshOrchestratorOptions& options)
{
return schedule.maxQueueDepth > 0 ? schedule.maxQueueDepth : options.maxQueueDepth;
}
} // namespace
const char* liteWalletAppRefreshOrchestrationStatusName(
LiteWalletAppRefreshOrchestrationStatus status)
{
switch (status) {
case LiteWalletAppRefreshOrchestrationStatus::Queued: return "Queued";
case LiteWalletAppRefreshOrchestrationStatus::Skipped: return "Skipped";
case LiteWalletAppRefreshOrchestrationStatus::Blocked: return "Blocked";
}
return "Unknown";
}
const char* liteWalletAppRefreshScheduleTriggerName(
LiteWalletAppRefreshScheduleTrigger trigger)
{
switch (trigger) {
case LiteWalletAppRefreshScheduleTrigger::Periodic: return "Periodic";
case LiteWalletAppRefreshScheduleTrigger::Manual: return "Manual";
case LiteWalletAppRefreshScheduleTrigger::Startup: return "Startup";
case LiteWalletAppRefreshScheduleTrigger::WalletOpened: return "WalletOpened";
}
return "Unknown";
}
const char* liteWalletAppRefreshOrchestrationIssueName(
LiteWalletAppRefreshOrchestrationIssue issue)
{
switch (issue) {
case LiteWalletAppRefreshOrchestrationIssue::ReadinessRejected: return "ReadinessRejected";
case LiteWalletAppRefreshOrchestrationIssue::UnsafeReadinessReport: return "UnsafeReadinessReport";
case LiteWalletAppRefreshOrchestrationIssue::SchedulerDisabled: return "SchedulerDisabled";
case LiteWalletAppRefreshOrchestrationIssue::RefreshNotDue: return "RefreshNotDue";
case LiteWalletAppRefreshOrchestrationIssue::RefreshAlreadyQueued: return "RefreshAlreadyQueued";
case LiteWalletAppRefreshOrchestrationIssue::RefreshInProgress: return "RefreshInProgress";
case LiteWalletAppRefreshOrchestrationIssue::QueuePressure: return "QueuePressure";
}
return "Unknown";
}
LiteWalletAppRefreshOrchestrationResult orchestrateLiteWalletAppRefresh(
const LiteWalletRefreshReadinessResult& readiness,
const LiteWalletAppRefreshScheduleInput& schedule,
LiteWalletAppRefreshOrchestratorOptions options)
{
LiteWalletAppRefreshOrchestrationResult result;
result.readinessResult = readiness;
result.route = readiness.route;
result.dryRunOnly = readiness.dryRunOnly;
result.noNetwork = readiness.noNetwork;
result.stateMutationRequested = readiness.stateMutationRequested;
result.stateMutationAllowed = readiness.stateMutationAllowed;
result.stateMutated = readiness.stateMutated;
result.walletStateWritten = readiness.walletStateWritten;
result.trigger = schedule.trigger;
result.schedulerEnabled = schedule.schedulerEnabled;
result.refreshDue = schedule.refreshDue;
result.forceRefresh = schedule.forceRefresh;
result.refreshAlreadyQueued = schedule.refreshAlreadyQueued;
result.refreshInProgress = schedule.refreshInProgress;
result.queueDepth = schedule.queueDepth;
result.maxQueueDepth = effectiveMaxQueueDepth(schedule, options);
if (options.requireEligibleReadiness && (!readiness.ok || !readiness.eligibleForFutureUiRefresh)) {
return blockedResult(
std::move(result),
LiteWalletAppRefreshOrchestrationIssue::ReadinessRejected,
readinessErrorOrDefault(readiness));
}
if (readinessReportIsUnsafe(readiness)) {
return blockedResult(
std::move(result),
LiteWalletAppRefreshOrchestrationIssue::UnsafeReadinessReport,
"lite refresh readiness report is not a no-network dry-run report");
}
result.readinessAccepted = true;
if (!schedule.schedulerEnabled) {
return blockedResult(
std::move(result),
LiteWalletAppRefreshOrchestrationIssue::SchedulerDisabled,
"lite app refresh scheduler is disabled");
}
result.schedulerAccepted = true;
if (result.maxQueueDepth > 0 && schedule.queueDepth >= result.maxQueueDepth) {
return blockedResult(
std::move(result),
LiteWalletAppRefreshOrchestrationIssue::QueuePressure,
"lite app refresh queue is at capacity");
}
if (schedule.refreshAlreadyQueued) {
return skippedResult(
std::move(result),
LiteWalletAppRefreshOrchestrationIssue::RefreshAlreadyQueued,
"lite app refresh is already queued");
}
if (schedule.refreshInProgress) {
return skippedResult(
std::move(result),
LiteWalletAppRefreshOrchestrationIssue::RefreshInProgress,
"lite app refresh is already in progress");
}
if (!schedule.refreshDue && !schedule.forceRefresh) {
return skippedResult(
std::move(result),
LiteWalletAppRefreshOrchestrationIssue::RefreshNotDue,
"lite app refresh is not due");
}
result.ok = true;
result.status = LiteWalletAppRefreshOrchestrationStatus::Queued;
result.wouldQueueRefresh = true;
return result;
}
LiteWalletAppRefreshOrchestrator::LiteWalletAppRefreshOrchestrator(
LiteWalletAppRefreshOrchestratorOptions options)
: options_(options)
{
}
LiteWalletAppRefreshOrchestrationResult LiteWalletAppRefreshOrchestrator::evaluate(
const LiteWalletRefreshReadinessResult& readiness,
const LiteWalletAppRefreshScheduleInput& schedule) const
{
return orchestrateLiteWalletAppRefresh(readiness, schedule, options_);
}
} // namespace dragonx::wallet

View File

@@ -1,109 +0,0 @@
#pragma once
#include "lite_wallet_refresh_readiness_policy.h"
#include <cstddef>
#include <string>
#include <vector>
namespace dragonx::wallet {
enum class LiteWalletAppRefreshOrchestrationStatus {
Queued,
Skipped,
Blocked,
};
enum class LiteWalletAppRefreshScheduleTrigger {
Periodic,
Manual,
Startup,
WalletOpened,
};
enum class LiteWalletAppRefreshOrchestrationIssue {
ReadinessRejected,
UnsafeReadinessReport,
SchedulerDisabled,
RefreshNotDue,
RefreshAlreadyQueued,
RefreshInProgress,
QueuePressure,
};
struct LiteWalletAppRefreshScheduleInput {
LiteWalletAppRefreshScheduleTrigger trigger = LiteWalletAppRefreshScheduleTrigger::Periodic;
bool schedulerEnabled = true;
bool refreshDue = false;
bool forceRefresh = false;
bool refreshAlreadyQueued = false;
bool refreshInProgress = false;
std::size_t queueDepth = 0;
std::size_t maxQueueDepth = 0;
};
struct LiteWalletAppRefreshOrchestratorOptions {
bool requireEligibleReadiness = true;
std::size_t maxQueueDepth = 0;
};
struct LiteWalletAppRefreshOrchestrationIssueInfo {
LiteWalletAppRefreshOrchestrationIssue issue = LiteWalletAppRefreshOrchestrationIssue::ReadinessRejected;
std::string message;
};
struct LiteWalletAppRefreshOrchestrationResult {
bool ok = false;
bool wouldQueueRefresh = false;
bool skipped = false;
bool blocked = false;
bool readinessAccepted = false;
bool schedulerAccepted = false;
bool dryRunOnly = true;
bool noNetwork = true;
bool stateMutationRequested = false;
bool stateMutationAllowed = false;
bool stateMutated = false;
bool walletStateWritten = false;
bool schedulerEnabled = true;
bool refreshDue = false;
bool forceRefresh = false;
bool refreshAlreadyQueued = false;
bool refreshInProgress = false;
std::size_t queueDepth = 0;
std::size_t maxQueueDepth = 0;
LiteWalletAppRefreshOrchestrationStatus status = LiteWalletAppRefreshOrchestrationStatus::Blocked;
LiteWalletAppRefreshScheduleTrigger trigger = LiteWalletAppRefreshScheduleTrigger::Periodic;
LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
LiteWalletRefreshReadinessResult readinessResult;
std::vector<LiteWalletAppRefreshOrchestrationIssueInfo> issues;
std::string error;
};
const char* liteWalletAppRefreshOrchestrationStatusName(
LiteWalletAppRefreshOrchestrationStatus status);
const char* liteWalletAppRefreshScheduleTriggerName(
LiteWalletAppRefreshScheduleTrigger trigger);
const char* liteWalletAppRefreshOrchestrationIssueName(
LiteWalletAppRefreshOrchestrationIssue issue);
LiteWalletAppRefreshOrchestrationResult orchestrateLiteWalletAppRefresh(
const LiteWalletRefreshReadinessResult& readiness,
const LiteWalletAppRefreshScheduleInput& schedule,
LiteWalletAppRefreshOrchestratorOptions options = {});
class LiteWalletAppRefreshOrchestrator {
public:
explicit LiteWalletAppRefreshOrchestrator(LiteWalletAppRefreshOrchestratorOptions options = {});
LiteWalletAppRefreshOrchestrationResult evaluate(
const LiteWalletRefreshReadinessResult& readiness,
const LiteWalletAppRefreshScheduleInput& schedule) const;
private:
LiteWalletAppRefreshOrchestratorOptions options_;
};
} // namespace dragonx::wallet

View File

@@ -1,205 +0,0 @@
#include "wallet/lite_wallet_refresh_readiness_policy.h"
#include <utility>
namespace dragonx::wallet {
namespace {
void addIssue(LiteWalletRefreshReadinessResult& result,
LiteWalletRefreshReadinessIssue issue,
std::string message)
{
result.issues.push_back(LiteWalletRefreshReadinessIssueInfo{issue, std::move(message)});
}
std::string statusMessageOrDefault(const WalletBackendStatus& status,
const std::string& fallback)
{
return status.message.empty() ? fallback : status.message;
}
LiteWalletRefreshReadinessResult failReadiness(
LiteWalletRefreshReadinessResult result,
LiteWalletRefreshReadinessStatus status,
LiteWalletRefreshReadinessIssue issue,
std::string message)
{
result.status = status;
addIssue(result, issue, std::move(message));
result.error = result.issues.back().message;
return result;
}
bool coordinatorReportIsUnsafe(const LiteWalletAppRefreshCoordinationResult& coordination)
{
return !coordination.dryRunOnly ||
!coordination.noNetwork ||
coordination.stateMutationRequested ||
coordination.stateMutationAllowed ||
coordination.stateMutated ||
coordination.walletStateWritten;
}
} // namespace
const char* liteWalletRefreshReadinessStatusName(LiteWalletRefreshReadinessStatus status)
{
switch (status) {
case LiteWalletRefreshReadinessStatus::EligibleDryRun: return "EligibleDryRun";
case LiteWalletRefreshReadinessStatus::CoordinatorRejected: return "CoordinatorRejected";
case LiteWalletRefreshReadinessStatus::UnsafeReport: return "UnsafeReport";
case LiteWalletRefreshReadinessStatus::WaitingForLifecycle: return "WaitingForLifecycle";
case LiteWalletRefreshReadinessStatus::WaitingForSync: return "WaitingForSync";
case LiteWalletRefreshReadinessStatus::Stale: return "Stale";
}
return "Unknown";
}
const char* liteWalletRefreshReadinessIssueName(LiteWalletRefreshReadinessIssue issue)
{
switch (issue) {
case LiteWalletRefreshReadinessIssue::CoordinatorReportRejected: return "CoordinatorReportRejected";
case LiteWalletRefreshReadinessIssue::CoordinatorReportIncomplete: return "CoordinatorReportIncomplete";
case LiteWalletRefreshReadinessIssue::CoordinatorReportUnsafe: return "CoordinatorReportUnsafe";
case LiteWalletRefreshReadinessIssue::FullNodeRouteRejected: return "FullNodeRouteRejected";
case LiteWalletRefreshReadinessIssue::LifecycleNotReady: return "LifecycleNotReady";
case LiteWalletRefreshReadinessIssue::SyncNotReady: return "SyncNotReady";
case LiteWalletRefreshReadinessIssue::RefreshTimestampMissing: return "RefreshTimestampMissing";
case LiteWalletRefreshReadinessIssue::RefreshTimestampInFuture: return "RefreshTimestampInFuture";
case LiteWalletRefreshReadinessIssue::RefreshStale: return "RefreshStale";
case LiteWalletRefreshReadinessIssue::StaleRefreshAllowed: return "StaleRefreshAllowed";
}
return "Unknown";
}
LiteWalletRefreshReadinessResult evaluateLiteWalletRefreshReadiness(
const LiteWalletAppRefreshCoordinationResult& coordination,
const LiteWalletRefreshReadinessInputs& inputs,
LiteWalletRefreshReadinessPolicyOptions options)
{
LiteWalletRefreshReadinessResult result;
result.route = coordination.route;
result.dryRunOnly = coordination.dryRunOnly;
result.noNetwork = coordination.noNetwork;
result.stateMutationRequested = coordination.stateMutationRequested;
result.stateMutationAllowed = coordination.stateMutationAllowed;
result.stateMutated = coordination.stateMutated;
result.walletStateWritten = coordination.walletStateWritten;
result.lifecycleReady = inputs.lifecycleReady;
result.lifecycleStatus = inputs.lifecycleStatus;
result.syncReady = inputs.syncReady;
result.syncStatus = inputs.syncStatus;
result.maxRefreshAgeSeconds = options.maxRefreshAgeSeconds;
if (coordination.fullNodeRefreshDelegated || coordination.route == LiteWalletRefreshRouteKind::FullNodeRpc) {
return failReadiness(
std::move(result),
LiteWalletRefreshReadinessStatus::CoordinatorRejected,
LiteWalletRefreshReadinessIssue::FullNodeRouteRejected,
"full-node refresh reports are not eligible for lite UI refresh readiness");
}
if (!coordination.ok) {
return failReadiness(
std::move(result),
LiteWalletRefreshReadinessStatus::CoordinatorRejected,
LiteWalletRefreshReadinessIssue::CoordinatorReportRejected,
coordination.error.empty()
? "lite app refresh coordinator report is not successful"
: coordination.error);
}
result.coordinatorReportAccepted = true;
if (!coordination.mapped || !coordination.planned || !coordination.executionReported ||
coordination.successfulCommandCount == 0) {
return failReadiness(
std::move(result),
LiteWalletRefreshReadinessStatus::CoordinatorRejected,
LiteWalletRefreshReadinessIssue::CoordinatorReportIncomplete,
"lite app refresh coordinator report is incomplete");
}
if (coordinatorReportIsUnsafe(coordination)) {
return failReadiness(
std::move(result),
LiteWalletRefreshReadinessStatus::UnsafeReport,
LiteWalletRefreshReadinessIssue::CoordinatorReportUnsafe,
"lite app refresh coordinator report is not a no-network dry-run report");
}
if (options.requireLifecycleReady && !inputs.lifecycleReady) {
return failReadiness(
std::move(result),
LiteWalletRefreshReadinessStatus::WaitingForLifecycle,
LiteWalletRefreshReadinessIssue::LifecycleNotReady,
statusMessageOrDefault(inputs.lifecycleStatus, "lite wallet lifecycle is not ready"));
}
if (options.requireSyncReady && !inputs.syncReady) {
return failReadiness(
std::move(result),
LiteWalletRefreshReadinessStatus::WaitingForSync,
LiteWalletRefreshReadinessIssue::SyncNotReady,
statusMessageOrDefault(inputs.syncStatus, "lite wallet sync is not ready"));
}
if (options.requireFreshRefresh) {
if (!inputs.freshness.haveSnapshotTime) {
return failReadiness(
std::move(result),
LiteWalletRefreshReadinessStatus::Stale,
LiteWalletRefreshReadinessIssue::RefreshTimestampMissing,
"lite refresh snapshot time is not known");
}
if (inputs.freshness.snapshotTimeSeconds > inputs.freshness.nowSeconds) {
return failReadiness(
std::move(result),
LiteWalletRefreshReadinessStatus::Stale,
LiteWalletRefreshReadinessIssue::RefreshTimestampInFuture,
"lite refresh snapshot time is in the future");
}
result.refreshAgeSeconds = inputs.freshness.nowSeconds - inputs.freshness.snapshotTimeSeconds;
if (result.refreshAgeSeconds > options.maxRefreshAgeSeconds) {
result.refreshStale = true;
if (!options.allowStaleRefresh) {
return failReadiness(
std::move(result),
LiteWalletRefreshReadinessStatus::Stale,
LiteWalletRefreshReadinessIssue::RefreshStale,
"lite refresh coordinator report is stale");
}
result.staleRefreshAllowed = true;
addIssue(result,
LiteWalletRefreshReadinessIssue::StaleRefreshAllowed,
"stale lite refresh coordinator report is allowed for reporting only");
} else {
result.refreshFresh = true;
}
} else {
result.refreshFresh = true;
}
result.ok = true;
result.eligibleForFutureUiRefresh = true;
result.status = LiteWalletRefreshReadinessStatus::EligibleDryRun;
return result;
}
LiteWalletRefreshReadinessPolicy::LiteWalletRefreshReadinessPolicy(
LiteWalletRefreshReadinessPolicyOptions options)
: options_(options)
{
}
LiteWalletRefreshReadinessResult LiteWalletRefreshReadinessPolicy::evaluate(
const LiteWalletAppRefreshCoordinationResult& coordination,
const LiteWalletRefreshReadinessInputs& inputs) const
{
return evaluateLiteWalletRefreshReadiness(coordination, inputs, options_);
}
} // namespace dragonx::wallet

View File

@@ -1,106 +0,0 @@
#pragma once
#include "lite_wallet_app_refresh_coordinator.h"
#include <cstdint>
#include <string>
#include <vector>
namespace dragonx::wallet {
enum class LiteWalletRefreshReadinessStatus {
EligibleDryRun,
CoordinatorRejected,
UnsafeReport,
WaitingForLifecycle,
WaitingForSync,
Stale,
};
enum class LiteWalletRefreshReadinessIssue {
CoordinatorReportRejected,
CoordinatorReportIncomplete,
CoordinatorReportUnsafe,
FullNodeRouteRejected,
LifecycleNotReady,
SyncNotReady,
RefreshTimestampMissing,
RefreshTimestampInFuture,
RefreshStale,
StaleRefreshAllowed,
};
struct LiteWalletRefreshFreshnessInput {
bool haveSnapshotTime = false;
std::uint64_t snapshotTimeSeconds = 0;
std::uint64_t nowSeconds = 0;
};
struct LiteWalletRefreshReadinessInputs {
bool lifecycleReady = false;
WalletBackendStatus lifecycleStatus;
bool syncReady = false;
WalletBackendStatus syncStatus;
LiteWalletRefreshFreshnessInput freshness;
};
struct LiteWalletRefreshReadinessPolicyOptions {
bool requireLifecycleReady = true;
bool requireSyncReady = true;
bool requireFreshRefresh = true;
bool allowStaleRefresh = false;
std::uint64_t maxRefreshAgeSeconds = 120;
};
struct LiteWalletRefreshReadinessIssueInfo {
LiteWalletRefreshReadinessIssue issue = LiteWalletRefreshReadinessIssue::CoordinatorReportRejected;
std::string message;
};
struct LiteWalletRefreshReadinessResult {
bool ok = false;
bool eligibleForFutureUiRefresh = false;
bool coordinatorReportAccepted = false;
bool dryRunOnly = true;
bool noNetwork = true;
bool stateMutationRequested = false;
bool stateMutationAllowed = false;
bool stateMutated = false;
bool walletStateWritten = false;
bool lifecycleReady = false;
bool syncReady = false;
bool refreshFresh = false;
bool refreshStale = false;
bool staleRefreshAllowed = false;
LiteWalletRefreshReadinessStatus status = LiteWalletRefreshReadinessStatus::CoordinatorRejected;
LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
WalletBackendStatus lifecycleStatus;
WalletBackendStatus syncStatus;
std::uint64_t refreshAgeSeconds = 0;
std::uint64_t maxRefreshAgeSeconds = 0;
std::vector<LiteWalletRefreshReadinessIssueInfo> issues;
std::string error;
};
const char* liteWalletRefreshReadinessStatusName(LiteWalletRefreshReadinessStatus status);
const char* liteWalletRefreshReadinessIssueName(LiteWalletRefreshReadinessIssue issue);
LiteWalletRefreshReadinessResult evaluateLiteWalletRefreshReadiness(
const LiteWalletAppRefreshCoordinationResult& coordination,
const LiteWalletRefreshReadinessInputs& inputs,
LiteWalletRefreshReadinessPolicyOptions options = {});
class LiteWalletRefreshReadinessPolicy {
public:
explicit LiteWalletRefreshReadinessPolicy(LiteWalletRefreshReadinessPolicyOptions options = {});
LiteWalletRefreshReadinessResult evaluate(
const LiteWalletAppRefreshCoordinationResult& coordination,
const LiteWalletRefreshReadinessInputs& inputs) const;
private:
LiteWalletRefreshReadinessPolicyOptions options_;
};
} // namespace dragonx::wallet

View File

@@ -1,189 +0,0 @@
#include "wallet/lite_wallet_refresh_service.h"
#include <utility>
namespace dragonx::wallet {
namespace {
WalletBackendStatus makeRefreshStatus(WalletBackendState state, std::string message)
{
WalletBackendStatus status;
status.state = state;
status.message = std::move(message);
return status;
}
} // namespace
LiteWalletGatewayRefreshAdapter::LiteWalletGatewayRefreshAdapter(LiteWalletGateway& gateway)
: gateway_(gateway)
{
}
LiteWalletRefreshPlan LiteWalletGatewayRefreshAdapter::planRefresh(
const LiteWalletRefreshRequest& request) const
{
return gateway_.planRefresh(request);
}
LiteWalletRefreshResult LiteWalletGatewayRefreshAdapter::refresh(
const LiteWalletRefreshRequest& request)
{
return gateway_.refresh(request);
}
WalletBackendStatus LiteWalletGatewayRefreshAdapter::status() const
{
return gateway_.status();
}
const char* liteWalletRefreshRouteKindName(LiteWalletRefreshRouteKind route)
{
switch (route) {
case LiteWalletRefreshRouteKind::FullNodeRpc: return "FullNodeRpc";
case LiteWalletRefreshRouteKind::LiteGateway: return "LiteGateway";
case LiteWalletRefreshRouteKind::Unavailable: return "Unavailable";
}
return "Unknown";
}
LiteWalletRefreshRouteKind liteWalletRefreshRouteForCapabilities(const WalletCapabilities& capabilities)
{
if (capabilities.fullNodeRpcAvailable) return LiteWalletRefreshRouteKind::FullNodeRpc;
if (isLiteBuild(capabilities) && supportsLiteBackend(capabilities)) {
return LiteWalletRefreshRouteKind::LiteGateway;
}
return LiteWalletRefreshRouteKind::Unavailable;
}
LiteWalletRefreshService::LiteWalletRefreshService(WalletCapabilities capabilities,
LiteWalletRefreshGateway* liteGateway,
LiteWalletRefreshServiceOptions options)
: capabilities_(capabilities), liteGateway_(liteGateway), options_(options)
{
}
LiteWalletRefreshRouteKind LiteWalletRefreshService::route() const
{
return liteWalletRefreshRouteForCapabilities(capabilities_);
}
WalletBackendStatus LiteWalletRefreshService::status() const
{
const auto selectedRoute = route();
if (selectedRoute == LiteWalletRefreshRouteKind::LiteGateway) {
if (!liteGateway_) return statusForRoute(selectedRoute, "lite wallet gateway is not configured");
return liteGateway_->status();
}
return statusForRoute(selectedRoute);
}
LiteWalletRefreshServicePlan LiteWalletRefreshService::planRefresh(
const LiteWalletRefreshRequest& request) const
{
LiteWalletRefreshServicePlan plan;
plan.route = route();
if (plan.route == LiteWalletRefreshRouteKind::FullNodeRpc) {
plan.ok = true;
plan.fullNodeRefreshDelegated = true;
plan.status = statusForRoute(plan.route);
return plan;
}
if (plan.route == LiteWalletRefreshRouteKind::Unavailable) {
plan.status = statusForRoute(plan.route);
plan.error = plan.status.message;
return plan;
}
if (!liteGateway_) {
plan.status = statusForRoute(plan.route, "lite wallet gateway is not configured");
plan.error = plan.status.message;
return plan;
}
plan.liteGatewayConfigured = true;
plan.liteGatewayExecutionAllowed = options_.allowLiteGatewayRefresh;
plan.liteGatewayPlan = liteGateway_->planRefresh(request);
if (!plan.liteGatewayPlan.ok) {
plan.status = makeRefreshStatus(WalletBackendState::Error, plan.liteGatewayPlan.error);
plan.error = plan.status.message;
return plan;
}
plan.ok = true;
plan.status = liteGateway_->status();
return plan;
}
LiteWalletRefreshServiceResult LiteWalletRefreshService::refresh(
const LiteWalletRefreshRequest& request)
{
auto plan = planRefresh(request);
if (!plan.ok) return resultFromPlan(plan);
if (plan.route == LiteWalletRefreshRouteKind::FullNodeRpc) {
auto result = resultFromPlan(plan);
result.ok = true;
return result;
}
if (!plan.liteGatewayExecutionAllowed) {
plan.status = makeRefreshStatus(
WalletBackendState::Unavailable,
"lite wallet refresh gateway execution is disabled");
plan.error = plan.status.message;
return resultFromPlan(plan);
}
LiteWalletRefreshServiceResult result;
result.plan = plan;
result.liteGatewayCalled = true;
result.liteGatewayResult = liteGateway_->refresh(request);
result.attempted = result.liteGatewayResult.attempted;
result.bundle = result.liteGatewayResult.bundle;
result.status = result.liteGatewayResult.status;
result.error = result.liteGatewayResult.error;
result.ok = result.liteGatewayResult.ok;
return result;
}
WalletBackendStatus LiteWalletRefreshService::statusForRoute(
LiteWalletRefreshRouteKind selectedRoute,
const std::string& detail) const
{
switch (selectedRoute) {
case LiteWalletRefreshRouteKind::FullNodeRpc:
return makeRefreshStatus(
WalletBackendState::Disconnected,
detail.empty()
? "full-node refresh remains handled by existing NetworkRefreshService"
: detail);
case LiteWalletRefreshRouteKind::LiteGateway:
return makeRefreshStatus(
detail.empty() ? WalletBackendState::Disconnected : WalletBackendState::Unavailable,
detail.empty()
? "lite wallet refresh route is ready for gateway planning"
: detail);
case LiteWalletRefreshRouteKind::Unavailable:
return makeRefreshStatus(
WalletBackendState::Unavailable,
detail.empty() ? "lite backend is not linked" : detail);
}
return makeRefreshStatus(WalletBackendState::Unavailable, "unknown wallet refresh route");
}
LiteWalletRefreshServiceResult LiteWalletRefreshService::resultFromPlan(
const LiteWalletRefreshServicePlan& plan) const
{
LiteWalletRefreshServiceResult result;
result.plan = plan;
result.fullNodeRefreshDelegated = plan.fullNodeRefreshDelegated;
result.status = plan.status;
result.error = plan.error;
return result;
}
} // namespace dragonx::wallet

View File

@@ -1,92 +0,0 @@
#pragma once
#include "lite_wallet_gateway.h"
#include "wallet_backend.h"
#include "wallet_capabilities.h"
#include <string>
namespace dragonx::wallet {
enum class LiteWalletRefreshRouteKind {
FullNodeRpc,
LiteGateway,
Unavailable,
};
struct LiteWalletRefreshServiceOptions {
bool allowLiteGatewayRefresh = false;
};
struct LiteWalletRefreshServicePlan {
bool ok = false;
LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
bool fullNodeRefreshDelegated = false;
bool liteGatewayConfigured = false;
bool liteGatewayExecutionAllowed = false;
LiteWalletRefreshPlan liteGatewayPlan;
WalletBackendStatus status;
std::string error;
};
struct LiteWalletRefreshServiceResult {
bool ok = false;
bool attempted = false;
bool fullNodeRefreshDelegated = false;
bool liteGatewayCalled = false;
LiteWalletRefreshServicePlan plan;
LiteWalletRefreshResult liteGatewayResult;
LiteWalletRefreshBundle bundle;
WalletBackendStatus status;
std::string error;
};
class LiteWalletRefreshGateway {
public:
virtual ~LiteWalletRefreshGateway() = default;
virtual LiteWalletRefreshPlan planRefresh(const LiteWalletRefreshRequest& request) const = 0;
virtual LiteWalletRefreshResult refresh(const LiteWalletRefreshRequest& request) = 0;
virtual WalletBackendStatus status() const = 0;
};
class LiteWalletGatewayRefreshAdapter final : public LiteWalletRefreshGateway {
public:
explicit LiteWalletGatewayRefreshAdapter(LiteWalletGateway& gateway);
LiteWalletRefreshPlan planRefresh(const LiteWalletRefreshRequest& request) const override;
LiteWalletRefreshResult refresh(const LiteWalletRefreshRequest& request) override;
WalletBackendStatus status() const override;
private:
LiteWalletGateway& gateway_;
};
const char* liteWalletRefreshRouteKindName(LiteWalletRefreshRouteKind route);
LiteWalletRefreshRouteKind liteWalletRefreshRouteForCapabilities(const WalletCapabilities& capabilities);
class LiteWalletRefreshService {
public:
LiteWalletRefreshService(WalletCapabilities capabilities,
LiteWalletRefreshGateway* liteGateway = nullptr,
LiteWalletRefreshServiceOptions options = {});
const WalletCapabilities& capabilities() const { return capabilities_; }
const LiteWalletRefreshServiceOptions& options() const { return options_; }
LiteWalletRefreshRouteKind route() const;
WalletBackendStatus status() const;
LiteWalletRefreshServicePlan planRefresh(const LiteWalletRefreshRequest& request) const;
LiteWalletRefreshServiceResult refresh(const LiteWalletRefreshRequest& request);
private:
WalletBackendStatus statusForRoute(LiteWalletRefreshRouteKind route,
const std::string& detail = {}) const;
LiteWalletRefreshServiceResult resultFromPlan(const LiteWalletRefreshServicePlan& plan) const;
WalletCapabilities capabilities_;
LiteWalletRefreshGateway* liteGateway_ = nullptr;
LiteWalletRefreshServiceOptions options_;
};
} // namespace dragonx::wallet

View File

@@ -34,7 +34,6 @@ LiteWalletServerLifecycleReadinessResult stoppedResult(
addIssue(result, issue, std::move(message)); addIssue(result, issue, std::move(message));
result.error = result.issues.back().message; result.error = result.issues.back().message;
result.lifecycleStatus = WalletBackendStatus{WalletBackendState::Unavailable, result.error, {}, {}, 0.0}; result.lifecycleStatus = WalletBackendStatus{WalletBackendState::Unavailable, result.error, {}, {}, 0.0};
result.syncLifecycleInput.status = result.lifecycleStatus;
return result; return result;
} }
@@ -381,17 +380,9 @@ LiteWalletServerLifecycleReadinessResult evaluateLiteWalletServerLifecycleReadin
result.futureLifecycleCouldBeEnabled = true; result.futureLifecycleCouldBeEnabled = true;
result.lifecycleReportCouldFeedSyncPlanners = true; result.lifecycleReportCouldFeedSyncPlanners = true;
result.lifecycleStatus = readyLifecycleStatus(result.selectedServerDisplay); result.lifecycleStatus = readyLifecycleStatus(result.selectedServerDisplay);
result.syncLifecycleInput.ready = true;
result.syncLifecycleInput.status = result.lifecycleStatus;
return result; return result;
} }
LiteWalletSyncAppRefreshLifecycleInput liteWalletSyncLifecycleInputFromServerLifecycleReadiness(
const LiteWalletServerLifecycleReadinessResult& result)
{
return result.syncLifecycleInput;
}
LiteWalletServerLifecycleReadinessPlanner::LiteWalletServerLifecycleReadinessPlanner( LiteWalletServerLifecycleReadinessPlanner::LiteWalletServerLifecycleReadinessPlanner(
LiteWalletServerLifecycleReadinessOptions options) LiteWalletServerLifecycleReadinessOptions options)
: options_(options) : options_(options)

View File

@@ -1,7 +1,6 @@
#pragma once #pragma once
#include "lite_wallet_lifecycle_service.h" #include "lite_wallet_lifecycle_service.h"
#include "lite_wallet_sync_app_refresh_integration.h"
#include <cstddef> #include <cstddef>
#include <string> #include <string>
@@ -163,7 +162,6 @@ struct LiteWalletServerLifecycleReadinessResult {
LiteWalletSelectedServerDisplayReport selectedServerDisplay; LiteWalletSelectedServerDisplayReport selectedServerDisplay;
LiteWalletServerSelectionPersistencePlan persistencePlan; LiteWalletServerSelectionPersistencePlan persistencePlan;
LiteWalletLifecycleUiRequestPlan requestPlan; LiteWalletLifecycleUiRequestPlan requestPlan;
LiteWalletSyncAppRefreshLifecycleInput syncLifecycleInput;
WalletBackendStatus lifecycleStatus; WalletBackendStatus lifecycleStatus;
std::vector<LiteWalletServerLifecycleReadinessIssueInfo> issues; std::vector<LiteWalletServerLifecycleReadinessIssueInfo> issues;
std::string error; std::string error;
@@ -179,8 +177,6 @@ const char* liteWalletSelectedServerDisplayStatusName(
LiteWalletServerLifecycleReadinessResult evaluateLiteWalletServerLifecycleReadiness( LiteWalletServerLifecycleReadinessResult evaluateLiteWalletServerLifecycleReadiness(
const LiteWalletServerLifecycleReadinessInput& input, const LiteWalletServerLifecycleReadinessInput& input,
LiteWalletServerLifecycleReadinessOptions options = {}); LiteWalletServerLifecycleReadinessOptions options = {});
LiteWalletSyncAppRefreshLifecycleInput liteWalletSyncLifecycleInputFromServerLifecycleReadiness(
const LiteWalletServerLifecycleReadinessResult& result);
class LiteWalletServerLifecycleReadinessPlanner { class LiteWalletServerLifecycleReadinessPlanner {
public: public:

View File

@@ -1,118 +0,0 @@
#include "wallet/lite_wallet_state_apply_executor.h"
#include <utility>
namespace dragonx::wallet {
namespace {
void addIssue(LiteWalletStateApplyExecutionResult& result,
LiteWalletStateApplyExecutionIssue issue,
std::string message)
{
result.issues.push_back(LiteWalletStateApplyExecutionIssueInfo{issue, std::move(message)});
}
std::size_t countPlannedChanges(const LiteWalletStateApplyPlan& plan)
{
std::size_t count = 0;
for (const auto& fieldPlan : plan.fieldPlans) {
if (fieldPlan.wouldChange) ++count;
}
for (const auto& collectionPlan : plan.collectionPlans) {
if (collectionPlan.wouldReplace) ++count;
}
return count;
}
LiteWalletStateApplyExecutionResult baseResult(const LiteWalletStateApplyPlan& plan,
LiteWalletStateApplyExecutorOptions options)
{
LiteWalletStateApplyExecutionResult result;
result.stateMutationRequested = options.requestStateMutation;
result.stateMutationAllowed = false;
result.applyImplemented = false;
result.fieldPlanCount = plan.fieldPlans.size();
result.collectionPlanCount = plan.collectionPlans.size();
result.plannedChangeCount = countPlannedChanges(plan);
result.planIssueCount = plan.issues.size();
return result;
}
} // namespace
const char* liteWalletStateApplyExecutionStatusName(LiteWalletStateApplyExecutionStatus status)
{
switch (status) {
case LiteWalletStateApplyExecutionStatus::Disabled: return "Disabled";
case LiteWalletStateApplyExecutionStatus::Rejected: return "Rejected";
case LiteWalletStateApplyExecutionStatus::ImplementationMissing: return "ImplementationMissing";
}
return "Unknown";
}
const char* liteWalletStateApplyExecutionIssueName(LiteWalletStateApplyExecutionIssue issue)
{
switch (issue) {
case LiteWalletStateApplyExecutionIssue::InvalidPlan: return "InvalidPlan";
case LiteWalletStateApplyExecutionIssue::MutablePlanRejected: return "MutablePlanRejected";
case LiteWalletStateApplyExecutionIssue::StateMutationDisabled: return "StateMutationDisabled";
case LiteWalletStateApplyExecutionIssue::StateMutationImplementationMissing: return "StateMutationImplementationMissing";
}
return "Unknown";
}
LiteWalletStateApplyExecutionResult executeLiteWalletStateApplyPlan(
const LiteWalletStateApplyPlan& plan,
LiteWalletStateApplyExecutorOptions options)
{
auto result = baseResult(plan, options);
if (!plan.ok) {
result.status = LiteWalletStateApplyExecutionStatus::Rejected;
addIssue(result,
LiteWalletStateApplyExecutionIssue::InvalidPlan,
"lite WalletState apply plan is not valid");
result.error = plan.error.empty() ? result.issues.back().message : plan.error;
return result;
}
if (!plan.dryRunOnly || plan.applyImplemented || plan.stateMutationAllowed) {
result.status = LiteWalletStateApplyExecutionStatus::Rejected;
addIssue(result,
LiteWalletStateApplyExecutionIssue::MutablePlanRejected,
"lite WalletState apply executor accepts dry-run-only plans only");
result.error = result.issues.back().message;
return result;
}
result.planAccepted = true;
if (options.requestStateMutation) {
result.status = LiteWalletStateApplyExecutionStatus::ImplementationMissing;
addIssue(result,
LiteWalletStateApplyExecutionIssue::StateMutationImplementationMissing,
"real lite WalletState application requires a future explicit implementation");
result.error = result.issues.back().message;
return result;
}
result.ok = true;
result.status = LiteWalletStateApplyExecutionStatus::Disabled;
addIssue(result,
LiteWalletStateApplyExecutionIssue::StateMutationDisabled,
"lite WalletState application is disabled; dry-run plan was accepted for reporting only");
return result;
}
LiteWalletStateApplyExecutor::LiteWalletStateApplyExecutor(LiteWalletStateApplyExecutorOptions options)
: options_(options)
{
}
LiteWalletStateApplyExecutionResult LiteWalletStateApplyExecutor::execute(
const LiteWalletStateApplyPlan& plan) const
{
return executeLiteWalletStateApplyPlan(plan, options_);
}
} // namespace dragonx::wallet

View File

@@ -1,71 +0,0 @@
#pragma once
#include "lite_wallet_state_apply_plan.h"
#include <cstddef>
#include <string>
#include <vector>
namespace dragonx::wallet {
enum class LiteWalletStateApplyExecutionStatus {
Disabled,
Rejected,
ImplementationMissing,
};
enum class LiteWalletStateApplyExecutionIssue {
InvalidPlan,
MutablePlanRejected,
StateMutationDisabled,
StateMutationImplementationMissing,
};
struct LiteWalletStateApplyExecutorOptions {
bool requestStateMutation = false;
};
struct LiteWalletStateApplyExecutionIssueInfo {
LiteWalletStateApplyExecutionIssue issue = LiteWalletStateApplyExecutionIssue::StateMutationDisabled;
std::string message;
};
struct LiteWalletStateApplyExecutionResult {
bool ok = false;
bool planAccepted = false;
bool attempted = false;
bool applied = false;
bool stateMutated = false;
bool dryRunOnly = true;
bool noNetwork = true;
bool stateMutationRequested = false;
bool stateMutationAllowed = false;
bool applyImplemented = false;
LiteWalletStateApplyExecutionStatus status = LiteWalletStateApplyExecutionStatus::Disabled;
std::size_t fieldPlanCount = 0;
std::size_t collectionPlanCount = 0;
std::size_t plannedChangeCount = 0;
std::size_t planIssueCount = 0;
std::vector<LiteWalletStateApplyExecutionIssueInfo> issues;
std::string error;
};
const char* liteWalletStateApplyExecutionStatusName(LiteWalletStateApplyExecutionStatus status);
const char* liteWalletStateApplyExecutionIssueName(LiteWalletStateApplyExecutionIssue issue);
LiteWalletStateApplyExecutionResult executeLiteWalletStateApplyPlan(
const LiteWalletStateApplyPlan& plan,
LiteWalletStateApplyExecutorOptions options = {});
class LiteWalletStateApplyExecutor {
public:
explicit LiteWalletStateApplyExecutor(LiteWalletStateApplyExecutorOptions options = {});
LiteWalletStateApplyExecutionResult execute(const LiteWalletStateApplyPlan& plan) const;
private:
LiteWalletStateApplyExecutorOptions options_;
};
} // namespace dragonx::wallet

View File

@@ -1,405 +0,0 @@
#include "wallet/lite_wallet_state_apply_plan.h"
#include <algorithm>
#include <cmath>
#include <limits>
#include <sstream>
#include <utility>
namespace dragonx::wallet {
namespace {
constexpr double kZatoshisPerCoin = 100000000.0;
std::string stringValue(const std::string& value)
{
return value;
}
std::string intValue(std::int64_t value)
{
return std::to_string(value);
}
std::string uintValue(std::uint64_t value)
{
return std::to_string(value);
}
std::string doubleValue(double value)
{
std::ostringstream output;
output << value;
return output.str();
}
std::string boolValue(bool value)
{
return value ? "true" : "false";
}
std::uint64_t coinsToZatoshis(double coins)
{
if (coins <= 0.0) return 0;
const double zatoshis = std::round(coins * kZatoshisPerCoin);
const double maxValue = static_cast<double>(std::numeric_limits<std::uint64_t>::max());
if (zatoshis >= maxValue) return std::numeric_limits<std::uint64_t>::max();
return static_cast<std::uint64_t>(zatoshis);
}
bool modelHasAnySection(const LiteWalletAppRefreshModel& model)
{
return model.hasChainInfo || model.hasHeight || model.hasBalance || model.hasAddresses ||
model.hasSpendableOutputs || model.hasTransactions || model.hasSyncStatus;
}
void addIssue(LiteWalletStateApplyPlan& plan,
LiteWalletStateApplyIssue issue,
std::string message)
{
plan.issues.push_back(LiteWalletStateApplyIssueInfo{issue, std::move(message)});
}
void addFieldPlan(LiteWalletStateApplyPlan& plan,
LiteWalletStateApplySection section,
const std::string& fieldName,
std::string currentValue,
std::string proposedValue)
{
LiteWalletStateApplyFieldPlan fieldPlan;
fieldPlan.section = section;
fieldPlan.fieldName = fieldName;
fieldPlan.currentValue = std::move(currentValue);
fieldPlan.proposedValue = std::move(proposedValue);
fieldPlan.wouldChange = fieldPlan.currentValue != fieldPlan.proposedValue;
fieldPlan.action = fieldPlan.wouldChange
? LiteWalletStateApplyAction::SetField
: LiteWalletStateApplyAction::Noop;
if (fieldPlan.wouldChange) plan.wouldChangeWalletState = true;
plan.fieldPlans.push_back(std::move(fieldPlan));
}
void addCollectionPlan(LiteWalletStateApplyPlan& plan,
LiteWalletStateApplySection section,
std::string collectionName,
std::size_t currentCount,
std::size_t proposedCount,
bool hasWalletStateTarget,
bool wouldReplace)
{
LiteWalletStateApplyCollectionPlan collectionPlan;
collectionPlan.section = section;
collectionPlan.collectionName = std::move(collectionName);
collectionPlan.currentCount = currentCount;
collectionPlan.proposedCount = proposedCount;
collectionPlan.hasWalletStateTarget = hasWalletStateTarget;
collectionPlan.wouldReplace = hasWalletStateTarget && wouldReplace;
if (!hasWalletStateTarget) {
collectionPlan.action = LiteWalletStateApplyAction::InspectOnly;
} else {
collectionPlan.action = collectionPlan.wouldReplace
? LiteWalletStateApplyAction::ReplaceCollection
: LiteWalletStateApplyAction::Noop;
}
if (collectionPlan.wouldReplace) plan.wouldChangeWalletState = true;
plan.collectionPlans.push_back(std::move(collectionPlan));
}
std::vector<std::string> mappedAddresses(const LiteWalletAppRefreshModel& model,
LiteWalletAppAddressKind kind)
{
std::vector<std::string> addresses;
for (const auto& address : model.addresses) {
if (address.kind == kind) addresses.push_back(address.address);
}
return addresses;
}
std::vector<std::string> mappedAddressStrings(const LiteWalletAppRefreshModel& model)
{
std::vector<std::string> addresses;
addresses.reserve(model.addresses.size());
for (const auto& address : model.addresses) addresses.push_back(address.address);
return addresses;
}
std::vector<std::string> stateAddressStrings(const std::vector<dragonx::AddressInfo>& addresses)
{
std::vector<std::string> values;
values.reserve(addresses.size());
for (const auto& address : addresses) values.push_back(address.address);
return values;
}
std::vector<std::string> mappedTransactionIds(const LiteWalletAppRefreshModel& model)
{
std::vector<std::string> txids;
txids.reserve(model.transactions.size());
for (const auto& transaction : model.transactions) txids.push_back(transaction.txid);
return txids;
}
std::vector<std::string> stateTransactionIds(const std::vector<dragonx::TransactionInfo>& transactions)
{
std::vector<std::string> txids;
txids.reserve(transactions.size());
for (const auto& transaction : transactions) txids.push_back(transaction.txid);
return txids;
}
void addChainInfoPlans(LiteWalletStateApplyPlan& plan,
const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state)
{
if (!model.hasChainInfo) return;
plan.hasChainInfo = true;
if (model.chain.longestChain) {
addFieldPlan(plan,
LiteWalletStateApplySection::ChainInfo,
"longestchain",
intValue(state.longestchain),
intValue(*model.chain.longestChain));
}
if (model.chain.notarized) {
addFieldPlan(plan,
LiteWalletStateApplySection::ChainInfo,
"notarized",
intValue(state.notarized),
intValue(*model.chain.notarized));
}
if (model.chain.chainName) {
addFieldPlan(plan,
LiteWalletStateApplySection::ChainInfo,
"chain_name",
stringValue(state.mining.chain),
stringValue(*model.chain.chainName));
}
}
void addHeightPlans(LiteWalletStateApplyPlan& plan,
const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state)
{
if (!model.hasHeight) return;
plan.hasHeight = true;
addFieldPlan(plan,
LiteWalletStateApplySection::Height,
"sync.blocks",
intValue(state.sync.blocks),
intValue(model.height.height));
}
void addBalancePlans(LiteWalletStateApplyPlan& plan,
const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state)
{
if (!model.hasBalance) return;
plan.hasBalance = true;
addFieldPlan(plan,
LiteWalletStateApplySection::Balance,
"privateBalanceZatoshis",
uintValue(coinsToZatoshis(state.privateBalance)),
uintValue(model.balance.shieldedZatoshis));
addFieldPlan(plan,
LiteWalletStateApplySection::Balance,
"transparentBalanceZatoshis",
uintValue(coinsToZatoshis(state.transparentBalance)),
uintValue(model.balance.transparentZatoshis));
addFieldPlan(plan,
LiteWalletStateApplySection::Balance,
"totalBalanceZatoshis",
uintValue(coinsToZatoshis(state.totalBalance)),
uintValue(model.balance.totalZatoshis));
addFieldPlan(plan,
LiteWalletStateApplySection::Balance,
"unconfirmedBalanceZatoshis",
uintValue(coinsToZatoshis(state.unconfirmedBalance)),
uintValue(model.balance.unconfirmedZatoshis));
}
void addAddressPlans(LiteWalletStateApplyPlan& plan,
const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state)
{
if (!model.hasAddresses) return;
plan.hasAddresses = true;
const auto proposedShielded = mappedAddresses(model, LiteWalletAppAddressKind::Shielded);
const auto proposedTransparent = mappedAddresses(model, LiteWalletAppAddressKind::Transparent);
const auto proposedCombined = mappedAddressStrings(model);
const auto currentShielded = stateAddressStrings(state.z_addresses);
const auto currentTransparent = stateAddressStrings(state.t_addresses);
const auto currentCombined = stateAddressStrings(state.addresses);
addCollectionPlan(plan,
LiteWalletStateApplySection::Addresses,
"z_addresses",
currentShielded.size(),
proposedShielded.size(),
true,
currentShielded != proposedShielded);
addCollectionPlan(plan,
LiteWalletStateApplySection::Addresses,
"t_addresses",
currentTransparent.size(),
proposedTransparent.size(),
true,
currentTransparent != proposedTransparent);
addCollectionPlan(plan,
LiteWalletStateApplySection::Addresses,
"addresses",
currentCombined.size(),
proposedCombined.size(),
true,
currentCombined != proposedCombined);
const auto unknownSpendability = std::any_of(model.addresses.begin(), model.addresses.end(),
[](const LiteWalletAppAddressModel& address) { return !address.spendabilityKnown; });
if (unknownSpendability) {
addIssue(plan,
LiteWalletStateApplyIssue::AddressSpendabilityUnknown,
"lite address rows do not yet carry wallet spendability policy");
}
}
void addSpendableOutputPlans(LiteWalletStateApplyPlan& plan,
const LiteWalletAppRefreshModel& model)
{
if (!model.hasSpendableOutputs) return;
plan.hasSpendableOutputs = true;
addCollectionPlan(plan,
LiteWalletStateApplySection::SpendableOutputs,
"spendableOutputs",
0,
model.spendableOutputs.size(),
false,
false);
addIssue(plan,
LiteWalletStateApplyIssue::SpendableOutputsHaveNoWalletStateTarget,
"lite spendable outputs remain source-only until an app apply target is designed");
}
void addTransactionPlans(LiteWalletStateApplyPlan& plan,
const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state)
{
if (!model.hasTransactions) return;
plan.hasTransactions = true;
const auto proposedTxids = mappedTransactionIds(model);
const auto currentTxids = stateTransactionIds(state.transactions);
addCollectionPlan(plan,
LiteWalletStateApplySection::Transactions,
"transactions",
currentTxids.size(),
proposedTxids.size(),
true,
currentTxids != proposedTxids);
}
void addSyncPlans(LiteWalletStateApplyPlan& plan,
const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state)
{
if (!model.hasSyncStatus) return;
plan.hasSyncStatus = true;
addFieldPlan(plan,
LiteWalletStateApplySection::SyncStatus,
"sync.blocks",
intValue(state.sync.blocks),
uintValue(model.sync.walletHeight));
addFieldPlan(plan,
LiteWalletStateApplySection::SyncStatus,
"sync.headers",
intValue(state.sync.headers),
uintValue(model.sync.chainHeight));
addFieldPlan(plan,
LiteWalletStateApplySection::SyncStatus,
"sync.verification_progress",
doubleValue(state.sync.verification_progress),
doubleValue(model.sync.progress));
addFieldPlan(plan,
LiteWalletStateApplySection::SyncStatus,
"sync.syncing",
boolValue(state.sync.syncing),
boolValue(!model.sync.complete));
}
} // namespace
const char* liteWalletStateApplySectionName(LiteWalletStateApplySection section)
{
switch (section) {
case LiteWalletStateApplySection::ChainInfo: return "ChainInfo";
case LiteWalletStateApplySection::Height: return "Height";
case LiteWalletStateApplySection::Balance: return "Balance";
case LiteWalletStateApplySection::Addresses: return "Addresses";
case LiteWalletStateApplySection::SpendableOutputs: return "SpendableOutputs";
case LiteWalletStateApplySection::Transactions: return "Transactions";
case LiteWalletStateApplySection::SyncStatus: return "SyncStatus";
}
return "Unknown";
}
const char* liteWalletStateApplyActionName(LiteWalletStateApplyAction action)
{
switch (action) {
case LiteWalletStateApplyAction::Noop: return "Noop";
case LiteWalletStateApplyAction::SetField: return "SetField";
case LiteWalletStateApplyAction::ReplaceCollection: return "ReplaceCollection";
case LiteWalletStateApplyAction::InspectOnly: return "InspectOnly";
}
return "Unknown";
}
const char* liteWalletStateApplyIssueName(LiteWalletStateApplyIssue issue)
{
switch (issue) {
case LiteWalletStateApplyIssue::EmptyModel: return "EmptyModel";
case LiteWalletStateApplyIssue::IncompleteModel: return "IncompleteModel";
case LiteWalletStateApplyIssue::AddressSpendabilityUnknown: return "AddressSpendabilityUnknown";
case LiteWalletStateApplyIssue::SpendableOutputsHaveNoWalletStateTarget: return "SpendableOutputsHaveNoWalletStateTarget";
}
return "Unknown";
}
LiteWalletStateApplyPlan planLiteWalletStateApply(const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state)
{
LiteWalletStateApplyPlan plan;
plan.sourceComplete = model.complete;
if (!modelHasAnySection(model)) {
addIssue(plan,
LiteWalletStateApplyIssue::EmptyModel,
"lite app refresh model has no sections to compare");
plan.error = plan.issues.back().message;
return plan;
}
if (!model.complete) {
addIssue(plan,
LiteWalletStateApplyIssue::IncompleteModel,
"lite app refresh model is partial; dry-run apply planning only");
}
addChainInfoPlans(plan, model, state);
addHeightPlans(plan, model, state);
addBalancePlans(plan, model, state);
addAddressPlans(plan, model, state);
addSpendableOutputPlans(plan, model);
addTransactionPlans(plan, model, state);
addSyncPlans(plan, model, state);
plan.ok = true;
return plan;
}
LiteWalletStateApplyPlan LiteWalletStateApplyPlanner::buildPlan(
const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state) const
{
return planLiteWalletStateApply(model, state);
}
} // namespace dragonx::wallet

View File

@@ -1,98 +0,0 @@
#pragma once
#include "data/wallet_state.h"
#include "lite_wallet_state_mapper.h"
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>
namespace dragonx::wallet {
enum class LiteWalletStateApplySection {
ChainInfo,
Height,
Balance,
Addresses,
SpendableOutputs,
Transactions,
SyncStatus,
};
enum class LiteWalletStateApplyAction {
Noop,
SetField,
ReplaceCollection,
InspectOnly,
};
enum class LiteWalletStateApplyIssue {
EmptyModel,
IncompleteModel,
AddressSpendabilityUnknown,
SpendableOutputsHaveNoWalletStateTarget,
};
struct LiteWalletStateApplyIssueInfo {
LiteWalletStateApplyIssue issue = LiteWalletStateApplyIssue::EmptyModel;
std::string message;
};
struct LiteWalletStateApplyFieldPlan {
LiteWalletStateApplySection section = LiteWalletStateApplySection::Balance;
LiteWalletStateApplyAction action = LiteWalletStateApplyAction::Noop;
std::string fieldName;
std::string currentValue;
std::string proposedValue;
bool currentKnown = true;
bool proposedKnown = true;
bool wouldChange = false;
};
struct LiteWalletStateApplyCollectionPlan {
LiteWalletStateApplySection section = LiteWalletStateApplySection::Addresses;
LiteWalletStateApplyAction action = LiteWalletStateApplyAction::Noop;
std::string collectionName;
std::size_t currentCount = 0;
std::size_t proposedCount = 0;
bool hasWalletStateTarget = true;
bool wouldReplace = false;
};
struct LiteWalletStateApplyPlan {
bool ok = false;
bool dryRunOnly = true;
bool applyImplemented = false;
bool stateMutationAllowed = false;
bool wouldChangeWalletState = false;
bool sourceComplete = false;
bool hasChainInfo = false;
bool hasHeight = false;
bool hasBalance = false;
bool hasAddresses = false;
bool hasSpendableOutputs = false;
bool hasTransactions = false;
bool hasSyncStatus = false;
std::vector<LiteWalletStateApplyFieldPlan> fieldPlans;
std::vector<LiteWalletStateApplyCollectionPlan> collectionPlans;
std::vector<LiteWalletStateApplyIssueInfo> issues;
std::string error;
};
const char* liteWalletStateApplySectionName(LiteWalletStateApplySection section);
const char* liteWalletStateApplyActionName(LiteWalletStateApplyAction action);
const char* liteWalletStateApplyIssueName(LiteWalletStateApplyIssue issue);
LiteWalletStateApplyPlan planLiteWalletStateApply(const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state);
class LiteWalletStateApplyPlanner {
public:
LiteWalletStateApplyPlan buildPlan(const LiteWalletAppRefreshModel& model,
const dragonx::WalletState& state) const;
};
} // namespace dragonx::wallet

View File

@@ -209,9 +209,4 @@ LiteWalletStateMapResult mapLiteWalletRefreshResult(const LiteWalletRefreshResul
return mapLiteWalletRefreshBundle(result.bundle); return mapLiteWalletRefreshBundle(result.bundle);
} }
LiteWalletStateMapResult mapLiteWalletRefreshServiceResult(const LiteWalletRefreshServiceResult& result)
{
return mapLiteWalletRefreshBundle(result.bundle);
}
} // namespace dragonx::wallet } // namespace dragonx::wallet

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "lite_wallet_refresh_service.h" #include "lite_wallet_gateway.h" // LiteWalletRefreshBundle / LiteWalletRefreshResult
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
@@ -134,6 +134,5 @@ const char* liteWalletStateMapIssueName(LiteWalletStateMapIssue issue);
LiteWalletStateMapResult mapLiteWalletRefreshBundle(const LiteWalletRefreshBundle& bundle); LiteWalletStateMapResult mapLiteWalletRefreshBundle(const LiteWalletRefreshBundle& bundle);
LiteWalletStateMapResult mapLiteWalletRefreshResult(const LiteWalletRefreshResult& result); LiteWalletStateMapResult mapLiteWalletRefreshResult(const LiteWalletRefreshResult& result);
LiteWalletStateMapResult mapLiteWalletRefreshServiceResult(const LiteWalletRefreshServiceResult& result);
} // namespace dragonx::wallet } // namespace dragonx::wallet

View File

@@ -1,344 +0,0 @@
#include "wallet/lite_wallet_sync_app_refresh_integration.h"
#include <utility>
namespace dragonx::wallet {
namespace {
void addIssue(LiteWalletSyncAppRefreshIntegrationResult& result,
LiteWalletSyncAppRefreshIntegrationIssue issue,
std::string message)
{
result.issues.push_back(LiteWalletSyncAppRefreshIntegrationIssueInfo{issue, std::move(message)});
}
std::string statusMessageOrDefault(const WalletBackendStatus& status,
const std::string& fallback)
{
return status.message.empty() ? fallback : status.message;
}
bool refreshReportIsUnsafe(const LiteWalletAppRefreshOrchestrationResult& refresh)
{
return !refresh.dryRunOnly ||
!refresh.noNetwork ||
refresh.stateMutationRequested ||
refresh.stateMutationAllowed ||
refresh.stateMutated ||
refresh.walletStateWritten;
}
bool syncStartPlanIsValid(const LiteSyncPlan& plan)
{
return plan.ok && plan.operation == LiteSyncOperation::StartSync && plan.command == "sync";
}
bool syncStatusPlanIsValid(const LiteSyncPlan& plan)
{
return plan.ok && plan.operation == LiteSyncOperation::PollSyncStatus && plan.command == "syncstatus";
}
LiteWalletSyncAppRefreshIntegrationResult stoppedResult(
LiteWalletSyncAppRefreshIntegrationResult result,
LiteWalletSyncAppRefreshIntegrationStatus status,
LiteWalletSyncAppRefreshIntegrationIssue issue,
std::string message)
{
result.status = status;
addIssue(result, issue, std::move(message));
result.error = result.issues.back().message;
return result;
}
LiteWalletSyncAppRefreshIntegrationResult skippedResult(
LiteWalletSyncAppRefreshIntegrationResult result,
LiteWalletSyncAppRefreshIntegrationIssue issue,
std::string message)
{
result.ok = true;
result.status = LiteWalletSyncAppRefreshIntegrationStatus::RefreshNotQueued;
addIssue(result, issue, std::move(message));
return result;
}
void copyRecoveryFlags(LiteWalletSyncAppRefreshIntegrationResult& result,
const LiteSyncRecoveryDecision& decision)
{
result.recoveryDecision = decision;
result.futureClearRequired = decision.shouldClear;
result.futureRescanRequired = decision.shouldRescan;
result.futureRestartSyncRequired = decision.shouldRestartSync;
result.requiresUserAttention = decision.requiresUserAttention;
}
} // namespace
const char* liteWalletSyncAppRefreshIntegrationStatusName(
LiteWalletSyncAppRefreshIntegrationStatus status)
{
switch (status) {
case LiteWalletSyncAppRefreshIntegrationStatus::FutureWorkerQueueFeedReady: return "FutureWorkerQueueFeedReady";
case LiteWalletSyncAppRefreshIntegrationStatus::WaitingForLifecycle: return "WaitingForLifecycle";
case LiteWalletSyncAppRefreshIntegrationStatus::WaitingForSyncPlan: return "WaitingForSyncPlan";
case LiteWalletSyncAppRefreshIntegrationStatus::WaitingForSyncStatus: return "WaitingForSyncStatus";
case LiteWalletSyncAppRefreshIntegrationStatus::WaitingForRecovery: return "WaitingForRecovery";
case LiteWalletSyncAppRefreshIntegrationStatus::WaitingForCancellation: return "WaitingForCancellation";
case LiteWalletSyncAppRefreshIntegrationStatus::RefreshNotQueued: return "RefreshNotQueued";
case LiteWalletSyncAppRefreshIntegrationStatus::WorkerQueueUnavailable: return "WorkerQueueUnavailable";
case LiteWalletSyncAppRefreshIntegrationStatus::UnsafePlan: return "UnsafePlan";
}
return "Unknown";
}
const char* liteWalletSyncAppRefreshIntegrationIssueName(
LiteWalletSyncAppRefreshIntegrationIssue issue)
{
switch (issue) {
case LiteWalletSyncAppRefreshIntegrationIssue::LifecycleNotReady: return "LifecycleNotReady";
case LiteWalletSyncAppRefreshIntegrationIssue::MissingSyncStartPlan: return "MissingSyncStartPlan";
case LiteWalletSyncAppRefreshIntegrationIssue::InvalidSyncStartPlan: return "InvalidSyncStartPlan";
case LiteWalletSyncAppRefreshIntegrationIssue::SyncStartWouldExecute: return "SyncStartWouldExecute";
case LiteWalletSyncAppRefreshIntegrationIssue::MissingSyncStatusPlan: return "MissingSyncStatusPlan";
case LiteWalletSyncAppRefreshIntegrationIssue::InvalidSyncStatusPlan: return "InvalidSyncStatusPlan";
case LiteWalletSyncAppRefreshIntegrationIssue::SyncStatusWouldExecute: return "SyncStatusWouldExecute";
case LiteWalletSyncAppRefreshIntegrationIssue::MissingRecoveryDecision: return "MissingRecoveryDecision";
case LiteWalletSyncAppRefreshIntegrationIssue::SyncStillPolling: return "SyncStillPolling";
case LiteWalletSyncAppRefreshIntegrationIssue::SyncRecoveryRequired: return "SyncRecoveryRequired";
case LiteWalletSyncAppRefreshIntegrationIssue::SyncRecoveryNeedsUserAttention: return "SyncRecoveryNeedsUserAttention";
case LiteWalletSyncAppRefreshIntegrationIssue::CancellationRequired: return "CancellationRequired";
case LiteWalletSyncAppRefreshIntegrationIssue::CancellationUnsupported: return "CancellationUnsupported";
case LiteWalletSyncAppRefreshIntegrationIssue::RefreshReportRejected: return "RefreshReportRejected";
case LiteWalletSyncAppRefreshIntegrationIssue::RefreshReportUnsafe: return "RefreshReportUnsafe";
case LiteWalletSyncAppRefreshIntegrationIssue::RefreshSkipped: return "RefreshSkipped";
case LiteWalletSyncAppRefreshIntegrationIssue::RefreshBlocked: return "RefreshBlocked";
case LiteWalletSyncAppRefreshIntegrationIssue::FutureWorkerQueueDisabled: return "FutureWorkerQueueDisabled";
case LiteWalletSyncAppRefreshIntegrationIssue::FutureWorkerQueuePressure: return "FutureWorkerQueuePressure";
}
return "Unknown";
}
LiteWalletSyncAppRefreshIntegrationResult planLiteWalletSyncAppRefreshIntegration(
const LiteWalletSyncAppRefreshIntegrationInput& input,
LiteWalletSyncAppRefreshIntegrationOptions options)
{
LiteWalletSyncAppRefreshIntegrationResult result;
result.lifecycleStatus = input.lifecycle.status;
result.refreshOrchestration = input.refreshOrchestration;
result.route = input.refreshOrchestration.route;
result.refreshWouldQueue = input.refreshOrchestration.wouldQueueRefresh;
result.refreshSkipped = input.refreshOrchestration.skipped;
result.refreshBlocked = input.refreshOrchestration.blocked;
result.futureWorkerQueuePlan.laneName = input.futureWorkerQueue.laneName;
result.futureWorkerQueuePlan.trigger = input.refreshOrchestration.trigger;
result.futureWorkerQueuePlan.route = input.refreshOrchestration.route;
result.futureWorkerQueuePlan.queueDepth = input.futureWorkerQueue.queueDepth;
result.futureWorkerQueuePlan.maxQueueDepth = input.futureWorkerQueue.maxQueueDepth;
if (input.sync.haveStartPlan) {
result.syncStartPlan = input.sync.startPlan;
result.futureWorkerQueuePlan.startSyncCommand = input.sync.startPlan.command;
}
if (input.sync.haveStatusPlan) {
result.syncStatusPlan = input.sync.statusPlan;
result.futureWorkerQueuePlan.syncStatusCommand = input.sync.statusPlan.command;
}
if (input.sync.haveRecoveryDecision) {
copyRecoveryFlags(result, input.sync.recoveryDecision);
}
if (options.requireLifecycleReady && !input.lifecycle.ready) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForLifecycle,
LiteWalletSyncAppRefreshIntegrationIssue::LifecycleNotReady,
statusMessageOrDefault(input.lifecycle.status, "lite wallet lifecycle is not ready"));
}
result.lifecycleAccepted = true;
if (options.requireSyncStartPlan && !input.sync.haveStartPlan) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForSyncPlan,
LiteWalletSyncAppRefreshIntegrationIssue::MissingSyncStartPlan,
"lite sync start plan is required before app refresh integration");
}
if (input.sync.haveStartPlan) {
if (!syncStartPlanIsValid(input.sync.startPlan)) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForSyncPlan,
LiteWalletSyncAppRefreshIntegrationIssue::InvalidSyncStartPlan,
input.sync.startPlan.error.empty()
? "lite sync start plan is invalid"
: input.sync.startPlan.error);
}
if (options.rejectExecutableSyncPlans && input.sync.startPlan.bridgeExecutionAllowed) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::UnsafePlan,
LiteWalletSyncAppRefreshIntegrationIssue::SyncStartWouldExecute,
"lite sync start plan would allow bridge execution");
}
result.syncStartPlanAccepted = true;
}
if (options.requireSyncStatusPlan && !input.sync.haveStatusPlan) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForSyncStatus,
LiteWalletSyncAppRefreshIntegrationIssue::MissingSyncStatusPlan,
"lite syncstatus plan is required before app refresh integration");
}
if (input.sync.haveStatusPlan) {
if (!syncStatusPlanIsValid(input.sync.statusPlan)) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForSyncStatus,
LiteWalletSyncAppRefreshIntegrationIssue::InvalidSyncStatusPlan,
input.sync.statusPlan.error.empty()
? "lite syncstatus plan is invalid"
: input.sync.statusPlan.error);
}
if (options.rejectExecutableSyncPlans && input.sync.statusPlan.bridgeExecutionAllowed) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::UnsafePlan,
LiteWalletSyncAppRefreshIntegrationIssue::SyncStatusWouldExecute,
"lite syncstatus plan would allow bridge execution");
}
result.syncStatusPlanAccepted = true;
}
if (options.requireRecoveryDecision && !input.sync.haveRecoveryDecision) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForSyncStatus,
LiteWalletSyncAppRefreshIntegrationIssue::MissingRecoveryDecision,
"lite sync recovery decision is required before app refresh integration");
}
if (input.sync.haveRecoveryDecision) {
const auto& decision = input.sync.recoveryDecision;
if (decision.kind == LiteSyncRecoveryDecisionKind::InvalidStatus) {
result.recoveryRequired = true;
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForRecovery,
LiteWalletSyncAppRefreshIntegrationIssue::SyncRecoveryNeedsUserAttention,
decision.reason.empty()
? "lite sync status is invalid and needs user attention"
: decision.reason);
}
if (decision.kind == LiteSyncRecoveryDecisionKind::Stuck ||
decision.kind == LiteSyncRecoveryDecisionKind::ReorgDetected) {
result.recoveryRequired = true;
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForRecovery,
LiteWalletSyncAppRefreshIntegrationIssue::SyncRecoveryRequired,
decision.reason.empty()
? "lite sync recovery must be modeled before refresh can feed a queue"
: decision.reason);
}
if (options.requireSyncCompleteForRefresh && decision.kind == LiteSyncRecoveryDecisionKind::KeepPolling) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForSyncStatus,
LiteWalletSyncAppRefreshIntegrationIssue::SyncStillPolling,
decision.reason.empty()
? "lite sync is still polling"
: decision.reason);
}
result.recoveryAccepted = true;
}
if (input.cancellation.cancellationRequested && input.cancellation.syncInProgress) {
result.cancellationRequired = true;
if (!input.cancellation.cancellationSupported) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForCancellation,
LiteWalletSyncAppRefreshIntegrationIssue::CancellationUnsupported,
"lite sync cancellation is requested but no cancellation path is available");
}
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WaitingForCancellation,
LiteWalletSyncAppRefreshIntegrationIssue::CancellationRequired,
"lite sync cancellation must complete before app refresh can feed a queue");
}
result.cancellationAccepted = true;
if (refreshReportIsUnsafe(input.refreshOrchestration)) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::UnsafePlan,
LiteWalletSyncAppRefreshIntegrationIssue::RefreshReportUnsafe,
"lite app refresh orchestration report is not a no-network dry-run report");
}
if (!input.refreshOrchestration.ok) {
const auto issue = input.refreshOrchestration.blocked
? LiteWalletSyncAppRefreshIntegrationIssue::RefreshBlocked
: LiteWalletSyncAppRefreshIntegrationIssue::RefreshReportRejected;
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::RefreshNotQueued,
issue,
input.refreshOrchestration.error.empty()
? "lite app refresh orchestration report is not queued"
: input.refreshOrchestration.error);
}
result.refreshReportAccepted = true;
if (input.refreshOrchestration.skipped || !input.refreshOrchestration.wouldQueueRefresh) {
return skippedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationIssue::RefreshSkipped,
input.refreshOrchestration.issues.empty()
? "lite app refresh orchestration skipped queueing"
: input.refreshOrchestration.issues.front().message);
}
if (options.requireFutureWorkerQueue && !input.futureWorkerQueue.enabled) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WorkerQueueUnavailable,
LiteWalletSyncAppRefreshIntegrationIssue::FutureWorkerQueueDisabled,
"future lite app refresh worker queue is disabled");
}
if (input.futureWorkerQueue.maxQueueDepth > 0 &&
input.futureWorkerQueue.queueDepth >= input.futureWorkerQueue.maxQueueDepth) {
return stoppedResult(
std::move(result),
LiteWalletSyncAppRefreshIntegrationStatus::WorkerQueueUnavailable,
LiteWalletSyncAppRefreshIntegrationIssue::FutureWorkerQueuePressure,
"future lite app refresh worker queue is at capacity");
}
result.ok = true;
result.status = LiteWalletSyncAppRefreshIntegrationStatus::FutureWorkerQueueFeedReady;
result.futureWorkerQueueFeedReady = true;
result.wouldFeedFutureWorkerQueue = true;
result.futureWorkerQueuePlan.readyToFeed = true;
result.futureWorkerQueuePlan.wouldFeed = true;
return result;
}
LiteWalletSyncAppRefreshIntegrationPlanner::LiteWalletSyncAppRefreshIntegrationPlanner(
LiteWalletSyncAppRefreshIntegrationOptions options)
: options_(options)
{
}
LiteWalletSyncAppRefreshIntegrationResult LiteWalletSyncAppRefreshIntegrationPlanner::plan(
const LiteWalletSyncAppRefreshIntegrationInput& input) const
{
return planLiteWalletSyncAppRefreshIntegration(input, options_);
}
} // namespace dragonx::wallet

View File

@@ -1,172 +0,0 @@
#pragma once
#include "lite_sync_service.h"
#include "lite_wallet_app_refresh_orchestrator.h"
#include <cstddef>
#include <string>
#include <vector>
namespace dragonx::wallet {
enum class LiteWalletSyncAppRefreshIntegrationStatus {
FutureWorkerQueueFeedReady,
WaitingForLifecycle,
WaitingForSyncPlan,
WaitingForSyncStatus,
WaitingForRecovery,
WaitingForCancellation,
RefreshNotQueued,
WorkerQueueUnavailable,
UnsafePlan,
};
enum class LiteWalletSyncAppRefreshIntegrationIssue {
LifecycleNotReady,
MissingSyncStartPlan,
InvalidSyncStartPlan,
SyncStartWouldExecute,
MissingSyncStatusPlan,
InvalidSyncStatusPlan,
SyncStatusWouldExecute,
MissingRecoveryDecision,
SyncStillPolling,
SyncRecoveryRequired,
SyncRecoveryNeedsUserAttention,
CancellationRequired,
CancellationUnsupported,
RefreshReportRejected,
RefreshReportUnsafe,
RefreshSkipped,
RefreshBlocked,
FutureWorkerQueueDisabled,
FutureWorkerQueuePressure,
};
struct LiteWalletSyncAppRefreshLifecycleInput {
bool ready = false;
WalletBackendStatus status;
};
struct LiteWalletSyncAppRefreshSyncPlanInput {
bool haveStartPlan = false;
LiteSyncPlan startPlan;
bool haveStatusPlan = false;
LiteSyncPlan statusPlan;
bool haveRecoveryDecision = false;
LiteSyncRecoveryDecision recoveryDecision;
};
struct LiteWalletSyncAppRefreshCancellationInput {
bool cancellationRequested = false;
bool syncInProgress = false;
bool cancellationSupported = false;
};
struct LiteWalletFutureWorkerQueueInput {
bool enabled = true;
std::size_t queueDepth = 0;
std::size_t maxQueueDepth = 0;
std::string laneName = "lite-app-refresh";
};
struct LiteWalletSyncAppRefreshIntegrationInput {
LiteWalletSyncAppRefreshLifecycleInput lifecycle;
LiteWalletSyncAppRefreshSyncPlanInput sync;
LiteWalletSyncAppRefreshCancellationInput cancellation;
LiteWalletFutureWorkerQueueInput futureWorkerQueue;
LiteWalletAppRefreshOrchestrationResult refreshOrchestration;
};
struct LiteWalletSyncAppRefreshIntegrationOptions {
bool requireLifecycleReady = true;
bool requireSyncStartPlan = true;
bool requireSyncStatusPlan = true;
bool requireRecoveryDecision = true;
bool requireSyncCompleteForRefresh = true;
bool rejectExecutableSyncPlans = true;
bool requireFutureWorkerQueue = true;
};
struct LiteWalletFutureWorkerQueuePlan {
bool readyToFeed = false;
bool wouldFeed = false;
bool enqueued = false;
std::string laneName;
LiteWalletAppRefreshScheduleTrigger trigger = LiteWalletAppRefreshScheduleTrigger::Periodic;
LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
std::string startSyncCommand;
std::string syncStatusCommand;
std::size_t queueDepth = 0;
std::size_t maxQueueDepth = 0;
};
struct LiteWalletSyncAppRefreshIntegrationIssueInfo {
LiteWalletSyncAppRefreshIntegrationIssue issue = LiteWalletSyncAppRefreshIntegrationIssue::LifecycleNotReady;
std::string message;
};
struct LiteWalletSyncAppRefreshIntegrationResult {
bool ok = false;
bool dryRunOnly = true;
bool noNetwork = true;
bool noBridgeCalls = true;
bool noSyncStarted = true;
bool noWalletPersistence = true;
bool stateMutationAllowed = false;
bool stateMutated = false;
bool walletStateWritten = false;
bool workerQueueEnqueued = false;
bool lifecycleAccepted = false;
bool syncStartPlanAccepted = false;
bool syncStatusPlanAccepted = false;
bool recoveryAccepted = false;
bool cancellationAccepted = false;
bool refreshReportAccepted = false;
bool futureWorkerQueueFeedReady = false;
bool wouldFeedFutureWorkerQueue = false;
bool refreshWouldQueue = false;
bool refreshSkipped = false;
bool refreshBlocked = false;
bool recoveryRequired = false;
bool cancellationRequired = false;
bool futureClearRequired = false;
bool futureRescanRequired = false;
bool futureRestartSyncRequired = false;
bool requiresUserAttention = false;
LiteWalletSyncAppRefreshIntegrationStatus status = LiteWalletSyncAppRefreshIntegrationStatus::WaitingForLifecycle;
LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
WalletBackendStatus lifecycleStatus;
LiteSyncPlan syncStartPlan;
LiteSyncPlan syncStatusPlan;
LiteSyncRecoveryDecision recoveryDecision;
LiteWalletAppRefreshOrchestrationResult refreshOrchestration;
LiteWalletFutureWorkerQueuePlan futureWorkerQueuePlan;
std::vector<LiteWalletSyncAppRefreshIntegrationIssueInfo> issues;
std::string error;
};
const char* liteWalletSyncAppRefreshIntegrationStatusName(
LiteWalletSyncAppRefreshIntegrationStatus status);
const char* liteWalletSyncAppRefreshIntegrationIssueName(
LiteWalletSyncAppRefreshIntegrationIssue issue);
LiteWalletSyncAppRefreshIntegrationResult planLiteWalletSyncAppRefreshIntegration(
const LiteWalletSyncAppRefreshIntegrationInput& input,
LiteWalletSyncAppRefreshIntegrationOptions options = {});
class LiteWalletSyncAppRefreshIntegrationPlanner {
public:
explicit LiteWalletSyncAppRefreshIntegrationPlanner(
LiteWalletSyncAppRefreshIntegrationOptions options = {});
LiteWalletSyncAppRefreshIntegrationResult plan(
const LiteWalletSyncAppRefreshIntegrationInput& input) const;
private:
LiteWalletSyncAppRefreshIntegrationOptions options_;
};
} // namespace dragonx::wallet

View File

@@ -1,461 +0,0 @@
#include "wallet/lite_wallet_sync_execution_readiness.h"
#include <utility>
namespace dragonx::wallet {
namespace {
void addIssue(LiteWalletSyncExecutionReadinessResult& result,
LiteWalletSyncExecutionReadinessIssue issue,
std::string message)
{
result.issues.push_back(LiteWalletSyncExecutionReadinessIssueInfo{issue, std::move(message)});
}
LiteWalletSyncExecutionReadinessResult stoppedResult(
LiteWalletSyncExecutionReadinessResult result,
LiteWalletSyncExecutionReadinessStatus status,
LiteWalletSyncExecutionReadinessIssue issue,
std::string message)
{
result.status = status;
addIssue(result, issue, std::move(message));
result.error = result.issues.back().message;
return result;
}
bool coreArtifactSymbolsReady(const LiteWalletSdxlArtifactSymbolsInput& symbols)
{
return symbols.walletExists &&
symbols.initializeNew &&
symbols.initializeNewFromPhrase &&
symbols.initializeExisting &&
symbols.execute &&
symbols.checkServerOnline;
}
bool integrationReportIsUnsafe(const LiteWalletSyncAppRefreshIntegrationResult& integration)
{
return !integration.dryRunOnly ||
!integration.noNetwork ||
!integration.noBridgeCalls ||
!integration.noSyncStarted ||
!integration.noWalletPersistence ||
integration.stateMutationAllowed ||
integration.stateMutated ||
integration.walletStateWritten ||
integration.workerQueueEnqueued;
}
std::string backendMessageOrDefault(const WalletBackendStatus& status,
const std::string& fallback)
{
return status.message.empty() ? fallback : status.message;
}
bool recoveryRequiredByIntegration(const LiteWalletSyncAppRefreshIntegrationResult& integration)
{
return integration.recoveryRequired ||
integration.futureClearRequired ||
integration.futureRescanRequired ||
integration.futureRestartSyncRequired ||
integration.requiresUserAttention;
}
bool cancellationRequiredByIntegration(const LiteWalletSyncAppRefreshIntegrationResult& integration)
{
return integration.cancellationRequired ||
integration.status == LiteWalletSyncAppRefreshIntegrationStatus::WaitingForCancellation;
}
void copyIntegrationSummary(LiteWalletSyncExecutionReadinessResult& result,
const LiteWalletSyncAppRefreshIntegrationResult& integration)
{
result.integrationReport = integration;
result.integrationFeedReady = integration.futureWorkerQueueFeedReady;
result.recoveryRequired = recoveryRequiredByIntegration(integration);
result.cancellationRequired = cancellationRequiredByIntegration(integration);
result.futureClearRequired = integration.futureClearRequired;
result.futureRescanRequired = integration.futureRescanRequired;
result.futureRestartSyncRequired = integration.futureRestartSyncRequired;
result.requiresUserAttention = integration.requiresUserAttention;
result.enablementPlan.startSyncCommand = integration.syncStartPlan.command;
result.enablementPlan.syncStatusCommand = integration.syncStatusPlan.command;
result.enablementPlan.workerQueueLane = integration.futureWorkerQueuePlan.laneName;
result.enablementPlan.route = integration.route;
}
LiteWalletSyncExecutionReadinessResult evaluateRecoveryReadiness(
LiteWalletSyncExecutionReadinessResult result,
const LiteWalletSyncExecutionRecoveryReadinessInput& recovery,
LiteWalletSyncExecutionReadinessOptions options)
{
if (!options.requireRecoveryExecutionReadiness) {
result.recoveryExecutionReady = true;
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForRecovery,
LiteWalletSyncExecutionReadinessIssue::IntegrationFeedNotReady,
"lite sync recovery must complete before sync execution can be enabled");
}
if (result.futureClearRequired && !recovery.clearActionReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForRecovery,
LiteWalletSyncExecutionReadinessIssue::RecoveryClearMissing,
"lite sync recovery requires a future clear action before sync execution");
}
if (result.futureRescanRequired && !recovery.rescanActionReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForRecovery,
LiteWalletSyncExecutionReadinessIssue::RecoveryRescanMissing,
"lite sync recovery requires a future rescan action before sync execution");
}
if (result.futureRestartSyncRequired && !recovery.restartSyncActionReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForRecovery,
LiteWalletSyncExecutionReadinessIssue::RecoveryRestartMissing,
"lite sync recovery requires a future restart-sync action before sync execution");
}
if (result.requiresUserAttention && !recovery.userAttentionPathReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForRecovery,
LiteWalletSyncExecutionReadinessIssue::RecoveryUserAttentionMissing,
"lite sync recovery requires a user-attention path before sync execution");
}
result.recoveryExecutionReady = true;
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForRecovery,
LiteWalletSyncExecutionReadinessIssue::IntegrationFeedNotReady,
"lite sync recovery is ready to be modeled but must complete before sync execution");
}
} // namespace
const char* liteWalletSyncExecutionReadinessStatusName(
LiteWalletSyncExecutionReadinessStatus status)
{
switch (status) {
case LiteWalletSyncExecutionReadinessStatus::ReadyToEnableSyncExecution: return "ReadyToEnableSyncExecution";
case LiteWalletSyncExecutionReadinessStatus::WaitingForLiteBuild: return "WaitingForLiteBuild";
case LiteWalletSyncExecutionReadinessStatus::WaitingForArtifact: return "WaitingForArtifact";
case LiteWalletSyncExecutionReadinessStatus::WaitingForBackendLink: return "WaitingForBackendLink";
case LiteWalletSyncExecutionReadinessStatus::WaitingForBridge: return "WaitingForBridge";
case LiteWalletSyncExecutionReadinessStatus::WaitingForIntegration: return "WaitingForIntegration";
case LiteWalletSyncExecutionReadinessStatus::WaitingForExecutionOwner: return "WaitingForExecutionOwner";
case LiteWalletSyncExecutionReadinessStatus::WaitingForCancellation: return "WaitingForCancellation";
case LiteWalletSyncExecutionReadinessStatus::WaitingForShutdown: return "WaitingForShutdown";
case LiteWalletSyncExecutionReadinessStatus::WaitingForRetry: return "WaitingForRetry";
case LiteWalletSyncExecutionReadinessStatus::WaitingForRecovery: return "WaitingForRecovery";
case LiteWalletSyncExecutionReadinessStatus::UnsafePlan: return "UnsafePlan";
}
return "Unknown";
}
const char* liteWalletSyncExecutionReadinessIssueName(
LiteWalletSyncExecutionReadinessIssue issue)
{
switch (issue) {
case LiteWalletSyncExecutionReadinessIssue::FullNodeBuild: return "FullNodeBuild";
case LiteWalletSyncExecutionReadinessIssue::LiteBackendCapabilityMissing: return "LiteBackendCapabilityMissing";
case LiteWalletSyncExecutionReadinessIssue::ArtifactPathMissing: return "ArtifactPathMissing";
case LiteWalletSyncExecutionReadinessIssue::ArtifactMissing: return "ArtifactMissing";
case LiteWalletSyncExecutionReadinessIssue::ArtifactUnreadable: return "ArtifactUnreadable";
case LiteWalletSyncExecutionReadinessIssue::ArtifactNotSdxlCompatible: return "ArtifactNotSdxlCompatible";
case LiteWalletSyncExecutionReadinessIssue::ArtifactSymbolsMissing: return "ArtifactSymbolsMissing";
case LiteWalletSyncExecutionReadinessIssue::ArtifactStringOwnershipUnverified: return "ArtifactStringOwnershipUnverified";
case LiteWalletSyncExecutionReadinessIssue::ArtifactShutdownUnavailable: return "ArtifactShutdownUnavailable";
case LiteWalletSyncExecutionReadinessIssue::BackendNotLinked: return "BackendNotLinked";
case LiteWalletSyncExecutionReadinessIssue::BridgeUnavailable: return "BridgeUnavailable";
case LiteWalletSyncExecutionReadinessIssue::IntegrationRejected: return "IntegrationRejected";
case LiteWalletSyncExecutionReadinessIssue::IntegrationUnsafe: return "IntegrationUnsafe";
case LiteWalletSyncExecutionReadinessIssue::IntegrationFeedNotReady: return "IntegrationFeedNotReady";
case LiteWalletSyncExecutionReadinessIssue::WorkerQueueOwnerMissing: return "WorkerQueueOwnerMissing";
case LiteWalletSyncExecutionReadinessIssue::SyncLoopOwnerMissing: return "SyncLoopOwnerMissing";
case LiteWalletSyncExecutionReadinessIssue::StartSyncExecutionMissing: return "StartSyncExecutionMissing";
case LiteWalletSyncExecutionReadinessIssue::SyncStatusExecutionMissing: return "SyncStatusExecutionMissing";
case LiteWalletSyncExecutionReadinessIssue::CancellationPathMissing: return "CancellationPathMissing";
case LiteWalletSyncExecutionReadinessIssue::CancellationPending: return "CancellationPending";
case LiteWalletSyncExecutionReadinessIssue::ShutdownPathMissing: return "ShutdownPathMissing";
case LiteWalletSyncExecutionReadinessIssue::ShutdownPending: return "ShutdownPending";
case LiteWalletSyncExecutionReadinessIssue::RetryPolicyMissing: return "RetryPolicyMissing";
case LiteWalletSyncExecutionReadinessIssue::RetryLimitReached: return "RetryLimitReached";
case LiteWalletSyncExecutionReadinessIssue::UserVisibleStatusMissing: return "UserVisibleStatusMissing";
case LiteWalletSyncExecutionReadinessIssue::RecoveryClearMissing: return "RecoveryClearMissing";
case LiteWalletSyncExecutionReadinessIssue::RecoveryRescanMissing: return "RecoveryRescanMissing";
case LiteWalletSyncExecutionReadinessIssue::RecoveryRestartMissing: return "RecoveryRestartMissing";
case LiteWalletSyncExecutionReadinessIssue::RecoveryUserAttentionMissing: return "RecoveryUserAttentionMissing";
}
return "Unknown";
}
LiteWalletSyncExecutionReadinessResult evaluateLiteWalletSyncExecutionReadiness(
const LiteWalletSyncExecutionReadinessInput& input,
LiteWalletSyncExecutionReadinessOptions options)
{
LiteWalletSyncExecutionReadinessResult result;
result.capabilities = input.capabilities;
result.backendStatus = input.backend.status;
copyIntegrationSummary(result, input.integrationReport);
if (options.requireLiteBuild && !isLiteBuild(input.capabilities)) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForLiteBuild,
LiteWalletSyncExecutionReadinessIssue::FullNodeBuild,
"lite sync execution readiness requires a lite build");
}
result.liteBuildAccepted = true;
if (options.requireLiteBackendCapability && !supportsLiteBackend(input.capabilities)) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForBackendLink,
LiteWalletSyncExecutionReadinessIssue::LiteBackendCapabilityMissing,
"lite backend capability is not available");
}
if (options.requireValidatedArtifact) {
if (!input.artifact.pathConfigured || input.artifact.artifactPath.empty()) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForArtifact,
LiteWalletSyncExecutionReadinessIssue::ArtifactPathMissing,
"SDXL-compatible lite backend artifact path is not configured");
}
if (!input.artifact.exists) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForArtifact,
LiteWalletSyncExecutionReadinessIssue::ArtifactMissing,
"SDXL-compatible lite backend artifact does not exist");
}
if (!input.artifact.readable) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForArtifact,
LiteWalletSyncExecutionReadinessIssue::ArtifactUnreadable,
"SDXL-compatible lite backend artifact is not readable");
}
if (!input.artifact.sdxlCompatible) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForArtifact,
LiteWalletSyncExecutionReadinessIssue::ArtifactNotSdxlCompatible,
"lite backend artifact has not been validated as SDXL-compatible");
}
if (!coreArtifactSymbolsReady(input.artifact.symbols)) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForArtifact,
LiteWalletSyncExecutionReadinessIssue::ArtifactSymbolsMissing,
"lite backend artifact is missing required SDXL lifecycle or execute symbols");
}
if (!input.artifact.symbols.freeString) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForArtifact,
LiteWalletSyncExecutionReadinessIssue::ArtifactStringOwnershipUnverified,
"lite backend artifact string ownership cleanup is not validated");
}
if (!input.artifact.symbols.shutdown) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForArtifact,
LiteWalletSyncExecutionReadinessIssue::ArtifactShutdownUnavailable,
"lite backend artifact shutdown symbol is not validated");
}
}
result.artifactAccepted = true;
if (options.requireLinkedBackend && !input.backend.linked) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForBackendLink,
LiteWalletSyncExecutionReadinessIssue::BackendNotLinked,
backendMessageOrDefault(input.backend.status, "lite backend is not linked"));
}
result.backendLinkedAccepted = true;
if (options.requireBridgeAvailable && !input.backend.bridgeAvailable) {
const auto message = !input.backend.bridgeUnavailableReason.empty()
? input.backend.bridgeUnavailableReason
: backendMessageOrDefault(input.backend.status, "lite client bridge is unavailable");
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForBridge,
LiteWalletSyncExecutionReadinessIssue::BridgeUnavailable,
message);
}
result.bridgeAccepted = true;
if (integrationReportIsUnsafe(input.integrationReport)) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::UnsafePlan,
LiteWalletSyncExecutionReadinessIssue::IntegrationUnsafe,
"lite sync/app-refresh integration report is not a no-network dry-run report");
}
if (result.recoveryRequired) {
return evaluateRecoveryReadiness(std::move(result), input.recovery, options);
}
if (result.cancellationRequired || input.cancellation.cancellationRequested) {
result.cancellationRequired = true;
if (!input.cancellation.cancellationPathReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForCancellation,
LiteWalletSyncExecutionReadinessIssue::CancellationPathMissing,
"lite sync cancellation path must be ready before sync execution");
}
if (!input.cancellation.cancellationComplete) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForCancellation,
LiteWalletSyncExecutionReadinessIssue::CancellationPending,
"lite sync cancellation must complete before sync execution");
}
}
if (!input.integrationReport.ok) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForIntegration,
LiteWalletSyncExecutionReadinessIssue::IntegrationRejected,
input.integrationReport.error.empty()
? "lite sync/app-refresh integration report is not successful"
: input.integrationReport.error);
}
if (options.requireIntegrationFeedReady && !input.integrationReport.futureWorkerQueueFeedReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForIntegration,
LiteWalletSyncExecutionReadinessIssue::IntegrationFeedNotReady,
"lite sync/app-refresh integration report is not ready to feed future work");
}
result.integrationAccepted = true;
if (options.requireWorkerQueueOwner && !input.ownership.workerQueueOwnerReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForExecutionOwner,
LiteWalletSyncExecutionReadinessIssue::WorkerQueueOwnerMissing,
"lite sync execution requires explicit worker queue ownership");
}
result.workerQueueOwnerAccepted = true;
if (options.requireSyncLoopOwner && !input.ownership.syncLoopOwnerReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForExecutionOwner,
LiteWalletSyncExecutionReadinessIssue::SyncLoopOwnerMissing,
"lite sync execution requires explicit sync loop ownership");
}
result.syncLoopOwnerAccepted = true;
if (options.requireStartSyncExecution && !input.ownership.startSyncExecutionReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForExecutionOwner,
LiteWalletSyncExecutionReadinessIssue::StartSyncExecutionMissing,
"lite sync start execution path is not ready");
}
result.startSyncExecutionReady = true;
if (options.requireSyncStatusPolling && !input.ownership.syncStatusPollingReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForExecutionOwner,
LiteWalletSyncExecutionReadinessIssue::SyncStatusExecutionMissing,
"lite syncstatus polling execution path is not ready");
}
result.syncStatusPollingReady = true;
if (options.requireCancellationPath && !input.cancellation.cancellationPathReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForCancellation,
LiteWalletSyncExecutionReadinessIssue::CancellationPathMissing,
"lite sync cancellation path must be ready before sync execution");
}
result.cancellationReady = true;
if (options.requireShutdownHook && !input.shutdown.shutdownHookReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForShutdown,
LiteWalletSyncExecutionReadinessIssue::ShutdownPathMissing,
"lite sync shutdown hook must be ready before sync execution");
}
if (input.shutdown.shutdownRequested && !input.shutdown.shutdownComplete) {
result.shutdownRequired = true;
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForShutdown,
LiteWalletSyncExecutionReadinessIssue::ShutdownPending,
"lite sync shutdown must complete before new sync execution");
}
result.shutdownReady = true;
if (options.requireRetryPolicy && !input.retry.retryPolicyReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForRetry,
LiteWalletSyncExecutionReadinessIssue::RetryPolicyMissing,
"lite sync retry policy must be ready before sync execution");
}
result.retryReady = true;
if (options.requireUserVisibleStatus && !input.ownership.userVisibleStatusReady) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForRetry,
LiteWalletSyncExecutionReadinessIssue::UserVisibleStatusMissing,
"lite sync execution requires user-visible status reporting");
}
result.userVisibleStatusReady = true;
if (input.retry.retryRequested) {
result.retryRequired = true;
if (input.retry.maxAttempts > 0 && input.retry.attempt >= input.retry.maxAttempts) {
return stoppedResult(
std::move(result),
LiteWalletSyncExecutionReadinessStatus::WaitingForRetry,
LiteWalletSyncExecutionReadinessIssue::RetryLimitReached,
"lite sync retry limit has been reached");
}
}
result.ok = true;
result.status = LiteWalletSyncExecutionReadinessStatus::ReadyToEnableSyncExecution;
result.syncExecutionCouldStart = true;
result.syncStatusPollingCouldStart = true;
result.executionWouldUseBridge = true;
result.enablementPlan.readyToEnable = true;
result.enablementPlan.startSyncExecutionEnabled = true;
result.enablementPlan.syncStatusPollingEnabled = true;
return result;
}
LiteWalletSyncExecutionReadinessPlanner::LiteWalletSyncExecutionReadinessPlanner(
LiteWalletSyncExecutionReadinessOptions options)
: options_(options)
{
}
LiteWalletSyncExecutionReadinessResult LiteWalletSyncExecutionReadinessPlanner::evaluate(
const LiteWalletSyncExecutionReadinessInput& input) const
{
return evaluateLiteWalletSyncExecutionReadiness(input, options_);
}
} // namespace dragonx::wallet

View File

@@ -1,238 +0,0 @@
#pragma once
#include "lite_wallet_sync_app_refresh_integration.h"
#include "wallet_capabilities.h"
#include <cstddef>
#include <string>
#include <vector>
namespace dragonx::wallet {
enum class LiteWalletSyncExecutionReadinessStatus {
ReadyToEnableSyncExecution,
WaitingForLiteBuild,
WaitingForArtifact,
WaitingForBackendLink,
WaitingForBridge,
WaitingForIntegration,
WaitingForExecutionOwner,
WaitingForCancellation,
WaitingForShutdown,
WaitingForRetry,
WaitingForRecovery,
UnsafePlan,
};
enum class LiteWalletSyncExecutionReadinessIssue {
FullNodeBuild,
LiteBackendCapabilityMissing,
ArtifactPathMissing,
ArtifactMissing,
ArtifactUnreadable,
ArtifactNotSdxlCompatible,
ArtifactSymbolsMissing,
ArtifactStringOwnershipUnverified,
ArtifactShutdownUnavailable,
BackendNotLinked,
BridgeUnavailable,
IntegrationRejected,
IntegrationUnsafe,
IntegrationFeedNotReady,
WorkerQueueOwnerMissing,
SyncLoopOwnerMissing,
StartSyncExecutionMissing,
SyncStatusExecutionMissing,
CancellationPathMissing,
CancellationPending,
ShutdownPathMissing,
ShutdownPending,
RetryPolicyMissing,
RetryLimitReached,
UserVisibleStatusMissing,
RecoveryClearMissing,
RecoveryRescanMissing,
RecoveryRestartMissing,
RecoveryUserAttentionMissing,
};
struct LiteWalletSdxlArtifactSymbolsInput {
bool walletExists = false;
bool initializeNew = false;
bool initializeNewFromPhrase = false;
bool initializeExisting = false;
bool execute = false;
bool freeString = false;
bool checkServerOnline = false;
bool shutdown = false;
};
struct LiteWalletSdxlArtifactInput {
bool pathConfigured = false;
bool exists = false;
bool readable = false;
bool sdxlCompatible = false;
std::string artifactPath;
std::string versionLabel;
LiteWalletSdxlArtifactSymbolsInput symbols;
};
struct LiteWalletLinkedBackendReadinessInput {
bool linked = false;
bool bridgeAvailable = false;
WalletBackendStatus status;
std::string bridgeUnavailableReason;
};
struct LiteWalletSyncExecutionOwnershipInput {
bool workerQueueOwnerReady = false;
bool syncLoopOwnerReady = false;
bool startSyncExecutionReady = false;
bool syncStatusPollingReady = false;
bool userVisibleStatusReady = false;
};
struct LiteWalletSyncExecutionCancellationReadinessInput {
bool cancellationPathReady = false;
bool cancellationRequested = false;
bool cancellationComplete = false;
};
struct LiteWalletSyncExecutionShutdownReadinessInput {
bool shutdownHookReady = false;
bool shutdownRequested = false;
bool shutdownComplete = false;
};
struct LiteWalletSyncExecutionRetryReadinessInput {
bool retryPolicyReady = false;
bool retryRequested = false;
std::size_t attempt = 0;
std::size_t maxAttempts = 0;
};
struct LiteWalletSyncExecutionRecoveryReadinessInput {
bool clearActionReady = false;
bool rescanActionReady = false;
bool restartSyncActionReady = false;
bool userAttentionPathReady = false;
};
struct LiteWalletSyncExecutionReadinessInput {
WalletCapabilities capabilities;
LiteWalletSdxlArtifactInput artifact;
LiteWalletLinkedBackendReadinessInput backend;
LiteWalletSyncExecutionOwnershipInput ownership;
LiteWalletSyncExecutionCancellationReadinessInput cancellation;
LiteWalletSyncExecutionShutdownReadinessInput shutdown;
LiteWalletSyncExecutionRetryReadinessInput retry;
LiteWalletSyncExecutionRecoveryReadinessInput recovery;
LiteWalletSyncAppRefreshIntegrationResult integrationReport;
};
struct LiteWalletSyncExecutionReadinessOptions {
bool requireLiteBuild = true;
bool requireLiteBackendCapability = true;
bool requireValidatedArtifact = true;
bool requireLinkedBackend = true;
bool requireBridgeAvailable = true;
bool requireIntegrationFeedReady = true;
bool requireWorkerQueueOwner = true;
bool requireSyncLoopOwner = true;
bool requireStartSyncExecution = true;
bool requireSyncStatusPolling = true;
bool requireCancellationPath = true;
bool requireShutdownHook = true;
bool requireRetryPolicy = true;
bool requireUserVisibleStatus = true;
bool requireRecoveryExecutionReadiness = true;
};
struct LiteWalletSyncExecutionEnablementPlan {
bool readyToEnable = false;
bool startSyncExecutionEnabled = false;
bool syncStatusPollingEnabled = false;
bool workerQueueEnqueued = false;
std::string startSyncCommand;
std::string syncStatusCommand;
std::string workerQueueLane;
LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
};
struct LiteWalletSyncExecutionReadinessIssueInfo {
LiteWalletSyncExecutionReadinessIssue issue = LiteWalletSyncExecutionReadinessIssue::FullNodeBuild;
std::string message;
};
struct LiteWalletSyncExecutionReadinessResult {
bool ok = false;
bool dryRunOnly = true;
bool noNetwork = true;
bool noBridgeCalls = true;
bool noSyncStarted = true;
bool noSyncStatusPolled = true;
bool noWalletPersistence = true;
bool stateMutationAllowed = false;
bool stateMutated = false;
bool walletStateWritten = false;
bool workerQueueEnqueued = false;
bool liteBuildAccepted = false;
bool artifactAccepted = false;
bool backendLinkedAccepted = false;
bool bridgeAccepted = false;
bool integrationAccepted = false;
bool workerQueueOwnerAccepted = false;
bool syncLoopOwnerAccepted = false;
bool startSyncExecutionReady = false;
bool syncStatusPollingReady = false;
bool cancellationReady = false;
bool shutdownReady = false;
bool retryReady = false;
bool userVisibleStatusReady = false;
bool recoveryExecutionReady = false;
bool syncExecutionCouldStart = false;
bool syncStatusPollingCouldStart = false;
bool executionWouldUseBridge = false;
bool integrationFeedReady = false;
bool recoveryRequired = false;
bool cancellationRequired = false;
bool shutdownRequired = false;
bool retryRequired = false;
bool futureClearRequired = false;
bool futureRescanRequired = false;
bool futureRestartSyncRequired = false;
bool requiresUserAttention = false;
LiteWalletSyncExecutionReadinessStatus status = LiteWalletSyncExecutionReadinessStatus::WaitingForLiteBuild;
WalletCapabilities capabilities;
WalletBackendStatus backendStatus;
LiteWalletSyncAppRefreshIntegrationResult integrationReport;
LiteWalletSyncExecutionEnablementPlan enablementPlan;
std::vector<LiteWalletSyncExecutionReadinessIssueInfo> issues;
std::string error;
};
const char* liteWalletSyncExecutionReadinessStatusName(
LiteWalletSyncExecutionReadinessStatus status);
const char* liteWalletSyncExecutionReadinessIssueName(
LiteWalletSyncExecutionReadinessIssue issue);
LiteWalletSyncExecutionReadinessResult evaluateLiteWalletSyncExecutionReadiness(
const LiteWalletSyncExecutionReadinessInput& input,
LiteWalletSyncExecutionReadinessOptions options = {});
class LiteWalletSyncExecutionReadinessPlanner {
public:
explicit LiteWalletSyncExecutionReadinessPlanner(
LiteWalletSyncExecutionReadinessOptions options = {});
LiteWalletSyncExecutionReadinessResult evaluate(
const LiteWalletSyncExecutionReadinessInput& input) const;
private:
LiteWalletSyncExecutionReadinessOptions options_;
};
} // namespace dragonx::wallet