[#691] Adopt sync/async synchronizer changes (#696)

- async APIs called instead of a sync one
- tests fixed
This commit is contained in:
Lukas Korba 2023-03-23 16:10:18 +01:00 committed by GitHub
parent 8294415a69
commit ef26c835c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 80 additions and 56 deletions

View File

@ -3546,8 +3546,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/zcash/ZcashLightClientKit.git";
requirement = {
kind = revision;
revision = c88fd684e8bea7f6c8c0ff799220a42361239af9;
branch = feature/831_solve_async_nonasync;
kind = branch;
};
};
6654C7382715A38000901167 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */ = {

View File

@ -338,7 +338,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash/ZcashLightClientKit.git",
"state" : {
"revision" : "c88fd684e8bea7f6c8c0ff799220a42361239af9"
"branch" : "feature/831_solve_async_nonasync",
"revision" : "cbf82ca668712d513f3aba48844fe03e7fe1eec9"
}
}
],

View File

@ -23,9 +23,9 @@ struct SDKSynchronizerClient {
let latestState: () -> SynchronizerState
let latestScannedHeight: () -> BlockHeight
let prepareWith: ([UInt8], UnifiedFullViewingKey, BlockHeight) throws -> Void
let start: (_ retry: Bool) throws -> Void
let stop: () -> Void
let prepareWith: ([UInt8], UnifiedFullViewingKey, BlockHeight) async throws -> Void
let start: (_ retry: Bool) async throws -> Void
let stop: () async -> Void
let isSyncing: () -> Bool
let isInitialized: () -> Bool

View File

@ -39,14 +39,14 @@ extension SDKSynchronizerClient: DependencyKey {
latestState: { synchronizer.latestState },
latestScannedHeight: { synchronizer.latestScannedHeight },
prepareWith: { seedBytes, viewingKey, walletBirtday in
let result = try synchronizer.prepare(with: seedBytes, viewingKeys: [viewingKey], walletBirthday: walletBirtday)
let result = try await synchronizer.prepare(with: seedBytes, viewingKeys: [viewingKey], walletBirthday: walletBirtday)
if result != .success {
throw SynchronizerError.initFailed(message: "")
}
},
start: { retry in try synchronizer.start(retry: retry) },
stop: { synchronizer.stop() },
start: { retry in try await synchronizer.start(retry: retry) },
stop: { await synchronizer.stop() },
isSyncing: { synchronizer.latestState.syncStatus.isSyncing },
isInitialized: { synchronizer.latestState.syncStatus != .unprepared },
rewind: { synchronizer.rewind($0) },

View File

@ -70,6 +70,7 @@ struct HomeReducer: ReducerProtocol {
case profile(ProfileReducer.Action)
case send(SendFlowReducer.Action)
case settings(SettingsReducer.Action)
case syncFailed(String)
case synchronizerStateChanged(SynchronizerState)
case walletEvents(WalletEventsFlowReducer.Action)
case updateDestination(HomeReducer.State.Destination?)
@ -173,17 +174,13 @@ struct HomeReducer: ReducerProtocol {
return .none
case .retrySync:
do {
try sdkSynchronizer.start(true)
} catch {
state.alert = AlertState<HomeReducer.Action>(
title: TextState(L10n.Home.SyncFailed.title),
message: TextState(error.localizedDescription),
primaryButton: .default(TextState(L10n.Home.SyncFailed.retry), action: .send(.retrySync)),
secondaryButton: .default(TextState(L10n.General.ok), action: .send(.dismissAlert))
)
return .run { send in
do {
try await sdkSynchronizer.start(true)
} catch {
await send(.syncFailed(error.localizedDescription))
}
}
return .none
case .showSynchronizerErrorAlert(let snapshot):
state.alert = HomeStore.syncErrorAlert(with: snapshot)
@ -202,6 +199,15 @@ struct HomeReducer: ReducerProtocol {
case .dismissAlert:
state.alert = nil
return .none
case .syncFailed(let errorMessage):
state.alert = AlertState<HomeReducer.Action>(
title: TextState(L10n.Home.SyncFailed.title),
message: TextState(errorMessage),
primaryButton: .default(TextState(L10n.Home.SyncFailed.retry), action: .send(.retrySync)),
secondaryButton: .default(TextState(L10n.General.ok), action: .send(.dismissAlert))
)
return .none
}
}
}

View File

@ -19,6 +19,7 @@ extension RootReducer {
indirect enum DebugAction: Equatable {
case cancelRescan
case cantStartSync(String)
case flagUpdated
case fullRescan
case quickRescan
@ -70,15 +71,12 @@ extension RootReducer {
dismissButton: .default(TextState(L10n.General.ok), action: .send(.dismissAlert))
)
} else {
do {
try sdkSynchronizer.start(false)
} catch {
// TODO: [#221] Handle error more properly (https://github.com/zcash/secant-ios-wallet/issues/221)
state.alert = AlertState(
title: TextState(L10n.Root.Debug.Alert.Rewind.CantStartSync.title),
message: TextState(L10n.Root.Debug.Alert.Rewind.CantStartSync.message(error.localizedDescription)),
dismissButton: .default(TextState(L10n.General.ok), action: .send(.dismissAlert))
)
return .run { send in
do {
try await sdkSynchronizer.start(false)
} catch {
await send(.debug(.cantStartSync(error.localizedDescription)))
}
}
}
@ -101,6 +99,15 @@ extension RootReducer {
case let .debug(.walletConfigLoaded(walletConfig)):
return EffectTask(value: .updateStateAfterConfigUpdate(walletConfig))
case .debug(.cantStartSync(let errorMessage)):
// TODO: [#221] Handle error more properly (https://github.com/zcash/secant-ios-wallet/issues/221)
state.alert = AlertState(
title: TextState(L10n.Root.Debug.Alert.Rewind.CantStartSync.title),
message: TextState(L10n.Root.Debug.Alert.Rewind.CantStartSync.message(errorMessage)),
dismissButton: .default(TextState(L10n.General.ok), action: .send(.dismissAlert))
)
return .none
default: return .none
}
}

View File

@ -20,6 +20,7 @@ extension RootReducer {
case checkWalletConfig
case initializeSDK
case initialSetups
case initializationFailed(String)
case nukeWallet
case nukeWalletRequest
case respondToWalletInitializationState(InitializationState)
@ -137,18 +138,16 @@ extension RootReducer {
let spendingKey = try derivationTool.deriveSpendingKey(seedBytes, 0)
let viewingKey = try spendingKey.deriveFullViewingKey()
try sdkSynchronizer.prepareWith(seedBytes, viewingKey, birthday)
try sdkSynchronizer.start(false)
return .none
return .run { send in
do {
try await sdkSynchronizer.prepareWith(seedBytes, viewingKey, birthday)
try await sdkSynchronizer.start(false)
} catch {
await send(.initialization(.initializationFailed(error.localizedDescription)))
}
}
} catch {
state.appInitializationState = .failed
// TODO: [#221] Handle error more properly (https://github.com/zcash/secant-ios-wallet/issues/221)
state.alert = AlertState(
title: TextState(L10n.Root.Initialization.Alert.SdkInitFailed.title),
message: TextState(L10n.Root.Initialization.Alert.Error.message(error.localizedDescription)),
dismissButton: .default(TextState(L10n.General.ok), action: .send(.dismissAlert))
)
return .none
return EffectTask(value: .initialization(.initializationFailed(error.localizedDescription)))
}
case .initialization(.checkBackupPhraseValidation):
@ -310,6 +309,16 @@ extension RootReducer {
state.homeState.walletConfig = walletConfig
return .none
case .initialization(.initializationFailed(let errorMessage)):
state.appInitializationState = .failed
// TODO: [#221] Handle error more properly (https://github.com/zcash/secant-ios-wallet/issues/221)
state.alert = AlertState(
title: TextState(L10n.Root.Initialization.Alert.SdkInitFailed.title),
message: TextState(L10n.Root.Initialization.Alert.Error.message(errorMessage)),
dismissButton: .default(TextState(L10n.General.ok), action: .send(.dismissAlert))
)
return .none
case .dismissAlert:
state.alert = nil
return .none

View File

@ -141,20 +141,22 @@ class RootTests: XCTestCase {
state.appInitializationState = .filesMissing
}
store.receive(.initialization(.initializeSDK)) { state in
store.receive(.initialization(.initializeSDK))
store.receive(.initialization(.checkBackupPhraseValidation)) { state in
// failed is expected because environment is throwing errors
state.appInitializationState = .failed
state.alert = AlertState(
title: TextState("Failed to initialize the SDK"),
message: TextState("Error: \(walletStorageError.localizedDescription)"),
title: TextState("Wallet initialisation failed."),
message: TextState("Can't load seed phrase from local storage."),
dismissButton: .default(TextState("Ok"), action: .send(.dismissAlert))
)
}
store.receive(.initialization(.checkBackupPhraseValidation)) { state in
store.receive(.initialization(.initializationFailed(walletStorageError.localizedDescription))) { state in
state.alert = AlertState(
title: TextState("Wallet initialisation failed."),
message: TextState("Can't load seed phrase from local storage."),
title: TextState("Failed to initialize the SDK"),
message: TextState("Error: \(walletStorageError.localizedDescription)"),
dismissButton: .default(TextState("Ok"), action: .send(.dismissAlert))
)
}
@ -172,20 +174,22 @@ class RootTests: XCTestCase {
store.send(.initialization(.respondToWalletInitializationState(.initialized)))
store.receive(.initialization(.initializeSDK)) { state in
store.receive(.initialization(.initializeSDK))
store.receive(.initialization(.checkBackupPhraseValidation)) { state in
// failed is expected because environment is throwing errors
state.appInitializationState = .failed
state.alert = AlertState(
title: TextState("Failed to initialize the SDK"),
message: TextState("Error: \(walletStorageError.localizedDescription)"),
title: TextState("Wallet initialisation failed."),
message: TextState("Can't load seed phrase from local storage."),
dismissButton: .default(TextState("Ok"), action: .send(.dismissAlert))
)
}
store.receive(.initialization(.checkBackupPhraseValidation)) { state in
store.receive(.initialization(.initializationFailed(walletStorageError.localizedDescription))) { state in
state.alert = AlertState(
title: TextState("Wallet initialisation failed."),
message: TextState("Can't load seed phrase from local storage."),
title: TextState("Failed to initialize the SDK"),
message: TextState("Error: \(walletStorageError.localizedDescription)"),
dismissButton: .default(TextState("Ok"), action: .send(.dismissAlert))
)
}

View File

@ -84,7 +84,6 @@ class ScanTests: XCTestCase {
store.dependencies.mainQueue = testScheduler.eraseToAnyScheduler()
store.dependencies.uriParser.isValidURI = { _ in true }
let address = "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po".redacted
store.send(.scan(address)) { state in
state.scanStatus = .value(address)

View File

@ -635,8 +635,6 @@ class SendTests: XCTestCase {
state.memoState.charLimit = 512
}
//store.receive(.synchronizerStateChanged(.unknown))
// .onAppear action starts long living cancelable action .synchronizerStateChanged
// .onDisappear cancels it, must have for the test to pass
store.send(.onDisappear)