Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ABW-1568 Don't Crash When Importing Zero Olympia Accounts #582

Merged
merged 1 commit into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extension ImportLegacyWalletClient: DependencyKey {
@Dependency(\.accountsClient) var accountsClient

@Sendable func migrate(
accounts: Set<OlympiaAccountToMigrate>,
accounts: NonEmpty<Set<OlympiaAccountToMigrate>>,
factorSouceID: FactorSourceID
) async throws -> (accounts: NonEmpty<OrderedSet<MigratedAccount>>, networkID: NetworkID) {
let sortedOlympia = accounts.sorted(by: \.addressIndex)
Expand Down Expand Up @@ -41,7 +41,9 @@ extension ImportLegacyWalletClient: DependencyKey {
accountsSet.append(migrated)
}

let accounts = NonEmpty<OrderedSet<MigratedAccount>>(rawValue: accountsSet)!
guard let accounts = NonEmpty<OrderedSet<MigratedAccount>>(rawValue: accountsSet) else {
throw NoValidatedAccountsError()
}

// Save all accounts
for account in accounts {
Expand Down Expand Up @@ -81,8 +83,12 @@ extension ImportLegacyWalletClient: DependencyKey {
let olympiaFactorSource = request.olympiaFactorSource
let factorSource = olympiaFactorSource?.factorSource

guard let olympiaAccounts = NonEmpty<Set>(request.olympiaAccounts) else {
throw NoValidatedAccountsError()
}

let (accounts, networkID) = try await migrate(
accounts: request.olympiaAccounts,
accounts: olympiaAccounts,
factorSouceID: request.olympiaFactorSouceID
)

Expand Down Expand Up @@ -137,6 +143,8 @@ extension ImportLegacyWalletClient: DependencyKey {
}
)
}()

struct NoValidatedAccountsError: Error {}
}

func convert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ public struct MigrateOlympiaSoftwareAccountsToBabylonRequest: Sendable, Hashable

// MARK: - MigrateOlympiaHardwareAccountsToBabylonRequest
public struct MigrateOlympiaHardwareAccountsToBabylonRequest: Sendable, Hashable {
public let olympiaAccounts: Set<OlympiaAccountToMigrate>
public let olympiaAccounts: NonEmpty<Set<OlympiaAccountToMigrate>>
public let ledgerFactorSourceID: FactorSourceID

public init(
olympiaAccounts: Set<OlympiaAccountToMigrate>,
olympiaAccounts: NonEmpty<Set<OlympiaAccountToMigrate>>,
ledgerFactorSourceID: FactorSourceID
) {
self.olympiaAccounts = olympiaAccounts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public struct ImportOlympiaLedgerAccountsAndFactorSources: Sendable, FeatureRedu

public enum InternalAction: Sendable, Equatable {
/// Validated public keys against expected, then migrate...
case validatedAccounts(Set<OlympiaAccountToMigrate>, LedgerHardwareWalletFactorSource)
case validatedAccounts(NonEmpty<Set<OlympiaAccountToMigrate>>, LedgerHardwareWalletFactorSource)

/// migrated accounts of validated public keys
case migratedOlympiaHardwareAccounts(LedgerWithAccounts)
Expand Down Expand Up @@ -148,7 +148,7 @@ public struct ImportOlympiaLedgerAccountsAndFactorSources: Sendable, FeatureRedu
)
return .none

case let .derivePublicKeys(.presented(.delegate(.failedToDerivePublicKey))):
case .derivePublicKeys(.presented(.delegate(.failedToDerivePublicKey))):
loggerGlobal.error("ImportOlympiaAccountsAndFactorSource - child derivePublicKeys failed to derive public key")
state.derivePublicKeys = nil
return .none
Expand All @@ -173,7 +173,10 @@ public struct ImportOlympiaLedgerAccountsAndFactorSources: Sendable, FeatureRedu
.run { [olympiaAccountsToValidate = state.unmigrated.unvalidated] send in
do {
let validation = try await validate(derivedPublicKeys: derivedPublicKeys, olympiaAccountsToValidate: olympiaAccountsToValidate)
await send(.internal(.validatedAccounts(validation.validated, ledger)))
guard let validated = NonEmpty<Set>(validation.validated) else {
throw NoValidatedAccountsError()
}
await send(.internal(.validatedAccounts(validated, ledger)))
} catch {
loggerGlobal.error("Failed to validate accounts, error: \(error)")
errorQueue.schedule(error)
Expand All @@ -183,7 +186,7 @@ public struct ImportOlympiaLedgerAccountsAndFactorSources: Sendable, FeatureRedu

private func convertHardwareAccountsToBabylon(
ledger: LedgerHardwareWalletFactorSource,
validatedAccountsToMigrate olympiaAccounts: Set<OlympiaAccountToMigrate>,
validatedAccountsToMigrate olympiaAccounts: NonEmpty<Set<OlympiaAccountToMigrate>>,
_ state: State
) -> EffectTask<Action> {
loggerGlobal.notice("Converting hardware accounts to babylon...")
Expand All @@ -195,7 +198,7 @@ public struct ImportOlympiaLedgerAccountsAndFactorSources: Sendable, FeatureRedu
// Migrates and saved all accounts to Profile
let migrated = try await importLegacyWalletClient.migrateOlympiaHardwareAccountsToBabylon(
.init(
olympiaAccounts: Set(olympiaAccounts),
olympiaAccounts: olympiaAccounts,
ledgerFactorSourceID: ledger.id
)
)
Expand Down Expand Up @@ -274,6 +277,8 @@ public struct ImportOlympiaLedgerAccountsAndFactorSources: Sendable, FeatureRedu
unvalidated: olympiaAccountsToValidate
)
}

struct NoValidatedAccountsError: Error {}
}

extension LedgerHardwareWalletFactorSource.DeviceModel {
Expand Down