refactor(lite): remove dead backend artifact-contract/resolver scaffold
lite_backend_artifact_{contract,resolver}.{cpp,h} (~1,960 lines) were
app-linked but never invoked: all 14 public entry points
(evaluateLiteBackendArtifactContract/Resolver, evaluateLiteBackendActivation-
Readiness, the resolve*/...Name helpers) had zero callers in the app, the
lite_smoke tool, build scripts, or surviving tests. The real backend load
path (LiteClientBridge::linkedSdxl) uses direct litelib_* externs, and the
DRAGONX_ENABLE_LITE_BACKEND symbol check is done in CMake against the symbols
inventory (FATAL_ERROR on a missing symbol) — not via these C++ files. The
files were saturated with churn markers (disabled / dry-dispatch / scaffold).
- Delete the four artifact files and their 8 CMakeLists references.
- Drop the orphaned test cruft in test_phase4.cpp: the contract include,
5 type aliases, and 3 never-called helpers (heapConstructPlanResult,
makeReadyLiteBackendArtifactProvenance, liteBackendArtifactContractHasIssue)
left over from the already-removed bridge-runtime tests.
- Correct the CLAUDE.md lite-wallet description (it credited these files with
backend validation that CMake actually performs) and drop the stale
lite_bridge_runtime mention.
Both variants build; full test suite passes; source-hygiene check clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -51,7 +51,7 @@ There is no per-test filtering — it is one binary that runs every assertion. T
|
|||||||
|
|
||||||
**UI** (`src/ui/`): `windows/` are the tabs and dialogs (one pair per screen, e.g. `send_tab`, `mining_tab`, `console_tab`), `pages/` are multi-section screens (Settings), `screens/` are layout headers, `material/` is the design-system layer, `schema/` loads the TOML UI schema/skins, `effects/` is GL post-processing (blur/acrylic).
|
**UI** (`src/ui/`): `windows/` are the tabs and dialogs (one pair per screen, e.g. `send_tab`, `mining_tab`, `console_tab`), `pages/` are multi-section screens (Settings), `screens/` are layout headers, `material/` is the design-system layer, `schema/` loads the TOML UI schema/skins, `effects/` is GL post-processing (blur/acrylic).
|
||||||
|
|
||||||
**Lite wallet** (`src/wallet/`): the bridge to an external `litelib_*` C-ABI backend (`lite_client_bridge`, `lite_bridge_runtime`, `lite_connection_service`, `lite_sync_service`, result parsers, and the artifact-contract/resolver that validates a prebuilt backend library). The real frontend entry points are `lite_wallet_lifecycle_ui_adapter` and `lite_wallet_server_selection_adapter` (used by `src/ui/pages/settings_page.cpp`); everything else is reachable through them.
|
**Lite wallet** (`src/wallet/`): the bridge to an external `litelib_*` C-ABI backend. `lite_client_bridge` loads the backend (via direct `litelib_*` externs in `linkedSdxl()`) and owns each Rust string through `lite_owned_string` (copy-before-free / free-once). On top sit `lite_connection_service`, `lite_sync_service`, `lite_result_parsers`, `lite_wallet_gateway`, `lite_wallet_state_mapper`, and `lite_wallet_lifecycle_service`, all driven by `lite_wallet_controller`. The real frontend entry points are `lite_wallet_lifecycle_ui_adapter` and `lite_wallet_server_selection_adapter` (used by `src/ui/pages/settings_page.cpp`); everything else is reachable through them. (The prebuilt-backend symbol check for `DRAGONX_ENABLE_LITE_BACKEND` is done in CMake against the symbols inventory — see below — not in C++.)
|
||||||
|
|
||||||
> ⚠️ **Do not regrow the `_plan`/`_batch` churn.** This directory previously held ~160 dead `lite_wallet_*_plan` / `*_batch*_receipt_custody_acceptance_confirmation_archive_handoff_*` files (filenames up to 250 chars) — auto-generated scaffolding that never reached the shipping binary. They were deleted. When extending lite-wallet behavior, **edit the named service/bridge/runtime files in place**; never add another "promotion/receipt/custody/handoff/stewardship" wrapper layer. `scripts/check-source-hygiene.sh` (wired as a `.git/hooks/pre-commit` hook) blocks >80-char filenames and chained churn-token names — run it in CI too.
|
> ⚠️ **Do not regrow the `_plan`/`_batch` churn.** This directory previously held ~160 dead `lite_wallet_*_plan` / `*_batch*_receipt_custody_acceptance_confirmation_archive_handoff_*` files (filenames up to 250 chars) — auto-generated scaffolding that never reached the shipping binary. They were deleted. When extending lite-wallet behavior, **edit the named service/bridge/runtime files in place**; never add another "promotion/receipt/custody/handoff/stewardship" wrapper layer. `scripts/check-source-hygiene.sh` (wired as a `.git/hooks/pre-commit` hook) blocks >80-char filenames and chained churn-token names — run it in CI too.
|
||||||
|
|
||||||
|
|||||||
@@ -389,8 +389,6 @@ set(APP_SOURCES
|
|||||||
src/services/wallet_security_workflow.cpp
|
src/services/wallet_security_workflow.cpp
|
||||||
src/services/wallet_security_workflow_executor.cpp
|
src/services/wallet_security_workflow_executor.cpp
|
||||||
src/chat/chat_protocol.cpp
|
src/chat/chat_protocol.cpp
|
||||||
src/wallet/lite_backend_artifact_contract.cpp
|
|
||||||
src/wallet/lite_backend_artifact_resolver.cpp
|
|
||||||
src/wallet/lite_owned_string.cpp
|
src/wallet/lite_owned_string.cpp
|
||||||
src/wallet/lite_client_bridge.cpp
|
src/wallet/lite_client_bridge.cpp
|
||||||
src/wallet/lite_connection_service.cpp
|
src/wallet/lite_connection_service.cpp
|
||||||
@@ -505,8 +503,6 @@ set(APP_HEADERS
|
|||||||
src/services/wallet_security_workflow_executor.h
|
src/services/wallet_security_workflow_executor.h
|
||||||
src/wallet/wallet_capabilities.h
|
src/wallet/wallet_capabilities.h
|
||||||
src/wallet/wallet_backend.h
|
src/wallet/wallet_backend.h
|
||||||
src/wallet/lite_backend_artifact_contract.h
|
|
||||||
src/wallet/lite_backend_artifact_resolver.h
|
|
||||||
src/wallet/lite_owned_string.h
|
src/wallet/lite_owned_string.h
|
||||||
src/wallet/lite_client_bridge.h
|
src/wallet/lite_client_bridge.h
|
||||||
src/wallet/lite_connection_service.h
|
src/wallet/lite_connection_service.h
|
||||||
@@ -693,8 +689,6 @@ if(DRAGONX_LITE_BACKEND_READY)
|
|||||||
tools/lite_smoke.cpp
|
tools/lite_smoke.cpp
|
||||||
src/wallet/lite_client_bridge.cpp
|
src/wallet/lite_client_bridge.cpp
|
||||||
src/wallet/lite_owned_string.cpp
|
src/wallet/lite_owned_string.cpp
|
||||||
src/wallet/lite_backend_artifact_contract.cpp
|
|
||||||
src/wallet/lite_backend_artifact_resolver.cpp
|
|
||||||
src/wallet/lite_connection_service.cpp
|
src/wallet/lite_connection_service.cpp
|
||||||
src/wallet/lite_result_parsers.cpp
|
src/wallet/lite_result_parsers.cpp
|
||||||
)
|
)
|
||||||
@@ -939,8 +933,6 @@ if(BUILD_TESTING)
|
|||||||
src/services/wallet_security_workflow.cpp
|
src/services/wallet_security_workflow.cpp
|
||||||
src/services/wallet_security_workflow_executor.cpp
|
src/services/wallet_security_workflow_executor.cpp
|
||||||
src/chat/chat_protocol.cpp
|
src/chat/chat_protocol.cpp
|
||||||
src/wallet/lite_backend_artifact_contract.cpp
|
|
||||||
src/wallet/lite_backend_artifact_resolver.cpp
|
|
||||||
src/wallet/lite_owned_string.cpp
|
src/wallet/lite_owned_string.cpp
|
||||||
src/wallet/lite_client_bridge.cpp
|
src/wallet/lite_client_bridge.cpp
|
||||||
src/wallet/lite_connection_service.cpp
|
src/wallet/lite_connection_service.cpp
|
||||||
|
|||||||
@@ -1,419 +0,0 @@
|
|||||||
#include "wallet/lite_backend_artifact_contract.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cctype>
|
|
||||||
#include <sstream>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace dragonx::wallet {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr const char* kSupportedAbiVersion = "sdxl-c-v1";
|
|
||||||
|
|
||||||
using Issue = LiteBackendArtifactContractIssue;
|
|
||||||
using Status = LiteBackendArtifactContractStatus;
|
|
||||||
|
|
||||||
void addIssue(LiteBackendArtifactContractResult& result, Issue issue, std::string message)
|
|
||||||
{
|
|
||||||
result.issues.push_back({issue, std::move(message)});
|
|
||||||
if (result.error.empty()) result.error = result.issues.back().message;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactContractResult stoppedResult(
|
|
||||||
LiteBackendArtifactContractResult result,
|
|
||||||
Status status,
|
|
||||||
Issue issue,
|
|
||||||
std::string message)
|
|
||||||
{
|
|
||||||
result.status = status;
|
|
||||||
addIssue(result, issue, std::move(message));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string trimCopy(const std::string& value)
|
|
||||||
{
|
|
||||||
auto begin = value.begin();
|
|
||||||
while (begin != value.end() && std::isspace(static_cast<unsigned char>(*begin))) ++begin;
|
|
||||||
|
|
||||||
auto end = value.end();
|
|
||||||
while (end != begin && std::isspace(static_cast<unsigned char>(*(end - 1)))) --end;
|
|
||||||
|
|
||||||
return std::string(begin, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool containsSymbol(const std::vector<std::string>& exportedSymbols, const char* abiName)
|
|
||||||
{
|
|
||||||
return std::find(exportedSymbols.begin(), exportedSymbols.end(), abiName) != exportedSymbols.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool importedArtifactKindLinkable(LiteBackendArtifactKind kind)
|
|
||||||
{
|
|
||||||
return kind == LiteBackendArtifactKind::StaticLibrary || kind == LiteBackendArtifactKind::SharedLibrary;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool signatureTrustMetadataProvided(const LiteBackendArtifactSignatureVerificationMetadata& signature)
|
|
||||||
{
|
|
||||||
return !trimCopy(signature.keyFingerprint).empty() || !trimCopy(signature.certificateIdentity).empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactContractResult validateSignatureMetadata(
|
|
||||||
LiteBackendArtifactContractResult result,
|
|
||||||
const LiteBackendArtifactContractInput& input,
|
|
||||||
LiteBackendArtifactContractOptions options)
|
|
||||||
{
|
|
||||||
const auto& signature = input.signatureVerification;
|
|
||||||
result.signatureRequiredForRelease = signature.requiredForRelease;
|
|
||||||
const bool shouldValidate = signature.requiredForRelease ||
|
|
||||||
(options.validateOptionalSignatureMetadata && signature.metadataProvided);
|
|
||||||
|
|
||||||
if (!shouldValidate) {
|
|
||||||
result.signatureMetadataAccepted = true;
|
|
||||||
result.signatureVerificationForwarded = signature.metadataProvided;
|
|
||||||
result.signatureVerified = signature.verified;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.requireSignatureMetadataWhenRequired && !signature.policyDefined) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForSignatureMetadata, Issue::SignaturePolicyMissing,
|
|
||||||
"lite backend artifact signature policy is not defined");
|
|
||||||
}
|
|
||||||
if (!signature.metadataProvided) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForSignatureMetadata, Issue::SignatureMetadataMissing,
|
|
||||||
"lite backend artifact signature metadata is required but missing");
|
|
||||||
}
|
|
||||||
if (trimCopy(signature.signatureFormat).empty() ||
|
|
||||||
trimCopy(signature.signaturePath).empty() ||
|
|
||||||
trimCopy(signature.verificationTool).empty() ||
|
|
||||||
trimCopy(signature.verifiedArtifactSha256).empty()) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForSignatureMetadata, Issue::SignatureMetadataIncomplete,
|
|
||||||
"lite backend artifact signature metadata is incomplete");
|
|
||||||
}
|
|
||||||
if (!signatureTrustMetadataProvided(signature)) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForSignatureMetadata, Issue::SignatureTrustMetadataMissing,
|
|
||||||
"lite backend artifact signature metadata is missing a reviewed trust identity");
|
|
||||||
}
|
|
||||||
if (!signature.verificationPerformed) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForSignatureMetadata, Issue::SignatureVerificationMissing,
|
|
||||||
"lite backend artifact signature verification has not been performed");
|
|
||||||
}
|
|
||||||
if (!signature.verified) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForSignatureMetadata, Issue::SignatureVerificationFailed,
|
|
||||||
"lite backend artifact signature verification did not pass");
|
|
||||||
}
|
|
||||||
if (!trimCopy(input.artifactSha256).empty() && signature.verifiedArtifactSha256 != input.artifactSha256) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForSignatureMetadata, Issue::SignatureVerifiedArtifactShaMismatch,
|
|
||||||
"lite backend artifact signature metadata does not match the artifact SHA-256");
|
|
||||||
}
|
|
||||||
|
|
||||||
result.signatureMetadataAccepted = true;
|
|
||||||
result.signatureVerificationForwarded = true;
|
|
||||||
result.signatureVerified = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactContractResult rejectRuntimeActions(
|
|
||||||
LiteBackendArtifactContractResult result,
|
|
||||||
const LiteBackendArtifactContractInput& input,
|
|
||||||
LiteBackendArtifactContractOptions options)
|
|
||||||
{
|
|
||||||
if (!options.rejectRuntimeActions) return result;
|
|
||||||
if (input.artifactMutationRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::ArtifactMutationRequested,
|
|
||||||
"lite backend artifact contract cannot mutate artifacts");
|
|
||||||
}
|
|
||||||
if (input.dynamicLibraryLoadRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::DynamicLibraryLoadRequested,
|
|
||||||
"lite backend artifact contract cannot load dynamic libraries");
|
|
||||||
}
|
|
||||||
if (input.dynamicLibraryUnloadRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::DynamicLibraryUnloadRequested,
|
|
||||||
"lite backend artifact contract cannot unload dynamic libraries");
|
|
||||||
}
|
|
||||||
if (input.symbolResolutionRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::SymbolResolutionRequested,
|
|
||||||
"lite backend artifact contract cannot resolve runtime symbols");
|
|
||||||
}
|
|
||||||
if (input.sdxlApiRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::SdxlApiRequested,
|
|
||||||
"lite backend artifact contract cannot call SDXL APIs");
|
|
||||||
}
|
|
||||||
if (input.bridgeCallRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::BridgeCallRequested,
|
|
||||||
"lite backend artifact contract cannot call the bridge");
|
|
||||||
}
|
|
||||||
if (input.serverConnectivityCheckRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::ServerConnectivityCheckRequested,
|
|
||||||
"lite backend artifact contract cannot check server connectivity");
|
|
||||||
}
|
|
||||||
if (input.walletLifecycleRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::WalletLifecycleRequested,
|
|
||||||
"lite backend artifact contract cannot execute wallet lifecycle flows");
|
|
||||||
}
|
|
||||||
if (input.syncRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::SyncRequested,
|
|
||||||
"lite backend artifact contract cannot start sync");
|
|
||||||
}
|
|
||||||
if (input.syncStatusPollingRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::SyncStatusPollingRequested,
|
|
||||||
"lite backend artifact contract cannot poll syncstatus");
|
|
||||||
}
|
|
||||||
if (input.workerQueueRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::WorkerQueueRequested,
|
|
||||||
"lite backend artifact contract cannot enqueue workers");
|
|
||||||
}
|
|
||||||
if (input.walletStateMutationRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::WalletStateMutationRequested,
|
|
||||||
"lite backend artifact contract cannot mutate WalletState");
|
|
||||||
}
|
|
||||||
if (input.walletPersistenceRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::WalletPersistenceRequested,
|
|
||||||
"lite backend artifact contract cannot persist wallet files");
|
|
||||||
}
|
|
||||||
if (input.uploadRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::UploadRequested,
|
|
||||||
"lite backend artifact contract cannot upload artifacts");
|
|
||||||
}
|
|
||||||
if (input.signingRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::SigningRequested,
|
|
||||||
"lite backend artifact contract cannot sign artifacts");
|
|
||||||
}
|
|
||||||
if (input.publicationRequested) {
|
|
||||||
return stoppedResult(std::move(result), Status::RuntimeActionDisabled, Issue::PublicationRequested,
|
|
||||||
"lite backend artifact contract cannot publish artifacts");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
const char* liteBackendArtifactContractSupportedAbiVersion()
|
|
||||||
{
|
|
||||||
return kSupportedAbiVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* liteBackendArtifactContractLinkModeName(LiteBackendArtifactContractLinkMode linkMode)
|
|
||||||
{
|
|
||||||
switch (linkMode) {
|
|
||||||
case LiteBackendArtifactContractLinkMode::ImportedLibrary: return "ImportedLibrary";
|
|
||||||
case LiteBackendArtifactContractLinkMode::RuntimeDynamicLibrary: return "RuntimeDynamicLibrary";
|
|
||||||
case LiteBackendArtifactContractLinkMode::ExternalExecutable: return "ExternalExecutable";
|
|
||||||
}
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* liteBackendArtifactContractStatusName(LiteBackendArtifactContractStatus status)
|
|
||||||
{
|
|
||||||
switch (status) {
|
|
||||||
case LiteBackendArtifactContractStatus::ReadyForResolver: return "ReadyForResolver";
|
|
||||||
case LiteBackendArtifactContractStatus::WaitingForContractOwner: return "WaitingForContractOwner";
|
|
||||||
case LiteBackendArtifactContractStatus::WaitingForReadOnlyGate: return "WaitingForReadOnlyGate";
|
|
||||||
case LiteBackendArtifactContractStatus::WaitingForLinkMode: return "WaitingForLinkMode";
|
|
||||||
case LiteBackendArtifactContractStatus::WaitingForArtifactPath: return "WaitingForArtifactPath";
|
|
||||||
case LiteBackendArtifactContractStatus::WaitingForArtifactKind: return "WaitingForArtifactKind";
|
|
||||||
case LiteBackendArtifactContractStatus::WaitingForAbiVersion: return "WaitingForAbiVersion";
|
|
||||||
case LiteBackendArtifactContractStatus::WaitingForSymbolInventory: return "WaitingForSymbolInventory";
|
|
||||||
case LiteBackendArtifactContractStatus::WaitingForRequiredSymbols: return "WaitingForRequiredSymbols";
|
|
||||||
case LiteBackendArtifactContractStatus::WaitingForSignatureMetadata: return "WaitingForSignatureMetadata";
|
|
||||||
case LiteBackendArtifactContractStatus::RuntimeActionDisabled: return "RuntimeActionDisabled";
|
|
||||||
}
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* liteBackendArtifactContractIssueName(LiteBackendArtifactContractIssue issue)
|
|
||||||
{
|
|
||||||
switch (issue) {
|
|
||||||
#define DRAGONX_CASE(value) case LiteBackendArtifactContractIssue::value: return #value
|
|
||||||
DRAGONX_CASE(ContractOwnerMissing);
|
|
||||||
DRAGONX_CASE(ReadOnlyGateMissing);
|
|
||||||
DRAGONX_CASE(RuntimeDynamicLinkDeferred);
|
|
||||||
DRAGONX_CASE(ExternalExecutableDeferred);
|
|
||||||
DRAGONX_CASE(ArtifactPathMissing);
|
|
||||||
DRAGONX_CASE(ArtifactKindNotLinkable);
|
|
||||||
DRAGONX_CASE(AbiVersionMissing);
|
|
||||||
DRAGONX_CASE(AbiVersionUnsupported);
|
|
||||||
DRAGONX_CASE(SymbolInventoryOwnerMissing);
|
|
||||||
DRAGONX_CASE(SymbolInventoryMissing);
|
|
||||||
DRAGONX_CASE(RequiredSymbolMissing);
|
|
||||||
DRAGONX_CASE(SignaturePolicyMissing);
|
|
||||||
DRAGONX_CASE(SignatureMetadataMissing);
|
|
||||||
DRAGONX_CASE(SignatureMetadataIncomplete);
|
|
||||||
DRAGONX_CASE(SignatureVerificationMissing);
|
|
||||||
DRAGONX_CASE(SignatureVerificationFailed);
|
|
||||||
DRAGONX_CASE(SignatureVerifiedArtifactShaMismatch);
|
|
||||||
DRAGONX_CASE(SignatureTrustMetadataMissing);
|
|
||||||
DRAGONX_CASE(ArtifactMutationRequested);
|
|
||||||
DRAGONX_CASE(DynamicLibraryLoadRequested);
|
|
||||||
DRAGONX_CASE(DynamicLibraryUnloadRequested);
|
|
||||||
DRAGONX_CASE(SymbolResolutionRequested);
|
|
||||||
DRAGONX_CASE(SdxlApiRequested);
|
|
||||||
DRAGONX_CASE(BridgeCallRequested);
|
|
||||||
DRAGONX_CASE(ServerConnectivityCheckRequested);
|
|
||||||
DRAGONX_CASE(WalletLifecycleRequested);
|
|
||||||
DRAGONX_CASE(SyncRequested);
|
|
||||||
DRAGONX_CASE(SyncStatusPollingRequested);
|
|
||||||
DRAGONX_CASE(WorkerQueueRequested);
|
|
||||||
DRAGONX_CASE(WalletStateMutationRequested);
|
|
||||||
DRAGONX_CASE(WalletPersistenceRequested);
|
|
||||||
DRAGONX_CASE(UploadRequested);
|
|
||||||
DRAGONX_CASE(SigningRequested);
|
|
||||||
DRAGONX_CASE(PublicationRequested);
|
|
||||||
#undef DRAGONX_CASE
|
|
||||||
}
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<LiteBackendArtifactContractSymbol> liteBackendArtifactContractRequiredSymbols()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
{"walletExists", "litelib_wallet_exists", false, false, true, false, false, false},
|
|
||||||
{"initializeNew", "litelib_initialize_new", true, false, true, false, false, false},
|
|
||||||
{"initializeNewFromPhrase", "litelib_initialize_new_from_phrase", true, false, true, false, false, false},
|
|
||||||
{"initializeExisting", "litelib_initialize_existing", true, false, true, false, false, false},
|
|
||||||
{"execute", "litelib_execute", true, false, false, true, false, false},
|
|
||||||
{"freeString", "litelib_rust_free_string", false, true, true, true, false, false},
|
|
||||||
{"checkServerOnline", "litelib_check_server_online", false, false, false, false, true, false},
|
|
||||||
{"shutdown", "litelib_shutdown", false, false, true, true, true, true},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteWalletSdxlArtifactSymbolsInput liteBackendArtifactSymbolsFromExportedNames(
|
|
||||||
const std::vector<std::string>& exportedSymbols)
|
|
||||||
{
|
|
||||||
LiteWalletSdxlArtifactSymbolsInput symbols;
|
|
||||||
symbols.walletExists = containsSymbol(exportedSymbols, "litelib_wallet_exists");
|
|
||||||
symbols.initializeNew = containsSymbol(exportedSymbols, "litelib_initialize_new");
|
|
||||||
symbols.initializeNewFromPhrase = containsSymbol(exportedSymbols, "litelib_initialize_new_from_phrase");
|
|
||||||
symbols.initializeExisting = containsSymbol(exportedSymbols, "litelib_initialize_existing");
|
|
||||||
symbols.execute = containsSymbol(exportedSymbols, "litelib_execute");
|
|
||||||
symbols.freeString = containsSymbol(exportedSymbols, "litelib_rust_free_string");
|
|
||||||
symbols.checkServerOnline = containsSymbol(exportedSymbols, "litelib_check_server_online");
|
|
||||||
symbols.shutdown = containsSymbol(exportedSymbols, "litelib_shutdown");
|
|
||||||
return symbols;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactContractResult evaluateLiteBackendArtifactContract(
|
|
||||||
const LiteBackendArtifactContractInput& input,
|
|
||||||
LiteBackendArtifactContractOptions options)
|
|
||||||
{
|
|
||||||
LiteBackendArtifactContractResult result;
|
|
||||||
result.requiredSymbolCount = liteBackendArtifactContractRequiredSymbols().size();
|
|
||||||
result.exportedSymbolCount = input.exportedSymbols.size();
|
|
||||||
|
|
||||||
result = rejectRuntimeActions(std::move(result), input, options);
|
|
||||||
if (!result.issues.empty()) return result;
|
|
||||||
|
|
||||||
if (options.requireContractOwner && !input.contractOwnerReady) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForContractOwner, Issue::ContractOwnerMissing,
|
|
||||||
"lite backend artifact contract owner is not ready");
|
|
||||||
}
|
|
||||||
result.contractOwnerAccepted = true;
|
|
||||||
|
|
||||||
if (options.requireReadOnlyGate && !input.readOnlyGateReady) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForReadOnlyGate, Issue::ReadOnlyGateMissing,
|
|
||||||
"lite backend artifact contract read-only gate is not ready");
|
|
||||||
}
|
|
||||||
result.readOnlyGateAccepted = true;
|
|
||||||
|
|
||||||
if (options.requireImportedLibraryLinkMode && input.linkMode == LiteBackendArtifactContractLinkMode::RuntimeDynamicLibrary) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForLinkMode, Issue::RuntimeDynamicLinkDeferred,
|
|
||||||
"runtime dynamic loading is deferred to the bridge runtime owner phase");
|
|
||||||
}
|
|
||||||
if (options.requireImportedLibraryLinkMode && input.linkMode == LiteBackendArtifactContractLinkMode::ExternalExecutable) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForLinkMode, Issue::ExternalExecutableDeferred,
|
|
||||||
"external executable bridge mode is not the Phase 1 production link contract");
|
|
||||||
}
|
|
||||||
result.importedLinkModeAccepted = input.linkMode == LiteBackendArtifactContractLinkMode::ImportedLibrary;
|
|
||||||
|
|
||||||
if (trimCopy(input.artifactPath).empty()) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForArtifactPath, Issue::ArtifactPathMissing,
|
|
||||||
"lite backend artifact contract requires an artifact path");
|
|
||||||
}
|
|
||||||
result.artifactPathAccepted = true;
|
|
||||||
|
|
||||||
if (!importedArtifactKindLinkable(input.artifactKind)) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForArtifactKind, Issue::ArtifactKindNotLinkable,
|
|
||||||
"Phase 1 imported link mode requires a static or shared library artifact");
|
|
||||||
}
|
|
||||||
result.artifactKindAccepted = true;
|
|
||||||
|
|
||||||
if (options.requireAbiVersion && trimCopy(input.abiVersion).empty()) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForAbiVersion, Issue::AbiVersionMissing,
|
|
||||||
"lite backend artifact ABI version is missing");
|
|
||||||
}
|
|
||||||
if (options.requireAbiVersion && input.abiVersion != kSupportedAbiVersion) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForAbiVersion, Issue::AbiVersionUnsupported,
|
|
||||||
"lite backend artifact ABI version is unsupported");
|
|
||||||
}
|
|
||||||
result.abiVersionAccepted = true;
|
|
||||||
|
|
||||||
result = validateSignatureMetadata(std::move(result), input, options);
|
|
||||||
if (!result.issues.empty()) return result;
|
|
||||||
|
|
||||||
if (options.requireSymbolInventory && !input.symbolInventoryOwnerReady) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForSymbolInventory, Issue::SymbolInventoryOwnerMissing,
|
|
||||||
"lite backend artifact symbol inventory owner is not ready");
|
|
||||||
}
|
|
||||||
if (options.requireSymbolInventory && input.exportedSymbols.empty()) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForSymbolInventory, Issue::SymbolInventoryMissing,
|
|
||||||
"lite backend artifact exported symbol inventory is missing");
|
|
||||||
}
|
|
||||||
result.symbolInventoryAccepted = true;
|
|
||||||
|
|
||||||
result.symbols = liteBackendArtifactSymbolsFromExportedNames(input.exportedSymbols);
|
|
||||||
for (const auto& symbol : liteBackendArtifactContractRequiredSymbols()) {
|
|
||||||
if (!containsSymbol(input.exportedSymbols, symbol.abiName.c_str())) {
|
|
||||||
result.missingSymbols.push_back(symbol.abiName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (options.requireAllRequiredSymbols && !result.missingSymbols.empty()) {
|
|
||||||
return stoppedResult(std::move(result), Status::WaitingForRequiredSymbols, Issue::RequiredSymbolMissing,
|
|
||||||
"lite backend artifact is missing required C ABI symbols");
|
|
||||||
}
|
|
||||||
result.requiredSymbolsAccepted = true;
|
|
||||||
|
|
||||||
result.resolverCandidate.configured = true;
|
|
||||||
result.resolverCandidate.artifactPath = input.artifactPath;
|
|
||||||
result.resolverCandidate.platform = input.platform;
|
|
||||||
result.resolverCandidate.kind = input.artifactKind;
|
|
||||||
result.resolverCandidate.versionLabel = input.abiVersion;
|
|
||||||
result.resolverCandidate.provenance = input.provenance;
|
|
||||||
result.resolverCandidate.signatureVerification = input.signatureVerification;
|
|
||||||
result.resolverCandidate.sdxlCompatible = input.sdxlCompatible;
|
|
||||||
result.resolverCandidate.symbols = result.symbols;
|
|
||||||
result.resolverCandidate.executableMetadataRequired = false;
|
|
||||||
|
|
||||||
result.resolverInput.resolverOwnerReady = true;
|
|
||||||
result.resolverInput.readOnlyGateReady = true;
|
|
||||||
result.resolverInput.projectRoot = input.projectRoot;
|
|
||||||
result.resolverInput.expectedPlatform = input.platform;
|
|
||||||
result.resolverInput.candidates.push_back(result.resolverCandidate);
|
|
||||||
result.resolverInputProduced = true;
|
|
||||||
result.provenanceForwarded = input.provenance.ownerReady && input.provenance.metadataProvided;
|
|
||||||
result.signatureVerificationForwarded = input.signatureVerification.metadataProvided;
|
|
||||||
result.sdxlCompatibilityForwarded = input.sdxlCompatible;
|
|
||||||
result.dynamicLibraryLoadAllowed = false;
|
|
||||||
result.symbolResolutionAllowed = false;
|
|
||||||
result.runtimeActivationAllowed = false;
|
|
||||||
result.ok = true;
|
|
||||||
result.status = Status::ReadyForResolver;
|
|
||||||
|
|
||||||
std::ostringstream summary;
|
|
||||||
summary << "lite_backend_artifact_contract=ready"
|
|
||||||
<< ";abi=" << input.abiVersion
|
|
||||||
<< ";link_mode=" << liteBackendArtifactContractLinkModeName(input.linkMode)
|
|
||||||
<< ";kind=" << liteBackendArtifactKindName(input.artifactKind)
|
|
||||||
<< ";symbols=" << result.requiredSymbolCount
|
|
||||||
<< ";signature_required=" << (result.signatureRequiredForRelease ? "true" : "false")
|
|
||||||
<< ";signature_verified=" << (result.signatureVerified ? "true" : "false")
|
|
||||||
<< ";dynamic_loading=false;runtime_activation=false";
|
|
||||||
result.summary = summary.str();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactResolverInput liteBackendArtifactResolverInputFromContractResult(
|
|
||||||
const LiteBackendArtifactContractResult& result)
|
|
||||||
{
|
|
||||||
return result.resolverInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dragonx::wallet
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "lite_backend_artifact_resolver.h"
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace dragonx::wallet {
|
|
||||||
|
|
||||||
enum class LiteBackendArtifactContractLinkMode {
|
|
||||||
ImportedLibrary,
|
|
||||||
RuntimeDynamicLibrary,
|
|
||||||
ExternalExecutable,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class LiteBackendArtifactContractStatus {
|
|
||||||
ReadyForResolver,
|
|
||||||
WaitingForContractOwner,
|
|
||||||
WaitingForReadOnlyGate,
|
|
||||||
WaitingForLinkMode,
|
|
||||||
WaitingForArtifactPath,
|
|
||||||
WaitingForArtifactKind,
|
|
||||||
WaitingForAbiVersion,
|
|
||||||
WaitingForSymbolInventory,
|
|
||||||
WaitingForRequiredSymbols,
|
|
||||||
WaitingForSignatureMetadata,
|
|
||||||
RuntimeActionDisabled,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class LiteBackendArtifactContractIssue {
|
|
||||||
ContractOwnerMissing,
|
|
||||||
ReadOnlyGateMissing,
|
|
||||||
RuntimeDynamicLinkDeferred,
|
|
||||||
ExternalExecutableDeferred,
|
|
||||||
ArtifactPathMissing,
|
|
||||||
ArtifactKindNotLinkable,
|
|
||||||
AbiVersionMissing,
|
|
||||||
AbiVersionUnsupported,
|
|
||||||
SymbolInventoryOwnerMissing,
|
|
||||||
SymbolInventoryMissing,
|
|
||||||
RequiredSymbolMissing,
|
|
||||||
SignaturePolicyMissing,
|
|
||||||
SignatureMetadataMissing,
|
|
||||||
SignatureMetadataIncomplete,
|
|
||||||
SignatureVerificationMissing,
|
|
||||||
SignatureVerificationFailed,
|
|
||||||
SignatureVerifiedArtifactShaMismatch,
|
|
||||||
SignatureTrustMetadataMissing,
|
|
||||||
ArtifactMutationRequested,
|
|
||||||
DynamicLibraryLoadRequested,
|
|
||||||
DynamicLibraryUnloadRequested,
|
|
||||||
SymbolResolutionRequested,
|
|
||||||
SdxlApiRequested,
|
|
||||||
BridgeCallRequested,
|
|
||||||
ServerConnectivityCheckRequested,
|
|
||||||
WalletLifecycleRequested,
|
|
||||||
SyncRequested,
|
|
||||||
SyncStatusPollingRequested,
|
|
||||||
WorkerQueueRequested,
|
|
||||||
WalletStateMutationRequested,
|
|
||||||
WalletPersistenceRequested,
|
|
||||||
UploadRequested,
|
|
||||||
SigningRequested,
|
|
||||||
PublicationRequested,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactContractSymbol {
|
|
||||||
std::string logicalName;
|
|
||||||
std::string abiName;
|
|
||||||
bool returnsOwnedString = false;
|
|
||||||
bool cleanupFunction = false;
|
|
||||||
bool requiredForLifecycle = false;
|
|
||||||
bool requiredForSync = false;
|
|
||||||
bool requiredForServerCheck = false;
|
|
||||||
bool requiredForShutdown = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactContractInput {
|
|
||||||
bool contractOwnerReady = false;
|
|
||||||
bool readOnlyGateReady = false;
|
|
||||||
std::string projectRoot;
|
|
||||||
std::string artifactPath;
|
|
||||||
LiteBackendArtifactPlatform platform = LiteBackendArtifactPlatform::Current;
|
|
||||||
LiteBackendArtifactKind artifactKind = LiteBackendArtifactKind::Unknown;
|
|
||||||
LiteBackendArtifactContractLinkMode linkMode = LiteBackendArtifactContractLinkMode::ImportedLibrary;
|
|
||||||
std::string abiVersion;
|
|
||||||
std::string artifactSha256;
|
|
||||||
LiteBackendArtifactProvenanceMetadata provenance;
|
|
||||||
LiteBackendArtifactSignatureVerificationMetadata signatureVerification;
|
|
||||||
bool sdxlCompatible = false;
|
|
||||||
bool symbolInventoryOwnerReady = false;
|
|
||||||
std::vector<std::string> exportedSymbols;
|
|
||||||
|
|
||||||
bool artifactMutationRequested = false;
|
|
||||||
bool dynamicLibraryLoadRequested = false;
|
|
||||||
bool dynamicLibraryUnloadRequested = false;
|
|
||||||
bool symbolResolutionRequested = false;
|
|
||||||
bool sdxlApiRequested = false;
|
|
||||||
bool bridgeCallRequested = false;
|
|
||||||
bool serverConnectivityCheckRequested = false;
|
|
||||||
bool walletLifecycleRequested = false;
|
|
||||||
bool syncRequested = false;
|
|
||||||
bool syncStatusPollingRequested = false;
|
|
||||||
bool workerQueueRequested = false;
|
|
||||||
bool walletStateMutationRequested = false;
|
|
||||||
bool walletPersistenceRequested = false;
|
|
||||||
bool uploadRequested = false;
|
|
||||||
bool signingRequested = false;
|
|
||||||
bool publicationRequested = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactContractOptions {
|
|
||||||
bool requireContractOwner = true;
|
|
||||||
bool requireReadOnlyGate = true;
|
|
||||||
bool requireImportedLibraryLinkMode = true;
|
|
||||||
bool requireAbiVersion = true;
|
|
||||||
bool requireSymbolInventory = true;
|
|
||||||
bool requireAllRequiredSymbols = true;
|
|
||||||
bool requireSignatureMetadataWhenRequired = true;
|
|
||||||
bool validateOptionalSignatureMetadata = true;
|
|
||||||
bool rejectRuntimeActions = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactContractIssueInfo {
|
|
||||||
LiteBackendArtifactContractIssue issue = LiteBackendArtifactContractIssue::ContractOwnerMissing;
|
|
||||||
std::string message;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactContractResult {
|
|
||||||
bool ok = false;
|
|
||||||
bool readOnlyContract = true;
|
|
||||||
bool noArtifactMutation = true;
|
|
||||||
bool noDynamicLibraryLoaded = true;
|
|
||||||
bool noDynamicLibraryUnloaded = true;
|
|
||||||
bool noSymbolResolutionPerformed = true;
|
|
||||||
bool noSdxlCalls = true;
|
|
||||||
bool noBridgeCalls = true;
|
|
||||||
bool noServerConnectivityChecked = true;
|
|
||||||
bool noWalletLifecycle = true;
|
|
||||||
bool noSyncStarted = true;
|
|
||||||
bool noSyncStatusPolled = true;
|
|
||||||
bool noWorkerQueueEnqueue = true;
|
|
||||||
bool noWalletStateMutation = true;
|
|
||||||
bool noWalletPersistence = true;
|
|
||||||
bool noUpload = true;
|
|
||||||
bool noSigning = true;
|
|
||||||
bool noPublication = true;
|
|
||||||
|
|
||||||
bool contractOwnerAccepted = false;
|
|
||||||
bool readOnlyGateAccepted = false;
|
|
||||||
bool importedLinkModeAccepted = false;
|
|
||||||
bool artifactPathAccepted = false;
|
|
||||||
bool artifactKindAccepted = false;
|
|
||||||
bool abiVersionAccepted = false;
|
|
||||||
bool provenanceForwarded = false;
|
|
||||||
bool signatureMetadataAccepted = false;
|
|
||||||
bool signatureVerificationForwarded = false;
|
|
||||||
bool signatureRequiredForRelease = false;
|
|
||||||
bool signatureVerified = false;
|
|
||||||
bool sdxlCompatibilityForwarded = false;
|
|
||||||
bool symbolInventoryAccepted = false;
|
|
||||||
bool requiredSymbolsAccepted = false;
|
|
||||||
bool resolverInputProduced = false;
|
|
||||||
bool dynamicLibraryLoadAllowed = false;
|
|
||||||
bool symbolResolutionAllowed = false;
|
|
||||||
bool runtimeActivationAllowed = false;
|
|
||||||
|
|
||||||
std::size_t requiredSymbolCount = 0;
|
|
||||||
std::size_t exportedSymbolCount = 0;
|
|
||||||
LiteBackendArtifactContractStatus status = LiteBackendArtifactContractStatus::WaitingForContractOwner;
|
|
||||||
LiteWalletSdxlArtifactSymbolsInput symbols;
|
|
||||||
LiteBackendArtifactCandidate resolverCandidate;
|
|
||||||
LiteBackendArtifactResolverInput resolverInput;
|
|
||||||
std::vector<std::string> missingSymbols;
|
|
||||||
std::vector<LiteBackendArtifactContractIssueInfo> issues;
|
|
||||||
std::string error;
|
|
||||||
std::string summary;
|
|
||||||
};
|
|
||||||
|
|
||||||
const char* liteBackendArtifactContractSupportedAbiVersion();
|
|
||||||
const char* liteBackendArtifactContractLinkModeName(LiteBackendArtifactContractLinkMode linkMode);
|
|
||||||
const char* liteBackendArtifactContractStatusName(LiteBackendArtifactContractStatus status);
|
|
||||||
const char* liteBackendArtifactContractIssueName(LiteBackendArtifactContractIssue issue);
|
|
||||||
|
|
||||||
std::vector<LiteBackendArtifactContractSymbol> liteBackendArtifactContractRequiredSymbols();
|
|
||||||
LiteWalletSdxlArtifactSymbolsInput liteBackendArtifactSymbolsFromExportedNames(
|
|
||||||
const std::vector<std::string>& exportedSymbols);
|
|
||||||
LiteBackendArtifactContractResult evaluateLiteBackendArtifactContract(
|
|
||||||
const LiteBackendArtifactContractInput& input,
|
|
||||||
LiteBackendArtifactContractOptions options = {});
|
|
||||||
LiteBackendArtifactResolverInput liteBackendArtifactResolverInputFromContractResult(
|
|
||||||
const LiteBackendArtifactContractResult& result);
|
|
||||||
|
|
||||||
} // namespace dragonx::wallet
|
|
||||||
@@ -1,913 +0,0 @@
|
|||||||
#include "wallet/lite_backend_artifact_resolver.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cctype>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
|
||||||
#include <system_error>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace dragonx::wallet {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
struct CandidateInspectionResult {
|
|
||||||
bool ok = false;
|
|
||||||
LiteBackendArtifactResolverStatus status = LiteBackendArtifactResolverStatus::WaitingForArtifactCandidate;
|
|
||||||
LiteBackendArtifactResolverIssue issue = LiteBackendArtifactResolverIssue::ArtifactMissing;
|
|
||||||
std::string message;
|
|
||||||
LiteBackendResolvedArtifact artifact;
|
|
||||||
LiteWalletSdxlArtifactInput syncArtifactInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
void addIssue(LiteBackendArtifactResolverResult& result,
|
|
||||||
LiteBackendArtifactResolverIssue issue,
|
|
||||||
std::string message)
|
|
||||||
{
|
|
||||||
result.issues.push_back(LiteBackendArtifactResolverIssueInfo{issue, std::move(message)});
|
|
||||||
}
|
|
||||||
|
|
||||||
void addIssue(LiteBackendActivationReadinessResult& result,
|
|
||||||
LiteBackendActivationReadinessIssue issue,
|
|
||||||
std::string message)
|
|
||||||
{
|
|
||||||
result.issues.push_back(LiteBackendActivationReadinessIssueInfo{issue, std::move(message)});
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactResolverResult stoppedResolverResult(
|
|
||||||
LiteBackendArtifactResolverResult result,
|
|
||||||
LiteBackendArtifactResolverStatus status,
|
|
||||||
LiteBackendArtifactResolverIssue issue,
|
|
||||||
std::string message)
|
|
||||||
{
|
|
||||||
result.status = status;
|
|
||||||
addIssue(result, issue, std::move(message));
|
|
||||||
result.error = result.issues.back().message;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendActivationReadinessResult stoppedActivationResult(
|
|
||||||
LiteBackendActivationReadinessResult result,
|
|
||||||
LiteBackendActivationReadinessStatus status,
|
|
||||||
LiteBackendActivationReadinessIssue issue,
|
|
||||||
std::string message,
|
|
||||||
WalletBackendState backendState = WalletBackendState::Unavailable)
|
|
||||||
{
|
|
||||||
result.status = status;
|
|
||||||
addIssue(result, issue, std::move(message));
|
|
||||||
result.error = result.issues.back().message;
|
|
||||||
result.connectionStatus = WalletBackendStatus{backendState, result.error, {}, {}, 0.0};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string lowerCopy(const std::string& value)
|
|
||||||
{
|
|
||||||
std::string lowered;
|
|
||||||
lowered.reserve(value.size());
|
|
||||||
for (const unsigned char character : value) {
|
|
||||||
lowered.push_back(static_cast<char>(std::tolower(character)));
|
|
||||||
}
|
|
||||||
return lowered;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string trimCopy(const std::string& value)
|
|
||||||
{
|
|
||||||
auto begin = value.begin();
|
|
||||||
while (begin != value.end() && std::isspace(static_cast<unsigned char>(*begin))) ++begin;
|
|
||||||
|
|
||||||
auto end = value.end();
|
|
||||||
while (end != begin && std::isspace(static_cast<unsigned char>(*(end - 1)))) --end;
|
|
||||||
|
|
||||||
return std::string(begin, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string baseNameLower(const std::string& path)
|
|
||||||
{
|
|
||||||
const auto slash = path.find_last_of("/\\");
|
|
||||||
const std::string name = slash == std::string::npos ? path : path.substr(slash + 1);
|
|
||||||
return lowerCopy(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool endsWith(const std::string& value, const char* suffix)
|
|
||||||
{
|
|
||||||
const std::string suffixValue(suffix);
|
|
||||||
return value.size() >= suffixValue.size() &&
|
|
||||||
value.compare(value.size() - suffixValue.size(), suffixValue.size(), suffixValue) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactPlatform normalizePlatform(LiteBackendArtifactPlatform platform)
|
|
||||||
{
|
|
||||||
return platform == LiteBackendArtifactPlatform::Current
|
|
||||||
? currentLiteBackendArtifactPlatform()
|
|
||||||
: platform;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactKind inferArtifactKind(const std::string& path)
|
|
||||||
{
|
|
||||||
const std::string name = baseNameLower(path);
|
|
||||||
if (endsWith(name, ".a") || endsWith(name, ".lib")) return LiteBackendArtifactKind::StaticLibrary;
|
|
||||||
if (endsWith(name, ".so") || endsWith(name, ".dll") || endsWith(name, ".dylib")) {
|
|
||||||
return LiteBackendArtifactKind::SharedLibrary;
|
|
||||||
}
|
|
||||||
if (endsWith(name, ".exe") || name == "silentdragonxlite" || name == "silentdragonx-lite") {
|
|
||||||
return LiteBackendArtifactKind::Executable;
|
|
||||||
}
|
|
||||||
return LiteBackendArtifactKind::Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool artifactKindSupported(LiteBackendArtifactKind kind)
|
|
||||||
{
|
|
||||||
return kind == LiteBackendArtifactKind::StaticLibrary ||
|
|
||||||
kind == LiteBackendArtifactKind::SharedLibrary ||
|
|
||||||
kind == LiteBackendArtifactKind::Executable;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> defaultArtifactNames(LiteBackendArtifactPlatform platform,
|
|
||||||
LiteBackendArtifactKind kind)
|
|
||||||
{
|
|
||||||
const auto normalizedPlatform = normalizePlatform(platform);
|
|
||||||
std::vector<std::string> names;
|
|
||||||
|
|
||||||
const auto addNamesForKind = [&](LiteBackendArtifactKind artifactKind) {
|
|
||||||
switch (normalizedPlatform) {
|
|
||||||
case LiteBackendArtifactPlatform::Windows:
|
|
||||||
if (artifactKind == LiteBackendArtifactKind::StaticLibrary) {
|
|
||||||
names.push_back("silentdragonxlite.lib");
|
|
||||||
names.push_back("libsilentdragonxlite.a");
|
|
||||||
} else if (artifactKind == LiteBackendArtifactKind::SharedLibrary) {
|
|
||||||
names.push_back("silentdragonxlite.dll");
|
|
||||||
} else if (artifactKind == LiteBackendArtifactKind::Executable) {
|
|
||||||
names.push_back("silentdragonxlite.exe");
|
|
||||||
names.push_back("silentdragonx-lite.exe");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LiteBackendArtifactPlatform::MacOS:
|
|
||||||
if (artifactKind == LiteBackendArtifactKind::StaticLibrary) {
|
|
||||||
names.push_back("libsilentdragonxlite.a");
|
|
||||||
names.push_back("silentdragonxlite.a");
|
|
||||||
} else if (artifactKind == LiteBackendArtifactKind::SharedLibrary) {
|
|
||||||
names.push_back("libsilentdragonxlite.dylib");
|
|
||||||
names.push_back("silentdragonxlite.dylib");
|
|
||||||
} else if (artifactKind == LiteBackendArtifactKind::Executable) {
|
|
||||||
names.push_back("silentdragonxlite");
|
|
||||||
names.push_back("silentdragonx-lite");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LiteBackendArtifactPlatform::Linux:
|
|
||||||
case LiteBackendArtifactPlatform::Current:
|
|
||||||
case LiteBackendArtifactPlatform::Unknown:
|
|
||||||
if (artifactKind == LiteBackendArtifactKind::StaticLibrary) {
|
|
||||||
names.push_back("silentdragonxlite.a");
|
|
||||||
names.push_back("libsilentdragonxlite.a");
|
|
||||||
} else if (artifactKind == LiteBackendArtifactKind::SharedLibrary) {
|
|
||||||
names.push_back("libsilentdragonxlite.so");
|
|
||||||
names.push_back("silentdragonxlite.so");
|
|
||||||
} else if (artifactKind == LiteBackendArtifactKind::Executable) {
|
|
||||||
names.push_back("silentdragonxlite");
|
|
||||||
names.push_back("silentdragonx-lite");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (kind == LiteBackendArtifactKind::Unknown) {
|
|
||||||
addNamesForKind(LiteBackendArtifactKind::StaticLibrary);
|
|
||||||
addNamesForKind(LiteBackendArtifactKind::SharedLibrary);
|
|
||||||
addNamesForKind(LiteBackendArtifactKind::Executable);
|
|
||||||
} else {
|
|
||||||
addNamesForKind(kind);
|
|
||||||
}
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::path resolvePath(const std::string& projectRoot, const std::string& path)
|
|
||||||
{
|
|
||||||
const fs::path value(path);
|
|
||||||
if (value.is_absolute()) return value;
|
|
||||||
const fs::path root = projectRoot.empty() ? fs::path(".") : fs::path(projectRoot);
|
|
||||||
return root / value;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<LiteBackendArtifactCandidate> expandSearchRoots(
|
|
||||||
const LiteBackendArtifactResolverInput& input,
|
|
||||||
LiteBackendArtifactResolverResult& result,
|
|
||||||
LiteBackendArtifactResolverOptions options)
|
|
||||||
{
|
|
||||||
std::vector<LiteBackendArtifactCandidate> candidates;
|
|
||||||
result.searchRootCount = input.searchRoots.size();
|
|
||||||
|
|
||||||
for (const auto& root : input.searchRoots) {
|
|
||||||
if (options.requireArtifactCandidates && !root.configured) {
|
|
||||||
result = stoppedResolverResult(
|
|
||||||
std::move(result),
|
|
||||||
LiteBackendArtifactResolverStatus::WaitingForArtifactSearchRoot,
|
|
||||||
LiteBackendArtifactResolverIssue::ArtifactSearchRootNotConfigured,
|
|
||||||
"lite backend artifact search root is not configured");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (trimCopy(root.rootPath).empty()) {
|
|
||||||
result = stoppedResolverResult(
|
|
||||||
std::move(result),
|
|
||||||
LiteBackendArtifactResolverStatus::WaitingForArtifactSearchRoot,
|
|
||||||
LiteBackendArtifactResolverIssue::ArtifactSearchRootMissing,
|
|
||||||
"lite backend artifact search root path is missing");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const fs::path rootPath = resolvePath(input.projectRoot, root.rootPath);
|
|
||||||
std::error_code error;
|
|
||||||
if (!fs::exists(rootPath, error) || error) {
|
|
||||||
result = stoppedResolverResult(
|
|
||||||
std::move(result),
|
|
||||||
LiteBackendArtifactResolverStatus::WaitingForArtifactSearchRoot,
|
|
||||||
LiteBackendArtifactResolverIssue::ArtifactSearchRootMissing,
|
|
||||||
"lite backend artifact search root does not exist");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (!fs::is_directory(rootPath, error) || error) {
|
|
||||||
result = stoppedResolverResult(
|
|
||||||
std::move(result),
|
|
||||||
LiteBackendArtifactResolverStatus::WaitingForArtifactSearchRoot,
|
|
||||||
LiteBackendArtifactResolverIssue::ArtifactSearchRootNotDirectory,
|
|
||||||
"lite backend artifact search root is not a directory");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto names = root.expectedArtifactNames.empty()
|
|
||||||
? defaultArtifactNames(root.platform, root.kind)
|
|
||||||
: root.expectedArtifactNames;
|
|
||||||
for (const auto& artifactName : names) {
|
|
||||||
LiteBackendArtifactCandidate candidate;
|
|
||||||
candidate.configured = true;
|
|
||||||
candidate.artifactPath = (rootPath / artifactName).string();
|
|
||||||
candidate.platform = root.platform;
|
|
||||||
candidate.kind = root.kind;
|
|
||||||
candidate.versionLabel = root.versionLabel;
|
|
||||||
candidate.provenance = root.provenance;
|
|
||||||
candidate.signatureVerification = root.signatureVerification;
|
|
||||||
candidate.sdxlCompatible = root.sdxlCompatible;
|
|
||||||
candidate.symbols = root.symbols;
|
|
||||||
candidate.executableMetadataRequired = root.executableMetadataRequired;
|
|
||||||
candidates.push_back(std::move(candidate));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.artifactSearchRootsAccepted = true;
|
|
||||||
return candidates;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool coreSymbolsReady(const LiteWalletSdxlArtifactSymbolsInput& symbols)
|
|
||||||
{
|
|
||||||
return symbols.walletExists &&
|
|
||||||
symbols.initializeNew &&
|
|
||||||
symbols.initializeNewFromPhrase &&
|
|
||||||
symbols.initializeExisting &&
|
|
||||||
symbols.execute &&
|
|
||||||
symbols.checkServerOnline;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fileReadable(const fs::path& path)
|
|
||||||
{
|
|
||||||
std::ifstream input(path, std::ios::binary);
|
|
||||||
return input.good();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fileExecutable(const fs::path& path, LiteBackendArtifactPlatform platform)
|
|
||||||
{
|
|
||||||
const std::string name = baseNameLower(path.string());
|
|
||||||
if (normalizePlatform(platform) == LiteBackendArtifactPlatform::Windows && endsWith(name, ".exe")) return true;
|
|
||||||
|
|
||||||
std::error_code error;
|
|
||||||
const auto permissions = fs::status(path, error).permissions();
|
|
||||||
if (error) return false;
|
|
||||||
return (permissions & fs::perms::owner_exec) != fs::perms::none ||
|
|
||||||
(permissions & fs::perms::group_exec) != fs::perms::none ||
|
|
||||||
(permissions & fs::perms::others_exec) != fs::perms::none;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool provenanceComplete(const LiteBackendArtifactProvenanceMetadata& provenance)
|
|
||||||
{
|
|
||||||
return provenance.metadataProvided &&
|
|
||||||
!trimCopy(provenance.source).empty() &&
|
|
||||||
!trimCopy(provenance.builder).empty() &&
|
|
||||||
!trimCopy(provenance.sourceRevision).empty() &&
|
|
||||||
!trimCopy(provenance.artifactSetId).empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
CandidateInspectionResult inspectCandidate(const LiteBackendArtifactResolverInput& input,
|
|
||||||
const LiteBackendArtifactCandidate& candidate,
|
|
||||||
LiteBackendArtifactResolverOptions options)
|
|
||||||
{
|
|
||||||
CandidateInspectionResult inspection;
|
|
||||||
if (options.requireArtifactCandidates && !candidate.configured) {
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ArtifactCandidateNotConfigured;
|
|
||||||
inspection.message = "lite backend artifact candidate is not configured";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
if (trimCopy(candidate.artifactPath).empty()) {
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ArtifactPathMissing;
|
|
||||||
inspection.message = "lite backend artifact candidate path is missing";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fs::path artifactPath = resolvePath(input.projectRoot, candidate.artifactPath);
|
|
||||||
std::error_code error;
|
|
||||||
if (!fs::exists(artifactPath, error) || error) {
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ArtifactMissing;
|
|
||||||
inspection.message = "lite backend artifact candidate does not exist";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
if (!fs::is_regular_file(artifactPath, error) || error) {
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ArtifactNotRegularFile;
|
|
||||||
inspection.message = "lite backend artifact candidate is not a regular file";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
if (!fileReadable(artifactPath)) {
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ArtifactUnreadable;
|
|
||||||
inspection.message = "lite backend artifact candidate is not readable";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto candidatePlatform = normalizePlatform(candidate.platform);
|
|
||||||
const auto expectedPlatform = normalizePlatform(input.expectedPlatform);
|
|
||||||
if (candidatePlatform == LiteBackendArtifactPlatform::Unknown || candidatePlatform != expectedPlatform) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::PlatformMismatch;
|
|
||||||
inspection.message = "lite backend artifact platform metadata does not match the expected platform";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto kind = candidate.kind == LiteBackendArtifactKind::Unknown
|
|
||||||
? inferArtifactKind(candidate.artifactPath)
|
|
||||||
: candidate.kind;
|
|
||||||
if (!artifactKindSupported(kind)) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::UnsupportedArtifactKind;
|
|
||||||
inspection.message = "lite backend artifact kind is unsupported or unknown";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.requireVersionMetadata && trimCopy(candidate.versionLabel).empty()) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::VersionMissing;
|
|
||||||
inspection.message = "lite backend artifact version metadata is missing";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.requireProvenanceMetadata) {
|
|
||||||
if (!candidate.provenance.ownerReady) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ProvenanceOwnerMissing;
|
|
||||||
inspection.message = "lite backend artifact provenance owner is not ready";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
if (!provenanceComplete(candidate.provenance)) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ProvenanceMetadataMissing;
|
|
||||||
inspection.message = "lite backend artifact provenance metadata is incomplete";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.requireSdxlCompatibility && !candidate.sdxlCompatible) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ArtifactNotSdxlCompatible;
|
|
||||||
inspection.message = "lite backend artifact is not marked SDXL-compatible";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.requireSdxlSymbols) {
|
|
||||||
if (!coreSymbolsReady(candidate.symbols)) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ArtifactSymbolsMissing;
|
|
||||||
inspection.message = "lite backend artifact is missing required SDXL bridge symbol metadata";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
if (!candidate.symbols.freeString) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ArtifactStringOwnershipUnverified;
|
|
||||||
inspection.message = "lite backend artifact string cleanup symbol metadata is missing";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
if (!candidate.symbols.shutdown) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ArtifactShutdownUnavailable;
|
|
||||||
inspection.message = "lite backend artifact shutdown symbol metadata is missing";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool executable = fileExecutable(artifactPath, candidatePlatform);
|
|
||||||
if ((kind == LiteBackendArtifactKind::Executable || candidate.executableMetadataRequired) && !executable) {
|
|
||||||
inspection.status = LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata;
|
|
||||||
inspection.issue = LiteBackendArtifactResolverIssue::ExecutableMetadataMissing;
|
|
||||||
inspection.message = "lite backend executable artifact is not marked executable";
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t artifactSizeBytes = 0;
|
|
||||||
const auto fileSize = fs::file_size(artifactPath, error);
|
|
||||||
if (!error) artifactSizeBytes = static_cast<std::size_t>(fileSize);
|
|
||||||
|
|
||||||
inspection.ok = true;
|
|
||||||
inspection.artifact.found = true;
|
|
||||||
inspection.artifact.artifactPath = artifactPath.string();
|
|
||||||
inspection.artifact.platform = candidatePlatform;
|
|
||||||
inspection.artifact.kind = kind;
|
|
||||||
inspection.artifact.versionLabel = candidate.versionLabel;
|
|
||||||
inspection.artifact.provenance = candidate.provenance;
|
|
||||||
inspection.artifact.signatureVerification = candidate.signatureVerification;
|
|
||||||
inspection.artifact.exists = true;
|
|
||||||
inspection.artifact.regularFile = true;
|
|
||||||
inspection.artifact.readable = true;
|
|
||||||
inspection.artifact.executable = executable;
|
|
||||||
inspection.artifact.sdxlCompatible = candidate.sdxlCompatible;
|
|
||||||
inspection.artifact.symbols = candidate.symbols;
|
|
||||||
inspection.artifact.artifactSizeBytes = artifactSizeBytes;
|
|
||||||
|
|
||||||
inspection.syncArtifactInput.pathConfigured = true;
|
|
||||||
inspection.syncArtifactInput.exists = true;
|
|
||||||
inspection.syncArtifactInput.readable = true;
|
|
||||||
inspection.syncArtifactInput.sdxlCompatible = candidate.sdxlCompatible;
|
|
||||||
inspection.syncArtifactInput.artifactPath = artifactPath.string();
|
|
||||||
inspection.syncArtifactInput.versionLabel = candidate.versionLabel;
|
|
||||||
inspection.syncArtifactInput.symbols = candidate.symbols;
|
|
||||||
return inspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactResolverResult rejectResolverRuntimeAction(
|
|
||||||
LiteBackendArtifactResolverResult result,
|
|
||||||
const LiteBackendArtifactResolverInput& input,
|
|
||||||
LiteBackendArtifactResolverOptions options)
|
|
||||||
{
|
|
||||||
if (options.rejectArtifactMutation && input.artifactMutationRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::ArtifactMutationRequested,
|
|
||||||
"lite backend artifact mutation is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectSdxlApiCalls && input.sdxlApiRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::SdxlApiRequested,
|
|
||||||
"SDXL API calls are disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectServerConnectivityChecks && input.serverConnectivityCheckRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::ServerConnectivityCheckRequested,
|
|
||||||
"server connectivity checks are disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectWalletLifecycle && input.walletLifecycleRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::WalletLifecycleRequested,
|
|
||||||
"wallet lifecycle execution is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectSync && input.syncRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::SyncRequested,
|
|
||||||
"lite sync execution is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectSyncStatusPolling && input.syncStatusPollingRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::SyncStatusPollingRequested,
|
|
||||||
"lite syncstatus polling is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectWorkerQueue && input.workerQueueRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::WorkerQueueRequested,
|
|
||||||
"worker queue enqueue is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectWalletStateMutation && input.walletStateMutationRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::WalletStateMutationRequested,
|
|
||||||
"WalletState mutation is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectWalletPersistence && input.walletPersistenceRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::WalletPersistenceRequested,
|
|
||||||
"wallet persistence is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectUpload && input.uploadRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::UploadRequested,
|
|
||||||
"upload is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectSigning && input.signingRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::SigningRequested,
|
|
||||||
"signing is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
if (options.rejectPublication && input.publicationRequested) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendArtifactResolverIssue::PublicationRequested,
|
|
||||||
"publication is disabled for artifact resolution");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendActivationReadinessResult rejectActivationRuntimeAction(
|
|
||||||
LiteBackendActivationReadinessResult result,
|
|
||||||
const LiteBackendActivationReadinessInput& input,
|
|
||||||
LiteBackendActivationReadinessOptions options)
|
|
||||||
{
|
|
||||||
if (options.rejectArtifactMutation && input.artifactMutationRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::ArtifactMutationRequested,
|
|
||||||
"lite backend artifact mutation is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectSdxlApiCalls && input.sdxlApiRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::SdxlApiRequested,
|
|
||||||
"SDXL API calls are disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectServerConnectivityChecks && input.serverConnectivityCheckRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::ServerConnectivityCheckRequested,
|
|
||||||
"server connectivity checks are disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectWalletLifecycle && input.walletLifecycleRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::WalletLifecycleRequested,
|
|
||||||
"wallet lifecycle execution is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectSync && input.syncRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::SyncRequested,
|
|
||||||
"lite sync execution is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectSyncStatusPolling && input.syncStatusPollingRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::SyncStatusPollingRequested,
|
|
||||||
"lite syncstatus polling is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectWorkerQueue && input.workerQueueRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::WorkerQueueRequested,
|
|
||||||
"worker queue enqueue is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectWalletStateMutation && input.walletStateMutationRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::WalletStateMutationRequested,
|
|
||||||
"WalletState mutation is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectWalletPersistence && input.walletPersistenceRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::WalletPersistenceRequested,
|
|
||||||
"wallet persistence is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectUpload && input.uploadRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::UploadRequested,
|
|
||||||
"upload is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectSigning && input.signingRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::SigningRequested,
|
|
||||||
"signing is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
if (options.rejectPublication && input.publicationRequested) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::RuntimeActionDisabled,
|
|
||||||
LiteBackendActivationReadinessIssue::PublicationRequested,
|
|
||||||
"publication is disabled for activation readiness");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
WalletBackendStatus backendStatusOrDefault(const LiteBackendBridgeReadinessInput& backend,
|
|
||||||
const std::string& fallback)
|
|
||||||
{
|
|
||||||
if (!backend.status.message.empty()) return backend.status;
|
|
||||||
return WalletBackendStatus{WalletBackendState::Unavailable, fallback, {}, {}, 0.0};
|
|
||||||
}
|
|
||||||
|
|
||||||
WalletBackendStatus readyConnectionStatus(const LiteServerSelectionResult& selectedServer)
|
|
||||||
{
|
|
||||||
const std::string serverLabel = selectedServer.server.label.empty()
|
|
||||||
? selectedServer.server.url
|
|
||||||
: selectedServer.server.label;
|
|
||||||
return WalletBackendStatus{
|
|
||||||
WalletBackendState::Disconnected,
|
|
||||||
"lite backend activation readiness accepted for " + serverLabel + "; bridge calls remain disabled here",
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
0.0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
LiteBackendArtifactPlatform currentLiteBackendArtifactPlatform()
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
return LiteBackendArtifactPlatform::Windows;
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
return LiteBackendArtifactPlatform::MacOS;
|
|
||||||
#else
|
|
||||||
return LiteBackendArtifactPlatform::Linux;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* liteBackendArtifactPlatformName(LiteBackendArtifactPlatform platform)
|
|
||||||
{
|
|
||||||
switch (platform) {
|
|
||||||
case LiteBackendArtifactPlatform::Current: return "Current";
|
|
||||||
case LiteBackendArtifactPlatform::Linux: return "Linux";
|
|
||||||
case LiteBackendArtifactPlatform::Windows: return "Windows";
|
|
||||||
case LiteBackendArtifactPlatform::MacOS: return "MacOS";
|
|
||||||
case LiteBackendArtifactPlatform::Unknown: return "Unknown";
|
|
||||||
}
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* liteBackendArtifactKindName(LiteBackendArtifactKind kind)
|
|
||||||
{
|
|
||||||
switch (kind) {
|
|
||||||
case LiteBackendArtifactKind::Unknown: return "Unknown";
|
|
||||||
case LiteBackendArtifactKind::StaticLibrary: return "StaticLibrary";
|
|
||||||
case LiteBackendArtifactKind::SharedLibrary: return "SharedLibrary";
|
|
||||||
case LiteBackendArtifactKind::Executable: return "Executable";
|
|
||||||
}
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* liteBackendArtifactResolverStatusName(LiteBackendArtifactResolverStatus status)
|
|
||||||
{
|
|
||||||
switch (status) {
|
|
||||||
case LiteBackendArtifactResolverStatus::ReadyForActivationReadiness: return "ReadyForActivationReadiness";
|
|
||||||
case LiteBackendArtifactResolverStatus::WaitingForResolverOwner: return "WaitingForResolverOwner";
|
|
||||||
case LiteBackendArtifactResolverStatus::WaitingForReadOnlyGate: return "WaitingForReadOnlyGate";
|
|
||||||
case LiteBackendArtifactResolverStatus::WaitingForArtifactSearchRoot: return "WaitingForArtifactSearchRoot";
|
|
||||||
case LiteBackendArtifactResolverStatus::WaitingForArtifactCandidate: return "WaitingForArtifactCandidate";
|
|
||||||
case LiteBackendArtifactResolverStatus::WaitingForArtifactMetadata: return "WaitingForArtifactMetadata";
|
|
||||||
case LiteBackendArtifactResolverStatus::RuntimeActionDisabled: return "RuntimeActionDisabled";
|
|
||||||
}
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* liteBackendArtifactResolverIssueName(LiteBackendArtifactResolverIssue issue)
|
|
||||||
{
|
|
||||||
switch (issue) {
|
|
||||||
case LiteBackendArtifactResolverIssue::ResolverOwnerMissing: return "ResolverOwnerMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ReadOnlyGateMissing: return "ReadOnlyGateMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactSearchRootMissing: return "ArtifactSearchRootMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactSearchRootNotConfigured: return "ArtifactSearchRootNotConfigured";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactSearchRootNotDirectory: return "ArtifactSearchRootNotDirectory";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactCandidateMissing: return "ArtifactCandidateMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactCandidateNotConfigured: return "ArtifactCandidateNotConfigured";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactPathMissing: return "ArtifactPathMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactMissing: return "ArtifactMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactNotRegularFile: return "ArtifactNotRegularFile";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactUnreadable: return "ArtifactUnreadable";
|
|
||||||
case LiteBackendArtifactResolverIssue::UnsupportedArtifactKind: return "UnsupportedArtifactKind";
|
|
||||||
case LiteBackendArtifactResolverIssue::PlatformMismatch: return "PlatformMismatch";
|
|
||||||
case LiteBackendArtifactResolverIssue::VersionMissing: return "VersionMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ProvenanceOwnerMissing: return "ProvenanceOwnerMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ProvenanceMetadataMissing: return "ProvenanceMetadataMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactNotSdxlCompatible: return "ArtifactNotSdxlCompatible";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactSymbolsMissing: return "ArtifactSymbolsMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactStringOwnershipUnverified: return "ArtifactStringOwnershipUnverified";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactShutdownUnavailable: return "ArtifactShutdownUnavailable";
|
|
||||||
case LiteBackendArtifactResolverIssue::ExecutableMetadataMissing: return "ExecutableMetadataMissing";
|
|
||||||
case LiteBackendArtifactResolverIssue::ArtifactMutationRequested: return "ArtifactMutationRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::SdxlApiRequested: return "SdxlApiRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::ServerConnectivityCheckRequested: return "ServerConnectivityCheckRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::WalletLifecycleRequested: return "WalletLifecycleRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::SyncRequested: return "SyncRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::SyncStatusPollingRequested: return "SyncStatusPollingRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::WorkerQueueRequested: return "WorkerQueueRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::WalletStateMutationRequested: return "WalletStateMutationRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::WalletPersistenceRequested: return "WalletPersistenceRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::UploadRequested: return "UploadRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::SigningRequested: return "SigningRequested";
|
|
||||||
case LiteBackendArtifactResolverIssue::PublicationRequested: return "PublicationRequested";
|
|
||||||
}
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* liteBackendActivationReadinessStatusName(LiteBackendActivationReadinessStatus status)
|
|
||||||
{
|
|
||||||
switch (status) {
|
|
||||||
case LiteBackendActivationReadinessStatus::ReadyForConnectionReadiness: return "ReadyForConnectionReadiness";
|
|
||||||
case LiteBackendActivationReadinessStatus::WaitingForActivationOwner: return "WaitingForActivationOwner";
|
|
||||||
case LiteBackendActivationReadinessStatus::WaitingForReadOnlyGate: return "WaitingForReadOnlyGate";
|
|
||||||
case LiteBackendActivationReadinessStatus::WaitingForLiteBuild: return "WaitingForLiteBuild";
|
|
||||||
case LiteBackendActivationReadinessStatus::WaitingForBackendCapability: return "WaitingForBackendCapability";
|
|
||||||
case LiteBackendActivationReadinessStatus::WaitingForArtifactResolver: return "WaitingForArtifactResolver";
|
|
||||||
case LiteBackendActivationReadinessStatus::WaitingForBackendLink: return "WaitingForBackendLink";
|
|
||||||
case LiteBackendActivationReadinessStatus::WaitingForBridge: return "WaitingForBridge";
|
|
||||||
case LiteBackendActivationReadinessStatus::WaitingForConnectionSettings: return "WaitingForConnectionSettings";
|
|
||||||
case LiteBackendActivationReadinessStatus::RuntimeActionDisabled: return "RuntimeActionDisabled";
|
|
||||||
}
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* liteBackendActivationReadinessIssueName(LiteBackendActivationReadinessIssue issue)
|
|
||||||
{
|
|
||||||
switch (issue) {
|
|
||||||
case LiteBackendActivationReadinessIssue::ActivationOwnerMissing: return "ActivationOwnerMissing";
|
|
||||||
case LiteBackendActivationReadinessIssue::ReadOnlyGateMissing: return "ReadOnlyGateMissing";
|
|
||||||
case LiteBackendActivationReadinessIssue::FullNodeBuild: return "FullNodeBuild";
|
|
||||||
case LiteBackendActivationReadinessIssue::LiteBackendCapabilityMissing: return "LiteBackendCapabilityMissing";
|
|
||||||
case LiteBackendActivationReadinessIssue::ArtifactResolverRejected: return "ArtifactResolverRejected";
|
|
||||||
case LiteBackendActivationReadinessIssue::BackendNotLinked: return "BackendNotLinked";
|
|
||||||
case LiteBackendActivationReadinessIssue::BridgeUnavailable: return "BridgeUnavailable";
|
|
||||||
case LiteBackendActivationReadinessIssue::ConnectionSettingsRejected: return "ConnectionSettingsRejected";
|
|
||||||
case LiteBackendActivationReadinessIssue::ArtifactMutationRequested: return "ArtifactMutationRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::SdxlApiRequested: return "SdxlApiRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::ServerConnectivityCheckRequested: return "ServerConnectivityCheckRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::WalletLifecycleRequested: return "WalletLifecycleRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::SyncRequested: return "SyncRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::SyncStatusPollingRequested: return "SyncStatusPollingRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::WorkerQueueRequested: return "WorkerQueueRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::WalletStateMutationRequested: return "WalletStateMutationRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::WalletPersistenceRequested: return "WalletPersistenceRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::UploadRequested: return "UploadRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::SigningRequested: return "SigningRequested";
|
|
||||||
case LiteBackendActivationReadinessIssue::PublicationRequested: return "PublicationRequested";
|
|
||||||
}
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactResolverResult evaluateLiteBackendArtifactResolver(
|
|
||||||
const LiteBackendArtifactResolverInput& input,
|
|
||||||
LiteBackendArtifactResolverOptions options)
|
|
||||||
{
|
|
||||||
LiteBackendArtifactResolverResult result;
|
|
||||||
|
|
||||||
result = rejectResolverRuntimeAction(std::move(result), input, options);
|
|
||||||
if (!result.issues.empty()) return result;
|
|
||||||
|
|
||||||
if (options.requireResolverOwner && !input.resolverOwnerReady) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::WaitingForResolverOwner,
|
|
||||||
LiteBackendArtifactResolverIssue::ResolverOwnerMissing,
|
|
||||||
"lite backend artifact resolver owner is not ready");
|
|
||||||
}
|
|
||||||
result.resolverOwnerAccepted = true;
|
|
||||||
|
|
||||||
if (options.requireReadOnlyGate && !input.readOnlyGateReady) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::WaitingForReadOnlyGate,
|
|
||||||
LiteBackendArtifactResolverIssue::ReadOnlyGateMissing,
|
|
||||||
"lite backend artifact resolver read-only gate is not ready");
|
|
||||||
}
|
|
||||||
result.readOnlyGateAccepted = true;
|
|
||||||
|
|
||||||
auto candidates = expandSearchRoots(input, result, options);
|
|
||||||
if (!result.issues.empty()) return result;
|
|
||||||
for (const auto& candidate : input.candidates) candidates.push_back(candidate);
|
|
||||||
|
|
||||||
result.candidateCount = candidates.size();
|
|
||||||
if (options.requireArtifactCandidates && candidates.empty()) {
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::WaitingForArtifactCandidate,
|
|
||||||
LiteBackendArtifactResolverIssue::ArtifactCandidateMissing,
|
|
||||||
"lite backend artifact resolver has no configured candidates");
|
|
||||||
}
|
|
||||||
result.artifactCandidatesAccepted = true;
|
|
||||||
|
|
||||||
CandidateInspectionResult firstRejected;
|
|
||||||
bool haveRejectedCandidate = false;
|
|
||||||
for (const auto& candidate : candidates) {
|
|
||||||
++result.checkedCandidateCount;
|
|
||||||
auto inspection = inspectCandidate(input, candidate, options);
|
|
||||||
if (!inspection.ok) {
|
|
||||||
++result.rejectedCandidateCount;
|
|
||||||
if (!haveRejectedCandidate) {
|
|
||||||
firstRejected = std::move(inspection);
|
|
||||||
haveRejectedCandidate = true;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.ok = true;
|
|
||||||
result.status = LiteBackendArtifactResolverStatus::ReadyForActivationReadiness;
|
|
||||||
result.artifact = std::move(inspection.artifact);
|
|
||||||
result.syncArtifactInput = std::move(inspection.syncArtifactInput);
|
|
||||||
result.artifactDiscovered = true;
|
|
||||||
result.artifactMetadataAccepted = true;
|
|
||||||
result.platformAccepted = true;
|
|
||||||
result.versionAccepted = !options.requireVersionMetadata || !result.artifact.versionLabel.empty();
|
|
||||||
result.provenanceAccepted = !options.requireProvenanceMetadata || provenanceComplete(result.artifact.provenance);
|
|
||||||
result.sdxlCompatibilityAccepted = !options.requireSdxlCompatibility || result.artifact.sdxlCompatible;
|
|
||||||
result.symbolMetadataAccepted = !options.requireSdxlSymbols ||
|
|
||||||
(coreSymbolsReady(result.artifact.symbols) && result.artifact.symbols.freeString && result.artifact.symbols.shutdown);
|
|
||||||
result.executableMetadataAccepted = true;
|
|
||||||
result.syncArtifactInputProduced = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (haveRejectedCandidate) {
|
|
||||||
return stoppedResolverResult(std::move(result), firstRejected.status, firstRejected.issue, firstRejected.message);
|
|
||||||
}
|
|
||||||
return stoppedResolverResult(std::move(result), LiteBackendArtifactResolverStatus::WaitingForArtifactCandidate,
|
|
||||||
LiteBackendArtifactResolverIssue::ArtifactCandidateMissing,
|
|
||||||
"lite backend artifact resolver did not find any artifact candidates");
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendActivationReadinessResult evaluateLiteBackendActivationReadiness(
|
|
||||||
const LiteBackendActivationReadinessInput& input,
|
|
||||||
LiteBackendActivationReadinessOptions options)
|
|
||||||
{
|
|
||||||
LiteBackendActivationReadinessResult result;
|
|
||||||
result.connectionAvailability = LiteConnectionAvailability::BackendUnavailable;
|
|
||||||
|
|
||||||
result = rejectActivationRuntimeAction(std::move(result), input, options);
|
|
||||||
if (!result.issues.empty()) return result;
|
|
||||||
|
|
||||||
if (options.requireActivationOwner && !input.activationOwnerReady) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::WaitingForActivationOwner,
|
|
||||||
LiteBackendActivationReadinessIssue::ActivationOwnerMissing,
|
|
||||||
"lite backend activation readiness owner is not ready");
|
|
||||||
}
|
|
||||||
result.activationOwnerAccepted = true;
|
|
||||||
|
|
||||||
if (options.requireReadOnlyGate && !input.readOnlyGateReady) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::WaitingForReadOnlyGate,
|
|
||||||
LiteBackendActivationReadinessIssue::ReadOnlyGateMissing,
|
|
||||||
"lite backend activation readiness read-only gate is not ready");
|
|
||||||
}
|
|
||||||
result.readOnlyGateAccepted = true;
|
|
||||||
|
|
||||||
if (options.requireLiteBuild && !isLiteBuild(input.capabilities)) {
|
|
||||||
result.connectionAvailability = LiteConnectionAvailability::UnsupportedBuild;
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::WaitingForLiteBuild,
|
|
||||||
LiteBackendActivationReadinessIssue::FullNodeBuild,
|
|
||||||
"lite backend activation readiness requires a lite build");
|
|
||||||
}
|
|
||||||
result.liteBuildAccepted = true;
|
|
||||||
|
|
||||||
if (options.requireLiteBackendCapability && !supportsLiteBackend(input.capabilities)) {
|
|
||||||
result.connectionAvailability = LiteConnectionAvailability::BackendUnavailable;
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::WaitingForBackendCapability,
|
|
||||||
LiteBackendActivationReadinessIssue::LiteBackendCapabilityMissing,
|
|
||||||
"lite backend capability is not available for activation readiness");
|
|
||||||
}
|
|
||||||
result.backendCapabilityAccepted = true;
|
|
||||||
|
|
||||||
result.artifactResolverResult = evaluateLiteBackendArtifactResolver(input.artifactResolver, options.resolverOptions);
|
|
||||||
if (options.requireResolvedArtifact && !result.artifactResolverResult.ok) {
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::WaitingForArtifactResolver,
|
|
||||||
LiteBackendActivationReadinessIssue::ArtifactResolverRejected,
|
|
||||||
result.artifactResolverResult.error.empty()
|
|
||||||
? "lite backend artifact resolver did not produce a usable artifact"
|
|
||||||
: result.artifactResolverResult.error);
|
|
||||||
}
|
|
||||||
result.artifactResolverAccepted = true;
|
|
||||||
result.syncArtifactInput = result.artifactResolverResult.syncArtifactInput;
|
|
||||||
|
|
||||||
if (options.requireLinkedBackend && !input.backend.linked) {
|
|
||||||
result.connectionAvailability = LiteConnectionAvailability::BackendUnavailable;
|
|
||||||
const auto status = backendStatusOrDefault(input.backend, "lite backend is not linked");
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::WaitingForBackendLink,
|
|
||||||
LiteBackendActivationReadinessIssue::BackendNotLinked,
|
|
||||||
status.message);
|
|
||||||
}
|
|
||||||
result.backendLinkedAccepted = true;
|
|
||||||
|
|
||||||
if (options.requireBridgeAvailable && !input.backend.bridgeAvailable) {
|
|
||||||
result.connectionAvailability = LiteConnectionAvailability::BridgeUnavailable;
|
|
||||||
const std::string message = !input.backend.bridgeUnavailableReason.empty()
|
|
||||||
? input.backend.bridgeUnavailableReason
|
|
||||||
: backendStatusOrDefault(input.backend, "lite client bridge is unavailable").message;
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::WaitingForBridge,
|
|
||||||
LiteBackendActivationReadinessIssue::BridgeUnavailable,
|
|
||||||
message);
|
|
||||||
}
|
|
||||||
result.bridgeAccepted = true;
|
|
||||||
|
|
||||||
result.selectedServer = selectLiteServer(input.connectionSettings);
|
|
||||||
if (options.requireUsableServer && !result.selectedServer.ok) {
|
|
||||||
result.connectionAvailability = LiteConnectionAvailability::NoUsableServer;
|
|
||||||
return stoppedActivationResult(std::move(result), LiteBackendActivationReadinessStatus::WaitingForConnectionSettings,
|
|
||||||
LiteBackendActivationReadinessIssue::ConnectionSettingsRejected,
|
|
||||||
result.selectedServer.error.empty()
|
|
||||||
? "no usable lite server is configured for activation readiness"
|
|
||||||
: result.selectedServer.error,
|
|
||||||
WalletBackendState::Error);
|
|
||||||
}
|
|
||||||
result.connectionSettingsAccepted = true;
|
|
||||||
|
|
||||||
result.syncBackendInput.linked = input.backend.linked;
|
|
||||||
result.syncBackendInput.bridgeAvailable = input.backend.bridgeAvailable;
|
|
||||||
result.syncBackendInput.status = input.backend.status.message.empty()
|
|
||||||
? WalletBackendStatus{WalletBackendState::Disconnected, "lite backend bridge readiness accepted", {}, {}, 0.0}
|
|
||||||
: input.backend.status;
|
|
||||||
result.syncBackendInput.bridgeUnavailableReason = input.backend.bridgeUnavailableReason;
|
|
||||||
result.syncReadinessInputsProduced = true;
|
|
||||||
|
|
||||||
result.ok = true;
|
|
||||||
result.status = LiteBackendActivationReadinessStatus::ReadyForConnectionReadiness;
|
|
||||||
result.connectionAvailability = LiteConnectionAvailability::Ready;
|
|
||||||
result.connectionStatus = readyConnectionStatus(result.selectedServer);
|
|
||||||
result.connectionServiceBoundaryAccepted = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactResolver::LiteBackendArtifactResolver(LiteBackendArtifactResolverOptions options)
|
|
||||||
: options_(options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteBackendArtifactResolverResult LiteBackendArtifactResolver::resolve(
|
|
||||||
const LiteBackendArtifactResolverInput& input) const
|
|
||||||
{
|
|
||||||
return evaluateLiteBackendArtifactResolver(input, options_);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dragonx::wallet
|
|
||||||
@@ -1,434 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "lite_connection_service.h" // pulls wallet_backend.h (WalletBackendStatus)
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
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 {
|
|
||||||
Current,
|
|
||||||
Linux,
|
|
||||||
Windows,
|
|
||||||
MacOS,
|
|
||||||
Unknown,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class LiteBackendArtifactKind {
|
|
||||||
Unknown,
|
|
||||||
StaticLibrary,
|
|
||||||
SharedLibrary,
|
|
||||||
Executable,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class LiteBackendArtifactResolverStatus {
|
|
||||||
ReadyForActivationReadiness,
|
|
||||||
WaitingForResolverOwner,
|
|
||||||
WaitingForReadOnlyGate,
|
|
||||||
WaitingForArtifactSearchRoot,
|
|
||||||
WaitingForArtifactCandidate,
|
|
||||||
WaitingForArtifactMetadata,
|
|
||||||
RuntimeActionDisabled,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class LiteBackendArtifactResolverIssue {
|
|
||||||
ResolverOwnerMissing,
|
|
||||||
ReadOnlyGateMissing,
|
|
||||||
ArtifactSearchRootMissing,
|
|
||||||
ArtifactSearchRootNotConfigured,
|
|
||||||
ArtifactSearchRootNotDirectory,
|
|
||||||
ArtifactCandidateMissing,
|
|
||||||
ArtifactCandidateNotConfigured,
|
|
||||||
ArtifactPathMissing,
|
|
||||||
ArtifactMissing,
|
|
||||||
ArtifactNotRegularFile,
|
|
||||||
ArtifactUnreadable,
|
|
||||||
UnsupportedArtifactKind,
|
|
||||||
PlatformMismatch,
|
|
||||||
VersionMissing,
|
|
||||||
ProvenanceOwnerMissing,
|
|
||||||
ProvenanceMetadataMissing,
|
|
||||||
ArtifactNotSdxlCompatible,
|
|
||||||
ArtifactSymbolsMissing,
|
|
||||||
ArtifactStringOwnershipUnverified,
|
|
||||||
ArtifactShutdownUnavailable,
|
|
||||||
ExecutableMetadataMissing,
|
|
||||||
ArtifactMutationRequested,
|
|
||||||
SdxlApiRequested,
|
|
||||||
ServerConnectivityCheckRequested,
|
|
||||||
WalletLifecycleRequested,
|
|
||||||
SyncRequested,
|
|
||||||
SyncStatusPollingRequested,
|
|
||||||
WorkerQueueRequested,
|
|
||||||
WalletStateMutationRequested,
|
|
||||||
WalletPersistenceRequested,
|
|
||||||
UploadRequested,
|
|
||||||
SigningRequested,
|
|
||||||
PublicationRequested,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactProvenanceMetadata {
|
|
||||||
bool ownerReady = false;
|
|
||||||
bool metadataProvided = false;
|
|
||||||
std::string source;
|
|
||||||
std::string builder;
|
|
||||||
std::string sourceRevision;
|
|
||||||
std::string artifactSetId;
|
|
||||||
bool redacted = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactSignatureVerificationMetadata {
|
|
||||||
bool policyDefined = false;
|
|
||||||
bool requiredForRelease = false;
|
|
||||||
bool metadataProvided = false;
|
|
||||||
bool verificationPerformed = false;
|
|
||||||
bool verified = false;
|
|
||||||
std::string signatureFormat;
|
|
||||||
std::string signaturePath;
|
|
||||||
std::string signatureFileSha256;
|
|
||||||
std::string verificationTool;
|
|
||||||
std::string verificationCommand;
|
|
||||||
std::string keyFingerprint;
|
|
||||||
std::string certificateIdentity;
|
|
||||||
std::string certificateIssuer;
|
|
||||||
std::string transparencyLogUrl;
|
|
||||||
std::string verifiedArtifactSha256;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactCandidate {
|
|
||||||
bool configured = false;
|
|
||||||
std::string artifactPath;
|
|
||||||
LiteBackendArtifactPlatform platform = LiteBackendArtifactPlatform::Current;
|
|
||||||
LiteBackendArtifactKind kind = LiteBackendArtifactKind::Unknown;
|
|
||||||
std::string versionLabel;
|
|
||||||
LiteBackendArtifactProvenanceMetadata provenance;
|
|
||||||
LiteBackendArtifactSignatureVerificationMetadata signatureVerification;
|
|
||||||
bool sdxlCompatible = false;
|
|
||||||
LiteWalletSdxlArtifactSymbolsInput symbols;
|
|
||||||
bool executableMetadataRequired = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactSearchRoot {
|
|
||||||
bool configured = false;
|
|
||||||
std::string rootPath;
|
|
||||||
LiteBackendArtifactPlatform platform = LiteBackendArtifactPlatform::Current;
|
|
||||||
LiteBackendArtifactKind kind = LiteBackendArtifactKind::Unknown;
|
|
||||||
std::string versionLabel;
|
|
||||||
LiteBackendArtifactProvenanceMetadata provenance;
|
|
||||||
LiteBackendArtifactSignatureVerificationMetadata signatureVerification;
|
|
||||||
bool sdxlCompatible = false;
|
|
||||||
LiteWalletSdxlArtifactSymbolsInput symbols;
|
|
||||||
bool executableMetadataRequired = false;
|
|
||||||
std::vector<std::string> expectedArtifactNames;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactResolverInput {
|
|
||||||
bool resolverOwnerReady = false;
|
|
||||||
bool readOnlyGateReady = false;
|
|
||||||
std::string projectRoot;
|
|
||||||
LiteBackendArtifactPlatform expectedPlatform = LiteBackendArtifactPlatform::Current;
|
|
||||||
std::vector<LiteBackendArtifactSearchRoot> searchRoots;
|
|
||||||
std::vector<LiteBackendArtifactCandidate> candidates;
|
|
||||||
|
|
||||||
bool artifactMutationRequested = false;
|
|
||||||
bool sdxlApiRequested = false;
|
|
||||||
bool serverConnectivityCheckRequested = false;
|
|
||||||
bool walletLifecycleRequested = false;
|
|
||||||
bool syncRequested = false;
|
|
||||||
bool syncStatusPollingRequested = false;
|
|
||||||
bool workerQueueRequested = false;
|
|
||||||
bool walletStateMutationRequested = false;
|
|
||||||
bool walletPersistenceRequested = false;
|
|
||||||
bool uploadRequested = false;
|
|
||||||
bool signingRequested = false;
|
|
||||||
bool publicationRequested = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactResolverOptions {
|
|
||||||
bool requireResolverOwner = true;
|
|
||||||
bool requireReadOnlyGate = true;
|
|
||||||
bool requireArtifactCandidates = true;
|
|
||||||
bool requireVersionMetadata = true;
|
|
||||||
bool requireProvenanceMetadata = true;
|
|
||||||
bool requireSdxlCompatibility = true;
|
|
||||||
bool requireSdxlSymbols = true;
|
|
||||||
bool rejectArtifactMutation = true;
|
|
||||||
bool rejectSdxlApiCalls = true;
|
|
||||||
bool rejectServerConnectivityChecks = true;
|
|
||||||
bool rejectWalletLifecycle = true;
|
|
||||||
bool rejectSync = true;
|
|
||||||
bool rejectSyncStatusPolling = true;
|
|
||||||
bool rejectWorkerQueue = true;
|
|
||||||
bool rejectWalletStateMutation = true;
|
|
||||||
bool rejectWalletPersistence = true;
|
|
||||||
bool rejectUpload = true;
|
|
||||||
bool rejectSigning = true;
|
|
||||||
bool rejectPublication = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendResolvedArtifact {
|
|
||||||
bool found = false;
|
|
||||||
std::string artifactPath;
|
|
||||||
LiteBackendArtifactPlatform platform = LiteBackendArtifactPlatform::Unknown;
|
|
||||||
LiteBackendArtifactKind kind = LiteBackendArtifactKind::Unknown;
|
|
||||||
std::string versionLabel;
|
|
||||||
LiteBackendArtifactProvenanceMetadata provenance;
|
|
||||||
LiteBackendArtifactSignatureVerificationMetadata signatureVerification;
|
|
||||||
bool exists = false;
|
|
||||||
bool regularFile = false;
|
|
||||||
bool readable = false;
|
|
||||||
bool executable = false;
|
|
||||||
bool sdxlCompatible = false;
|
|
||||||
LiteWalletSdxlArtifactSymbolsInput symbols;
|
|
||||||
std::size_t artifactSizeBytes = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactResolverIssueInfo {
|
|
||||||
LiteBackendArtifactResolverIssue issue = LiteBackendArtifactResolverIssue::ArtifactCandidateMissing;
|
|
||||||
std::string message;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendArtifactResolverResult {
|
|
||||||
bool ok = false;
|
|
||||||
bool readOnlyArtifactDiscovery = true;
|
|
||||||
bool artifactMetadataReadOnly = true;
|
|
||||||
bool provenanceReadOnly = true;
|
|
||||||
bool executableMetadataReadOnly = true;
|
|
||||||
bool noArtifactMutation = true;
|
|
||||||
bool noSdxlCalls = true;
|
|
||||||
bool noServerConnectivityChecked = true;
|
|
||||||
bool noWalletCreated = true;
|
|
||||||
bool noWalletOpened = true;
|
|
||||||
bool noWalletRestored = true;
|
|
||||||
bool noSyncStarted = true;
|
|
||||||
bool noSyncStatusPolled = true;
|
|
||||||
bool noWorkerQueueEnqueue = true;
|
|
||||||
bool noWalletStateMutation = true;
|
|
||||||
bool noWalletPersistence = true;
|
|
||||||
bool noUpload = true;
|
|
||||||
bool noSigning = true;
|
|
||||||
bool noPublication = true;
|
|
||||||
|
|
||||||
bool resolverOwnerAccepted = false;
|
|
||||||
bool readOnlyGateAccepted = false;
|
|
||||||
bool artifactSearchRootsAccepted = false;
|
|
||||||
bool artifactCandidatesAccepted = false;
|
|
||||||
bool artifactDiscovered = false;
|
|
||||||
bool artifactMetadataAccepted = false;
|
|
||||||
bool platformAccepted = false;
|
|
||||||
bool versionAccepted = false;
|
|
||||||
bool provenanceAccepted = false;
|
|
||||||
bool sdxlCompatibilityAccepted = false;
|
|
||||||
bool symbolMetadataAccepted = false;
|
|
||||||
bool executableMetadataAccepted = false;
|
|
||||||
bool syncArtifactInputProduced = false;
|
|
||||||
|
|
||||||
std::size_t searchRootCount = 0;
|
|
||||||
std::size_t candidateCount = 0;
|
|
||||||
std::size_t checkedCandidateCount = 0;
|
|
||||||
std::size_t rejectedCandidateCount = 0;
|
|
||||||
|
|
||||||
LiteBackendArtifactResolverStatus status = LiteBackendArtifactResolverStatus::WaitingForResolverOwner;
|
|
||||||
LiteBackendResolvedArtifact artifact;
|
|
||||||
LiteWalletSdxlArtifactInput syncArtifactInput;
|
|
||||||
std::vector<LiteBackendArtifactResolverIssueInfo> issues;
|
|
||||||
std::string error;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class LiteBackendActivationReadinessStatus {
|
|
||||||
ReadyForConnectionReadiness,
|
|
||||||
WaitingForActivationOwner,
|
|
||||||
WaitingForReadOnlyGate,
|
|
||||||
WaitingForLiteBuild,
|
|
||||||
WaitingForBackendCapability,
|
|
||||||
WaitingForArtifactResolver,
|
|
||||||
WaitingForBackendLink,
|
|
||||||
WaitingForBridge,
|
|
||||||
WaitingForConnectionSettings,
|
|
||||||
RuntimeActionDisabled,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class LiteBackendActivationReadinessIssue {
|
|
||||||
ActivationOwnerMissing,
|
|
||||||
ReadOnlyGateMissing,
|
|
||||||
FullNodeBuild,
|
|
||||||
LiteBackendCapabilityMissing,
|
|
||||||
ArtifactResolverRejected,
|
|
||||||
BackendNotLinked,
|
|
||||||
BridgeUnavailable,
|
|
||||||
ConnectionSettingsRejected,
|
|
||||||
ArtifactMutationRequested,
|
|
||||||
SdxlApiRequested,
|
|
||||||
ServerConnectivityCheckRequested,
|
|
||||||
WalletLifecycleRequested,
|
|
||||||
SyncRequested,
|
|
||||||
SyncStatusPollingRequested,
|
|
||||||
WorkerQueueRequested,
|
|
||||||
WalletStateMutationRequested,
|
|
||||||
WalletPersistenceRequested,
|
|
||||||
UploadRequested,
|
|
||||||
SigningRequested,
|
|
||||||
PublicationRequested,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendBridgeReadinessInput {
|
|
||||||
bool linked = false;
|
|
||||||
bool bridgeAvailable = false;
|
|
||||||
WalletBackendStatus status;
|
|
||||||
std::string bridgeUnavailableReason;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendActivationReadinessInput {
|
|
||||||
WalletCapabilities capabilities;
|
|
||||||
LiteConnectionSettings connectionSettings;
|
|
||||||
LiteBackendArtifactResolverInput artifactResolver;
|
|
||||||
LiteBackendBridgeReadinessInput backend;
|
|
||||||
bool activationOwnerReady = false;
|
|
||||||
bool readOnlyGateReady = false;
|
|
||||||
|
|
||||||
bool artifactMutationRequested = false;
|
|
||||||
bool sdxlApiRequested = false;
|
|
||||||
bool serverConnectivityCheckRequested = false;
|
|
||||||
bool walletLifecycleRequested = false;
|
|
||||||
bool syncRequested = false;
|
|
||||||
bool syncStatusPollingRequested = false;
|
|
||||||
bool workerQueueRequested = false;
|
|
||||||
bool walletStateMutationRequested = false;
|
|
||||||
bool walletPersistenceRequested = false;
|
|
||||||
bool uploadRequested = false;
|
|
||||||
bool signingRequested = false;
|
|
||||||
bool publicationRequested = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendActivationReadinessOptions {
|
|
||||||
bool requireActivationOwner = true;
|
|
||||||
bool requireReadOnlyGate = true;
|
|
||||||
bool requireLiteBuild = true;
|
|
||||||
bool requireLiteBackendCapability = true;
|
|
||||||
bool requireResolvedArtifact = true;
|
|
||||||
bool requireLinkedBackend = true;
|
|
||||||
bool requireBridgeAvailable = true;
|
|
||||||
bool requireUsableServer = true;
|
|
||||||
bool rejectArtifactMutation = true;
|
|
||||||
bool rejectSdxlApiCalls = true;
|
|
||||||
bool rejectServerConnectivityChecks = true;
|
|
||||||
bool rejectWalletLifecycle = true;
|
|
||||||
bool rejectSync = true;
|
|
||||||
bool rejectSyncStatusPolling = true;
|
|
||||||
bool rejectWorkerQueue = true;
|
|
||||||
bool rejectWalletStateMutation = true;
|
|
||||||
bool rejectWalletPersistence = true;
|
|
||||||
bool rejectUpload = true;
|
|
||||||
bool rejectSigning = true;
|
|
||||||
bool rejectPublication = true;
|
|
||||||
LiteBackendArtifactResolverOptions resolverOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendActivationReadinessIssueInfo {
|
|
||||||
LiteBackendActivationReadinessIssue issue = LiteBackendActivationReadinessIssue::ActivationOwnerMissing;
|
|
||||||
std::string message;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LiteBackendActivationReadinessResult {
|
|
||||||
bool ok = false;
|
|
||||||
bool readOnlyActivation = true;
|
|
||||||
bool artifactDiscoveryReadOnly = true;
|
|
||||||
bool connectionReadinessOnly = true;
|
|
||||||
bool noBridgeCalls = true;
|
|
||||||
bool noArtifactMutation = true;
|
|
||||||
bool noSdxlCalls = true;
|
|
||||||
bool noServerConnectivityChecked = true;
|
|
||||||
bool noWalletCreated = true;
|
|
||||||
bool noWalletOpened = true;
|
|
||||||
bool noWalletRestored = true;
|
|
||||||
bool noSyncStarted = true;
|
|
||||||
bool noSyncStatusPolled = true;
|
|
||||||
bool noWorkerQueueEnqueue = true;
|
|
||||||
bool noWalletStateMutation = true;
|
|
||||||
bool noWalletPersistence = true;
|
|
||||||
bool noUpload = true;
|
|
||||||
bool noSigning = true;
|
|
||||||
bool noPublication = true;
|
|
||||||
|
|
||||||
bool activationOwnerAccepted = false;
|
|
||||||
bool readOnlyGateAccepted = false;
|
|
||||||
bool liteBuildAccepted = false;
|
|
||||||
bool backendCapabilityAccepted = false;
|
|
||||||
bool artifactResolverAccepted = false;
|
|
||||||
bool backendLinkedAccepted = false;
|
|
||||||
bool bridgeAccepted = false;
|
|
||||||
bool connectionSettingsAccepted = false;
|
|
||||||
bool connectionServiceBoundaryAccepted = false;
|
|
||||||
bool syncReadinessInputsProduced = false;
|
|
||||||
|
|
||||||
LiteBackendActivationReadinessStatus status = LiteBackendActivationReadinessStatus::WaitingForActivationOwner;
|
|
||||||
LiteBackendArtifactResolverResult artifactResolverResult;
|
|
||||||
LiteWalletSdxlArtifactInput syncArtifactInput;
|
|
||||||
LiteWalletLinkedBackendReadinessInput syncBackendInput;
|
|
||||||
LiteConnectionAvailability connectionAvailability = LiteConnectionAvailability::BackendUnavailable;
|
|
||||||
LiteServerSelectionResult selectedServer;
|
|
||||||
WalletBackendStatus connectionStatus;
|
|
||||||
std::vector<LiteBackendActivationReadinessIssueInfo> issues;
|
|
||||||
std::string error;
|
|
||||||
};
|
|
||||||
|
|
||||||
LiteBackendArtifactPlatform currentLiteBackendArtifactPlatform();
|
|
||||||
const char* liteBackendArtifactPlatformName(LiteBackendArtifactPlatform platform);
|
|
||||||
const char* liteBackendArtifactKindName(LiteBackendArtifactKind kind);
|
|
||||||
const char* liteBackendArtifactResolverStatusName(LiteBackendArtifactResolverStatus status);
|
|
||||||
const char* liteBackendArtifactResolverIssueName(LiteBackendArtifactResolverIssue issue);
|
|
||||||
const char* liteBackendActivationReadinessStatusName(LiteBackendActivationReadinessStatus status);
|
|
||||||
const char* liteBackendActivationReadinessIssueName(LiteBackendActivationReadinessIssue issue);
|
|
||||||
|
|
||||||
LiteBackendArtifactResolverResult evaluateLiteBackendArtifactResolver(
|
|
||||||
const LiteBackendArtifactResolverInput& input,
|
|
||||||
LiteBackendArtifactResolverOptions options = {});
|
|
||||||
|
|
||||||
LiteBackendActivationReadinessResult evaluateLiteBackendActivationReadiness(
|
|
||||||
const LiteBackendActivationReadinessInput& input,
|
|
||||||
LiteBackendActivationReadinessOptions options = {});
|
|
||||||
|
|
||||||
class LiteBackendArtifactResolver {
|
|
||||||
public:
|
|
||||||
explicit LiteBackendArtifactResolver(LiteBackendArtifactResolverOptions options = {});
|
|
||||||
|
|
||||||
LiteBackendArtifactResolverResult resolve(const LiteBackendArtifactResolverInput& input) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
LiteBackendArtifactResolverOptions options_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace dragonx::wallet
|
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
#include "ui/windows/mining_tab_helpers.h"
|
#include "ui/windows/mining_tab_helpers.h"
|
||||||
#include "util/amount_format.h"
|
#include "util/amount_format.h"
|
||||||
#include "util/payment_uri.h"
|
#include "util/payment_uri.h"
|
||||||
#include "wallet/lite_backend_artifact_contract.h"
|
|
||||||
#include "wallet/lite_owned_string.h"
|
#include "wallet/lite_owned_string.h"
|
||||||
#include "wallet/lite_wallet_controller.h"
|
#include "wallet/lite_wallet_controller.h"
|
||||||
#include "wallet/lite_wallet_gateway.h"
|
#include "wallet/lite_wallet_gateway.h"
|
||||||
@@ -98,11 +97,6 @@ void writeTestFile(const fs::path& path, const std::string& content)
|
|||||||
output << content;
|
output << content;
|
||||||
}
|
}
|
||||||
|
|
||||||
using LiteBackendArtifactContractInput = dragonx::wallet::LiteBackendArtifactContractInput;
|
|
||||||
using LiteBackendArtifactContractIssue = dragonx::wallet::LiteBackendArtifactContractIssue;
|
|
||||||
using LiteBackendArtifactContractLinkMode = dragonx::wallet::LiteBackendArtifactContractLinkMode;
|
|
||||||
using LiteBackendArtifactContractResult = dragonx::wallet::LiteBackendArtifactContractResult;
|
|
||||||
using LiteBackendArtifactContractStatus = dragonx::wallet::LiteBackendArtifactContractStatus;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -266,42 +260,6 @@ using LiteBackendArtifactContractStatus = dragonx::wallet::LiteBackendArtifactCo
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename Factory>
|
|
||||||
std::unique_ptr<T> heapConstructPlanResult(Factory&& factory)
|
|
||||||
{
|
|
||||||
void* storage = ::operator new(sizeof(T));
|
|
||||||
try {
|
|
||||||
return std::unique_ptr<T>(::new (storage) T(factory()));
|
|
||||||
} catch (...) {
|
|
||||||
::operator delete(storage);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dragonx::wallet::LiteBackendArtifactProvenanceMetadata makeReadyLiteBackendArtifactProvenance()
|
|
||||||
{
|
|
||||||
dragonx::wallet::LiteBackendArtifactProvenanceMetadata provenance;
|
|
||||||
provenance.ownerReady = true;
|
|
||||||
provenance.metadataProvided = true;
|
|
||||||
provenance.source = "test-fixture";
|
|
||||||
provenance.builder = "phase4-tests";
|
|
||||||
provenance.sourceRevision = "test-revision";
|
|
||||||
provenance.artifactSetId = "phase1-contract";
|
|
||||||
provenance.redacted = true;
|
|
||||||
return provenance;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool liteBackendArtifactContractHasIssue(
|
|
||||||
const LiteBackendArtifactContractResult& result,
|
|
||||||
LiteBackendArtifactContractIssue issue)
|
|
||||||
{
|
|
||||||
for (const auto& issueInfo : result.issues) {
|
|
||||||
if (issueInfo.issue == issue) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int g_liteBridgeRuntimeFakeCallCount = 0;
|
int g_liteBridgeRuntimeFakeCallCount = 0;
|
||||||
int g_liteBridgeRuntimeTrackedFreeCount = 0;
|
int g_liteBridgeRuntimeTrackedFreeCount = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user