diff --git a/apps/shared/wallet/src/LogosWalletProvider.cpp b/apps/shared/wallet/src/LogosWalletProvider.cpp index eeb7547..a95c377 100644 --- a/apps/shared/wallet/src/LogosWalletProvider.cpp +++ b/apps/shared/wallet/src/LogosWalletProvider.cpp @@ -323,8 +323,6 @@ WalletCreation LogosWalletProvider::createWallet(const WalletPaths& paths, return creation; } - creation.snapshot = snapshot(true); - creation.failure = creation.snapshot.failure; return creation; } diff --git a/apps/shared/wallet/src/WalletController.cpp b/apps/shared/wallet/src/WalletController.cpp index 39aa47e..d7c34ee 100644 --- a/apps/shared/wallet/src/WalletController.cpp +++ b/apps/shared/wallet/src/WalletController.cpp @@ -166,6 +166,7 @@ QString WalletController::createWallet(const QString& configPath, const QString& storagePath, const QString& password) { + const quint64 generation = ++m_operationGeneration; const QString config = toLocalPath(configPath); const QString storage = toLocalPath(storagePath); const WalletCreation creation = m_wallet.createWallet( @@ -175,6 +176,7 @@ QString WalletController::createWallet(const QString& configPath, << walletFailureCode(creation.failure); return {}; } + stopReachability(); m_state.configPath = config; m_state.storagePath = storage; @@ -192,9 +194,32 @@ QString WalletController::createWallet(const QString& configPath, m_state.walletExists = true; m_state.isWalletOpen = true; - m_state.syncStatus = QStringLiteral("ready"); + m_state.syncStatus = QStringLiteral("syncing"); m_state.syncError.clear(); - applySnapshot(creation.snapshot); + m_accountModel->replaceAccounts({}); + emit stateChanged(); + + const QPointer guard(this); + QTimer::singleShot(0, this, [guard, generation]() { + if (!guard || generation != guard->m_operationGeneration) + return; + guard->m_wallet.snapshotAsync(true, + [guard, generation](WalletSnapshot snapshot) { + if (!guard || generation != guard->m_operationGeneration) + return; + if (snapshot.ok()) { + guard->m_state.syncStatus = QStringLiteral("ready"); + guard->applySnapshot(snapshot); + return; + } + + qWarning() << "WalletController: initial wallet sync failed" + << walletFailureCode(snapshot.failure); + guard->m_state.syncStatus = QStringLiteral("error"); + guard->m_state.syncError = walletFailureCode(snapshot.failure); + emit guard->stateChanged(); + }); + }); return creation.mnemonic; } diff --git a/apps/shared/wallet/tests/cpp/LogosWalletProviderTest.cpp b/apps/shared/wallet/tests/cpp/LogosWalletProviderTest.cpp index 94db985..55fed17 100644 --- a/apps/shared/wallet/tests/cpp/LogosWalletProviderTest.cpp +++ b/apps/shared/wallet/tests/cpp/LogosWalletProviderTest.cpp @@ -68,6 +68,7 @@ private slots: void fakeProviderImplementsConsumerContract(); void controllerOwnsUiWalletFlow(); void controllerOpenDoesNotWaitForWalletSync(); + void controllerCreationDoesNotWaitForWalletSync(); void controllerStopsReachabilityChecksAfterDisconnect(); void completedAsyncSnapshotReleasesCallback(); void deferredCallbacksIgnoreDestroyedController(); @@ -161,6 +162,9 @@ void LogosWalletProviderTest::createsAndPersistsWallet() QVERIFY(directory.isValid()); LogosModules modules; + modules.logos_execution_zone.currentBlockHeight = 12; + modules.logos_execution_zone.accounts = { accountEntry(ACCOUNT_A, true) }; + modules.logos_execution_zone.publicAccounts.insert(ACCOUNT_A, publicAccountJson()); LogosWalletProvider provider(&modules); const WalletPaths paths { directory.filePath(QStringLiteral("config/wallet.json")), @@ -174,6 +178,9 @@ void LogosWalletProviderTest::createsAndPersistsWallet() QCOMPARE(modules.logos_execution_zone.createdStorage, paths.storage); QCOMPARE(modules.logos_execution_zone.createdPassword, QStringLiteral("secret")); QVERIFY(modules.logos_execution_zone.saveCalls >= 1); + QCOMPARE(modules.logos_execution_zone.syncCalls, 0); + QCOMPARE(modules.logos_execution_zone.listCalls, 0); + QCOMPARE(modules.logos_execution_zone.publicReadCalls, 0); LogosModules rejectedModules; rejectedModules.logos_execution_zone.mnemonic.clear(); @@ -567,6 +574,40 @@ void LogosWalletProviderTest::controllerOpenDoesNotWaitForWalletSync() settings.clear(); } +void LogosWalletProviderTest::controllerCreationDoesNotWaitForWalletSync() +{ + const QString settingsApplication = QStringLiteral("WalletAsyncCreationTest"); + QSettings settings(QStringLiteral("Logos"), settingsApplication); + settings.clear(); + + FakeWalletProvider provider; + provider.deferAsync = true; + provider.createWalletResult.mnemonic = QStringLiteral("one two three"); + provider.snapshotResult.accounts = { + { ACCOUNT_A, QStringLiteral("5"), true }, + }; + WalletController controller(provider, settingsApplication); + + QCOMPARE(controller.createDefaultWallet(QStringLiteral("secret")), + provider.createWalletResult.mnemonic); + QCOMPARE(provider.createWalletCalls, 1); + QCOMPARE(provider.snapshotCalls, 0); + QVERIFY(controller.state().isWalletOpen); + QCOMPARE(controller.state().syncStatus, QStringLiteral("syncing")); + QVERIFY(!controller.state().canSubmit()); + QCOMPARE(controller.accountModel()->count(), 0); + + QTRY_COMPARE(provider.snapshotCalls, 1); + QVERIFY(provider.lastForceRefresh); + QCOMPARE(controller.state().syncStatus, QStringLiteral("syncing")); + provider.finishSnapshot(); + + QCOMPARE(controller.state().syncStatus, QStringLiteral("ready")); + QVERIFY(controller.state().canSubmit()); + QCOMPARE(controller.accountModel()->count(), 1); + settings.clear(); +} + void LogosWalletProviderTest::controllerStopsReachabilityChecksAfterDisconnect() { const QString settingsApplication = QStringLiteral("WalletReachabilityTest");