fix(wallet): ignore stale reachability results

This commit is contained in:
Ricardo Guilherme Schmidt 2026-07-17 20:01:49 -03:00
parent 3721d88386
commit 5c2e4fe462
No known key found for this signature in database
GPG Key ID: 1396EA17DE132FFE
3 changed files with 53 additions and 3 deletions

View File

@ -284,11 +284,16 @@ void WalletController::checkReachability()
if (!m_state.isWalletOpen || m_state.sequencerAddress.isEmpty()) if (!m_state.isWalletOpen || m_state.sequencerAddress.isEmpty())
return; return;
QNetworkRequest request{QUrl(m_state.sequencerAddress)}; const quint64 generation = ++m_reachabilityGeneration;
const QString endpoint = m_state.sequencerAddress;
QNetworkRequest request{QUrl(endpoint)};
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,
if (!m_state.isWalletOpen) { [this, reply, generation, endpoint]() {
if (!m_state.isWalletOpen
|| generation != m_reachabilityGeneration
|| endpoint != m_state.sequencerAddress) {
reply->deleteLater(); reply->deleteLater();
return; return;
} }

View File

@ -73,4 +73,5 @@ private:
QTimer* m_reachabilityTimer; QTimer* m_reachabilityTimer;
bool m_started = false; bool m_started = false;
quint64 m_operationGeneration = 0; quint64 m_operationGeneration = 0;
quint64 m_reachabilityGeneration = 0;
}; };

View File

@ -1,9 +1,12 @@
#include <QFile> #include <QFile>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QHostAddress>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QSettings> #include <QSettings>
#include <QSignalSpy> #include <QSignalSpy>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTemporaryDir> #include <QTemporaryDir>
#include <QTimer> #include <QTimer>
#include <QtTest> #include <QtTest>
@ -65,6 +68,7 @@ private slots:
void controllerStopsReachabilityChecksAfterDisconnect(); void controllerStopsReachabilityChecksAfterDisconnect();
void completedAsyncSnapshotReleasesCallback(); void completedAsyncSnapshotReleasesCallback();
void deferredCallbacksIgnoreDestroyedController(); void deferredCallbacksIgnoreDestroyedController();
void newerReachabilityResultWins();
}; };
void LogosWalletProviderTest::adoptsOpenWalletAndCachesSnapshots() void LogosWalletProviderTest::adoptsOpenWalletAndCachesSnapshots()
@ -530,6 +534,46 @@ void LogosWalletProviderTest::deferredCallbacksIgnoreDestroyedController()
settings.clear(); settings.clear();
} }
void LogosWalletProviderTest::newerReachabilityResultWins()
{
const QString settingsApplication = QStringLiteral("WalletReachabilityOrderTest");
QSettings settings(QStringLiteral("Logos"), settingsApplication);
settings.clear();
QTcpServer server;
QVERIFY(server.listen(QHostAddress::LocalHost));
const QString endpoint = QStringLiteral("http://127.0.0.1:%1").arg(server.serverPort());
FakeWalletProvider provider;
provider.connectResult.snapshot.sequencerAddress = endpoint;
WalletController controller(provider, settingsApplication);
auto* network = controller.findChild<QNetworkAccessManager*>();
QVERIFY(network);
QSignalSpy finished(network, &QNetworkAccessManager::finished);
QVERIFY(controller.open());
QTRY_VERIFY(server.hasPendingConnections());
QTcpSocket* first = server.nextPendingConnection();
QVERIFY(first);
provider.createAccountResult.accountId = ACCOUNT_B;
provider.createAccountResult.snapshot.sequencerAddress = endpoint;
QCOMPARE(controller.createAccount(true), ACCOUNT_B);
QTRY_VERIFY(server.hasPendingConnections());
QTcpSocket* second = server.nextPendingConnection();
QVERIFY(second);
second->write("HTTP/1.1 200 OK\r\nContent-Length: 0\r\nConnection: close\r\n\r\n");
second->disconnectFromHost();
QTRY_COMPARE(finished.size(), 1);
QVERIFY(controller.state().sequencerReachable);
first->disconnectFromHost();
QTRY_COMPARE(finished.size(), 2);
QVERIFY(controller.state().sequencerReachable);
settings.clear();
}
QTEST_GUILESS_MAIN(LogosWalletProviderTest) QTEST_GUILESS_MAIN(LogosWalletProviderTest)
#include "LogosWalletProviderTest.moc" #include "LogosWalletProviderTest.moc"