Skip to content

Commit

Permalink
Merge pull request #397 from Adamant-im/trello.com/c/H3H8SXeM
Browse files Browse the repository at this point in the history
[trello.com/c/H3H8SXeM] Eth crash fix
  • Loading branch information
StanislavDevIOS authored Nov 30, 2023
2 parents 6541c95 + 0c26b20 commit 9fac0e1
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 76 deletions.
4 changes: 4 additions & 0 deletions Adamant.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@
93C7944E2B077C1F00408826 /* DashSendRawTransactionDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93C7944D2B077C1F00408826 /* DashSendRawTransactionDTO.swift */; };
93CC8DC7296F00D6003772BF /* ChatTransactionContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CC8DC6296F00D6003772BF /* ChatTransactionContainerView.swift */; };
93CC8DC9296F01DE003772BF /* ChatTransactionContainerView+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CC8DC8296F01DE003772BF /* ChatTransactionContainerView+Model.swift */; };
93CC94C12B17EE73004842AC /* EthApiCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CC94C02B17EE73004842AC /* EthApiCore.swift */; };
93CCAE752B06CC3600EA5B94 /* LskNodeApiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CCAE742B06CC3600EA5B94 /* LskNodeApiService.swift */; };
93CCAE772B06D6CC00EA5B94 /* LskServiceApiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CCAE762B06D6CC00EA5B94 /* LskServiceApiService.swift */; };
93CCAE792B06D81D00EA5B94 /* DogeApiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CCAE782B06D81D00EA5B94 /* DogeApiService.swift */; };
Expand Down Expand Up @@ -920,6 +921,7 @@
93C7944D2B077C1F00408826 /* DashSendRawTransactionDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashSendRawTransactionDTO.swift; sourceTree = "<group>"; };
93CC8DC6296F00D6003772BF /* ChatTransactionContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTransactionContainerView.swift; sourceTree = "<group>"; };
93CC8DC8296F01DE003772BF /* ChatTransactionContainerView+Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChatTransactionContainerView+Model.swift"; sourceTree = "<group>"; };
93CC94C02B17EE73004842AC /* EthApiCore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthApiCore.swift; sourceTree = "<group>"; };
93CCAE742B06CC3600EA5B94 /* LskNodeApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LskNodeApiService.swift; sourceTree = "<group>"; };
93CCAE762B06D6CC00EA5B94 /* LskServiceApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LskServiceApiService.swift; sourceTree = "<group>"; };
93CCAE782B06D81D00EA5B94 /* DogeApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DogeApiService.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2175,6 +2177,7 @@
E993302121354BC300CD5200 /* EthWalletFactory.swift */,
E940087A2114ED0600CD2D67 /* EthWalletService.swift */,
93FC169C2B019F440062B507 /* EthApiService.swift */,
93CC94C02B17EE73004842AC /* EthApiCore.swift */,
4186B333294200C5006594A3 /* EthWalletService+DynamicConstants.swift */,
E9AA8BF9212C166600F9249F /* EthWalletService+Send.swift */,
E9FEECA52143C300007DD7C8 /* EthWalletService+RichMessageProvider.swift */,
Expand Down Expand Up @@ -3025,6 +3028,7 @@
E9E7CD8B20026B0600DFC4DB /* AccountService.swift in Sources */,
41E3C9CC2A0E20F500AF0985 /* AdamantCoinTools.swift in Sources */,
93ADE0712ACA66AF008ED641 /* VibrationSelectionViewModel.swift in Sources */,
93CC94C12B17EE73004842AC /* EthApiCore.swift in Sources */,
93FC169D2B019F440062B507 /* EthApiService.swift in Sources */,
9371130F2996EDA900F64CF9 /* ChatRefreshMock.swift in Sources */,
93547BCA29E2262D00B0914B /* WelcomeViewController.swift in Sources */,
Expand Down
99 changes: 99 additions & 0 deletions Adamant/Modules/Wallets/Ethereum/EthApiCore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//
// EthApiCore.swift
// Adamant
//
// Created by Andrew G on 30.11.2023.
// Copyright © 2023 Adamant. All rights reserved.
//

import CommonKit
import Foundation
import web3swift
import Web3Core

actor EthApiCore {
let apiCore: APICoreProtocol
private(set) var keystoreManager: KeystoreManager?
private var web3Cache: [URL: Web3] = .init()

func performRequest<Success>(
node: Node,
_ body: @escaping @Sendable (_ web3: Web3) async throws -> Success
) async -> WalletServiceResult<Success> {
switch await getWeb3(node: node) {
case let .success(web3):
do {
return .success(try await body(web3))
} catch {
return .failure(mapError(error))
}
case let .failure(error):
return .failure(error)
}
}

func setKeystoreManager(_ keystoreManager: KeystoreManager) {
self.keystoreManager = keystoreManager
web3Cache = .init()
}

init(apiCore: APICoreProtocol) {
self.apiCore = apiCore
}
}

extension EthApiCore: BlockchainHealthCheckableService {
func getStatusInfo(node: Node) async -> WalletServiceResult<NodeStatusInfo> {
await performRequest(node: node) { web3 in
let startTimestamp = Date.now.timeIntervalSince1970
let height = try await web3.eth.blockNumber()
let ping = Date.now.timeIntervalSince1970 - startTimestamp

return .init(
ping: ping,
height: Int(height.asDouble()),
wsEnabled: false,
wsPort: nil,
version: nil
)
}
}
}

private extension EthApiCore {
func getWeb3(node: Node) async -> WalletServiceResult<Web3> {
guard let url = node.asURL() else {
return .failure(.internalError(.endpointBuildFailed))
}

if let web3 = web3Cache[url] {
return .success(web3)
}

do {
let web3 = try await Web3.new(url)
web3.addKeystoreManager(keystoreManager)
web3Cache[url] = web3
return .success(web3)
} catch {
return .failure(.internalError(
message: error.localizedDescription,
error: error
))
}
}
}

private func mapError(_ error: Error) -> WalletServiceError {
if let error = error as? Web3Error {
return error.asWalletServiceError()
} else if let error = error as? ApiServiceError {
return error.asWalletServiceError()
} else if let error = error as? WalletServiceError {
return error
} else if let _ = error as? URLError {
return .networkError
} else {
return .remoteServiceError(message: error.localizedDescription)
}
}
71 changes: 0 additions & 71 deletions Adamant/Modules/Wallets/Ethereum/EthApiService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,63 +11,6 @@ import Foundation
import web3swift
import Web3Core

@MainActor
final class EthApiCore: BlockchainHealthCheckableService {
let apiCore: APICoreProtocol
private(set) var keystoreManager: KeystoreManager?

func makeWeb3(node: Node) async -> WalletServiceResult<Web3> {
do {
guard let url = node.asURL() else { throw InternalAPIError.endpointBuildFailed }
let web3 = try await Web3.new(url)
web3.addKeystoreManager(keystoreManager)
return .success(web3)
} catch {
return .failure(.internalError(message: error.localizedDescription, error: error))
}
}

func performRequest<Success>(
node: Node,
_ body: @escaping @Sendable (_ web3: Web3) async throws -> Success
) async -> WalletServiceResult<Success> {
switch await makeWeb3(node: node) {
case let .success(web3):
do {
return .success(try await body(web3))
} catch {
return .failure(mapError(error))
}
case let .failure(error):
return .failure(error)
}
}

func getStatusInfo(node: Node) async -> WalletServiceResult<NodeStatusInfo> {
await performRequest(node: node) { web3 in
let startTimestamp = Date.now.timeIntervalSince1970
let height = try await web3.eth.blockNumber()
let ping = Date.now.timeIntervalSince1970 - startTimestamp

return .init(
ping: ping,
height: Int(height.asDouble()),
wsEnabled: false,
wsPort: nil,
version: nil
)
}
}

func setKeystoreManager(_ keystoreManager: KeystoreManager) {
self.keystoreManager = keystoreManager
}

nonisolated init(apiCore: APICoreProtocol) {
self.apiCore = apiCore
}
}

class EthApiService: WalletApiService {
let api: BlockchainHealthCheckWrapper<EthApiCore>

Expand Down Expand Up @@ -113,17 +56,3 @@ class EthApiService: WalletApiService {
await api.service.setKeystoreManager(keystoreManager)
}
}

private func mapError(_ error: Error) -> WalletServiceError {
if let error = error as? Web3Error {
return error.asWalletServiceError()
} else if let error = error as? ApiServiceError {
return error.asWalletServiceError()
} else if let error = error as? WalletServiceError {
return error
} else if let _ = error as? URLError {
return .networkError
} else {
return .remoteServiceError(message: error.localizedDescription)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private extension EthWalletService {
func getTransactionInfo(hash: String, web3: Web3) async throws -> EthTransactionInfo {
try await withThrowingTaskGroup(
of: EthTransactionInfoElement.self,
returning: EthTransactionInfo.self
returning: Atomic<EthTransactionInfo>.self
) { group in
group.addTask(priority: .userInitiated) {
.details(try await web3.eth.transactionDetails(hash))
Expand All @@ -81,15 +81,17 @@ private extension EthWalletService {
.receipt(try await web3.eth.transactionReceipt(hash))
}

return try await group.reduce(into: .init()) { result, value in
return try await group.reduce(
into: .init(wrappedValue: .init())
) { result, value in
switch value {
case let .receipt(receipt):
result.receipt = receipt
result.wrappedValue.receipt = receipt
case let .details(details):
result.details = details
result.wrappedValue.details = details
}
}
}
}.wrappedValue
}

func getStatus(
Expand Down

0 comments on commit 9fac0e1

Please sign in to comment.