diff --git a/src/BlockchainBackend.cpp b/src/BlockchainBackend.cpp index c0ffa05..3d8cae1 100644 --- a/src/BlockchainBackend.cpp +++ b/src/BlockchainBackend.cpp @@ -47,15 +47,23 @@ static QString toErrorMessage(const LogosResult& result) return QStringLiteral("Error: %1").arg(result.error.toString()); } -// QML callers distinguish success from failure by sniffing for an "Error" -// prefix (see BlockchainView.qml), so both branches must share this type. -// TODO: Currently functions are returning a string (for ok and ko cases), which is later re-parsed to know if the call -// succeeded or failed. We can simplify this by returning the result itself upward. +// Renders the balance column text in AccountsModel. getBalance() and +// transferFunds() return the LogosResult itself (see toVariantMap) so QML +// branches on success/error directly instead of re-parsing a string. static QString toDisplayMessage(const LogosResult& result) { return result.success ? result.value.toString() : toErrorMessage(result); } +static QVariantMap toVariantMap(const LogosResult& result) +{ + return QVariantMap{ + {"success", result.success}, + {"value", result.value}, + {"error", result.error}, + }; +} + BlockchainBackend::BlockchainBackend(LogosAPI* logosAPI, QObject* parent) : BlockchainBackendSimpleSource(parent) , m_logosAPI(logosAPI) @@ -147,12 +155,12 @@ BlockchainBackend::~BlockchainBackend() stopBlockchain(); } -QString BlockchainBackend::claimLeaderRewards() +QVariantMap BlockchainBackend::claimLeaderRewards() { if (!m_blockchainClient) - return QStringLiteral("Error: Module not initialized."); + return toVariantMap(LogosResult{false, QVariant(), QStringLiteral("Module not initialized.")}); - return toDisplayMessage(toLogosResult(m_blockchainClient->invokeRemoteMethod( + return toVariantMap(toLogosResult(m_blockchainClient->invokeRemoteMethod( BLOCKCHAIN_MODULE_NAME, "leader_claim"))); } @@ -224,39 +232,36 @@ void BlockchainBackend::fetchBalancesForAccounts(const QStringList& list) } } -QString BlockchainBackend::getBalance(QString addressHex) +QVariantMap BlockchainBackend::getBalance(QString addressHex) { - QString result; - if (!m_blockchainClient) { - result = QStringLiteral("Error: Module not initialized."); - } else { - result = toDisplayMessage(toLogosResult(m_blockchainClient->invokeRemoteMethod( - BLOCKCHAIN_MODULE_NAME, "wallet_get_balance", addressHex))); - } + const LogosResult lr = m_blockchainClient + ? toLogosResult(m_blockchainClient->invokeRemoteMethod( + BLOCKCHAIN_MODULE_NAME, "wallet_get_balance", addressHex)) + : LogosResult{false, QVariant(), QStringLiteral("Module not initialized.")}; - m_accountsModel->setBalanceForAddress(addressHex, result); - return result; + m_accountsModel->setBalanceForAddress(addressHex, toDisplayMessage(lr)); + return toVariantMap(lr); } -QString BlockchainBackend::transferFunds( +QVariantMap BlockchainBackend::transferFunds( QString fromKeyHex, QString toKeyHex, QString amountStr) { if (!m_blockchainClient) - return QStringLiteral("Error: Module not initialized."); + return toVariantMap(LogosResult{false, QVariant(), QStringLiteral("Module not initialized.")}); QStringList senders{fromKeyHex}; - return toDisplayMessage(toLogosResult(m_blockchainClient->invokeRemoteMethod( + return toVariantMap(toLogosResult(m_blockchainClient->invokeRemoteMethod( BLOCKCHAIN_MODULE_NAME, "wallet_transfer_funds", fromKeyHex, senders, toKeyHex, amountStr, QString()))); } -int BlockchainBackend::generateConfig( +QVariantMap BlockchainBackend::generateConfig( QString outputPath, QStringList initialPeers, int netPort, int blendPort, QString httpAddr, QString externalAddress, bool noPublicIpCheck, int deploymentMode, QString deploymentConfigPath, QString statePath) { if (!m_blockchainClient) - return -1; + return toVariantMap(LogosResult{false, QVariant(), QStringLiteral("Module not initialized.")}); QVariantMap normalized; @@ -304,10 +309,8 @@ int BlockchainBackend::generateConfig( const QString jsonToSend = QString::fromUtf8(doc.toJson(QJsonDocument::Compact)); - const LogosResult result = toLogosResult(m_blockchainClient->invokeRemoteMethod( - BLOCKCHAIN_MODULE_NAME, "generate_user_config", jsonToSend)); - - return result.success ? 0 : -1; + return toVariantMap(toLogosResult(m_blockchainClient->invokeRemoteMethod( + BLOCKCHAIN_MODULE_NAME, "generate_user_config", jsonToSend))); } void BlockchainBackend::clearLogs() diff --git a/src/BlockchainBackend.h b/src/BlockchainBackend.h index 5e9d0e3..b628f57 100644 --- a/src/BlockchainBackend.h +++ b/src/BlockchainBackend.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "rep_BlockchainBackend_source.h" @@ -41,10 +42,10 @@ public slots: void startBlockchain() override; void stopBlockchain() override; void refreshAccounts() override; - QString getBalance(QString addressHex) override; - QString transferFunds(QString fromKeyHex, QString toKeyHex, QString amountStr) override; - QString claimLeaderRewards() override; - int generateConfig(QString outputPath, QStringList initialPeers, int netPort, + QVariantMap getBalance(QString addressHex) override; + QVariantMap transferFunds(QString fromKeyHex, QString toKeyHex, QString amountStr) override; + QVariantMap claimLeaderRewards() override; + QVariantMap generateConfig(QString outputPath, QStringList initialPeers, int netPort, int blendPort, QString httpAddr, QString externalAddress, bool noPublicIpCheck, int deploymentMode, QString deploymentConfigPath, QString statePath) override; diff --git a/src/BlockchainBackend.rep b/src/BlockchainBackend.rep index b75e191..c657fbc 100644 --- a/src/BlockchainBackend.rep +++ b/src/BlockchainBackend.rep @@ -12,10 +12,10 @@ class BlockchainBackend SLOT(void startBlockchain()) SLOT(void stopBlockchain()) SLOT(void refreshAccounts()) - SLOT(QString getBalance(QString addressHex)) - SLOT(QString transferFunds(QString fromKeyHex, QString toKeyHex, QString amountStr)) - SLOT(QString claimLeaderRewards()) - SLOT(int generateConfig(QString outputPath, QStringList initialPeers, int netPort, int blendPort, QString httpAddr, QString externalAddress, bool noPublicIpCheck, int deploymentMode, QString deploymentConfigPath, QString statePath)) + SLOT(QVariantMap getBalance(QString addressHex)) + SLOT(QVariantMap transferFunds(QString fromKeyHex, QString toKeyHex, QString amountStr)) + SLOT(QVariantMap claimLeaderRewards()) + SLOT(QVariantMap generateConfig(QString outputPath, QStringList initialPeers, int netPort, int blendPort, QString httpAddr, QString externalAddress, bool noPublicIpCheck, int deploymentMode, QString deploymentConfigPath, QString statePath)) SLOT(void clearLogs()) SLOT(void copyToClipboard(QString text)) } diff --git a/src/qml/BlockchainView.qml b/src/qml/BlockchainView.qml index bd4832d..6e41136 100644 --- a/src/qml/BlockchainView.qml +++ b/src/qml/BlockchainView.qml @@ -41,6 +41,10 @@ Rectangle { QtObject { id: _d + function errorText(message) { + return qsTr("Error: %1").arg(message) + } + function getStatusString(s) { switch(s) { case BlockchainBackend.NotStarted: return qsTr("Not Started") @@ -48,7 +52,7 @@ Rectangle { case BlockchainBackend.Running: return qsTr("Running") case BlockchainBackend.Stopping: return qsTr("Stopping...") case BlockchainBackend.Stopped: return qsTr("Stopped") - case BlockchainBackend.Error: return qsTr("Error: %1").arg(root.backend.lastErrorMessage) + case BlockchainBackend.Error: return _d.errorText(root.backend.lastErrorMessage) default: return qsTr("Unknown") } } @@ -120,16 +124,14 @@ Rectangle { outputPath, initialPeers, netPort, blendPort, httpAddr, externalAddress, noPublicIpCheck, deploymentMode, deploymentConfigPath, statePath), - function(code) { - // logos.watch stringifies the returned int — coerce back. - var rc = parseInt(code, 10) - console.log("[BlockchainView] generateConfig success callback: code=", code, "type=", typeof code, "→ rc=", rc) - configChoiceView.generateResultSuccess = (rc === 0) + function(result) { + console.log("[BlockchainView] generateConfig success callback: result=", JSON.stringify(result)) + configChoiceView.generateResultSuccess = result.success configChoiceView.generateResultMessage = - rc === 0 + result.success ? qsTr("Config generated successfully.") - : qsTr("Generate failed (code: %1).").arg(rc) - if (rc === 0) { + : qsTr("Generate failed: %1").arg(result.error) + if (result.success) { root.backend.userConfig = (outputPath !== "") ? outputPath : root.backend.generatedUserConfigPath root.backend.deploymentConfig = @@ -192,17 +194,17 @@ Rectangle { logos.watch( root.backend.getBalance(addressHex), function(result) { - if ((result || "").indexOf("Error") === 0) { - walletView.lastBalanceErrorAddress = addressHex - walletView.lastBalanceError = result - } else { + if (result.success) { walletView.lastBalanceErrorAddress = "" walletView.lastBalanceError = "" + } else { + walletView.lastBalanceErrorAddress = addressHex + walletView.lastBalanceError = _d.errorText(result.error) } }, function(error) { walletView.lastBalanceErrorAddress = addressHex - walletView.lastBalanceError = "Error: " + error + walletView.lastBalanceError = _d.errorText(error) } ) } @@ -213,16 +215,28 @@ Rectangle { if (!root.backend) return logos.watch( root.backend.transferFunds(fromKeyHex, toKeyHex, amount), - function(result) { walletView.setTransferResult(result) }, - function(error) { walletView.setTransferResult("Error: " + error) } + function(result) { + if (result.success) { + walletView.setTransferResult(result.value) + } else { + walletView.setTransferResult(_d.errorText(result.error)) + } + }, + function(error) { walletView.setTransferResult(_d.errorText(error)) } ) } onClaimLeaderRewardsRequested: function() { if (!root.backend) return logos.watch( root.backend.claimLeaderRewards(), - function(result) { walletView.setLeaderClaimResult(result) }, - function(error) { walletView.setLeaderClaimResult("Error: " + error) } + function(result) { + if (result.success) { + walletView.setLeaderClaimResult(result.value) + } else { + walletView.setLeaderClaimResult(_d.errorText(result.error)) + } + }, + function(error) { walletView.setLeaderClaimResult(_d.errorText(error)) } ) } }