fix(wallet): stop disconnected reachability polling

Skip reachability requests and stale callbacks after the wallet closes. Keep fake account reads aligned with the provider contract by echoing the requested account ID.
This commit is contained in:
Ricardo Guilherme Schmidt 2026-07-15 15:06:44 -03:00
parent ebb1b87399
commit fa1b0fd3c3
No known key found for this signature in database
GPG Key ID: 1396EA17DE132FFE
3 changed files with 42 additions and 3 deletions

View File

@ -215,13 +215,17 @@ void WalletController::applySnapshot(const WalletSnapshot& snapshot)
void WalletController::checkReachability() void WalletController::checkReachability()
{ {
if (m_state.sequencerAddress.isEmpty()) if (!m_state.isWalletOpen || m_state.sequencerAddress.isEmpty())
return; return;
QNetworkRequest request{QUrl(m_state.sequencerAddress)}; QNetworkRequest request{QUrl(m_state.sequencerAddress)};
request.setTransferTimeout(4000); request.setTransferTimeout(4000);
QNetworkReply* reply = m_network->get(request); QNetworkReply* reply = m_network->get(request);
connect(reply, &QNetworkReply::finished, this, [this, reply]() { connect(reply, &QNetworkReply::finished, this, [this, reply]() {
if (!m_state.isWalletOpen) {
reply->deleteLater();
return;
}
const bool receivedHttp = const bool receivedHttp =
reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).isValid(); reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).isValid();
const bool reachable = receivedHttp || reply->error() == QNetworkReply::NoError; const bool reachable = receivedHttp || reply->error() == QNetworkReply::NoError;

View File

@ -1,9 +1,11 @@
#include <QFile> #include <QFile>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QNetworkAccessManager>
#include <QSettings> #include <QSettings>
#include <QSignalSpy> #include <QSignalSpy>
#include <QTemporaryDir> #include <QTemporaryDir>
#include <QTimer>
#include <QtTest> #include <QtTest>
#include "FakeWalletProvider.h" #include "FakeWalletProvider.h"
@ -56,6 +58,7 @@ private slots:
void exposesStableAccountModelRoles(); void exposesStableAccountModelRoles();
void fakeProviderImplementsConsumerContract(); void fakeProviderImplementsConsumerContract();
void controllerOwnsUiWalletFlow(); void controllerOwnsUiWalletFlow();
void controllerStopsReachabilityChecksAfterDisconnect();
}; };
void LogosWalletProviderTest::adoptsOpenWalletAndCachesSnapshots() void LogosWalletProviderTest::adoptsOpenWalletAndCachesSnapshots()
@ -358,6 +361,8 @@ void LogosWalletProviderTest::fakeProviderImplementsConsumerContract()
QCOMPARE(provider.snapshot(true).accounts.size(), 1); QCOMPARE(provider.snapshot(true).accounts.size(), 1);
QVERIFY(provider.lastForceRefresh); QVERIFY(provider.lastForceRefresh);
QCOMPARE(provider.readPublicAccount(ACCOUNT_B).accountId, ACCOUNT_B);
QCOMPARE(provider.readCalls, 1);
WalletTransaction transaction { PROGRAM_ID, { ACCOUNT_A }, { true }, { 9 } }; WalletTransaction transaction { PROGRAM_ID, { ACCOUNT_A }, { true }, { 9 } };
QVERIFY(provider.submitPublicTransaction(transaction).accepted()); QVERIFY(provider.submitPublicTransaction(transaction).accepted());
QCOMPARE(provider.lastTransaction.instruction, transaction.instruction); QCOMPARE(provider.lastTransaction.instruction, transaction.instruction);
@ -414,6 +419,34 @@ void LogosWalletProviderTest::controllerOwnsUiWalletFlow()
settings.clear(); settings.clear();
} }
void LogosWalletProviderTest::controllerStopsReachabilityChecksAfterDisconnect()
{
const QString settingsApplication = QStringLiteral("WalletReachabilityTest");
QSettings settings(QStringLiteral("Logos"), settingsApplication);
settings.clear();
FakeWalletProvider provider;
provider.connectResult.snapshot.sequencerAddress = QStringLiteral("http://127.0.0.1:1");
WalletController controller(provider, settingsApplication);
auto* network = controller.findChild<QNetworkAccessManager*>();
QVERIFY(network);
QSignalSpy finished(network, &QNetworkAccessManager::finished);
QVERIFY(controller.open());
QTRY_VERIFY_WITH_TIMEOUT(!finished.isEmpty(), 1000);
controller.disconnect();
finished.clear();
auto* timer = controller.findChild<QTimer*>();
QVERIFY(timer);
timer->setInterval(1);
controller.start();
QTest::qWait(50);
QCOMPARE(finished.count(), 0);
settings.clear();
}
QTEST_GUILESS_MAIN(LogosWalletProviderTest) QTEST_GUILESS_MAIN(LogosWalletProviderTest)
#include "LogosWalletProviderTest.moc" #include "LogosWalletProviderTest.moc"

View File

@ -55,10 +55,12 @@ public:
return createAccountResult; return createAccountResult;
} }
WalletAccountRead readPublicAccount(const QString&) const override WalletAccountRead readPublicAccount(const QString& accountId) const override
{ {
++readCalls; ++readCalls;
return readResult; WalletAccountRead result = readResult;
result.accountId = accountId;
return result;
} }
WalletSubmission submitPublicTransaction( WalletSubmission submitPublicTransaction(