diff --git a/novawallet.xcodeproj/project.pbxproj b/novawallet.xcodeproj/project.pbxproj index beacf6ac5b..28211a4c0c 100644 --- a/novawallet.xcodeproj/project.pbxproj +++ b/novawallet.xcodeproj/project.pbxproj @@ -931,6 +931,7 @@ 77A0B2F92A3CA40E00CBF653 /* StakingMoreOptionsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77A0B2F82A3CA40E00CBF653 /* StakingMoreOptionsSection.swift */; }; 77A4F4012B035027006294BC /* AssetOperationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77A4F4002B035027006294BC /* AssetOperationState.swift */; }; 77A4F4032B036615006294BC /* Optional+Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77A4F4022B036615006294BC /* Optional+Result.swift */; }; + 77A502F12B63E3830062FA51 /* ProxyAccountSubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77A502F02B63E3830062FA51 /* ProxyAccountSubscription.swift */; }; 77A6F5AB2A2E0B31004AFD1A /* ReceiveAssetOperationPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77A6F5AA2A2E0B31004AFD1A /* ReceiveAssetOperationPresenter.swift */; }; 77A6F5AE2A2E0C7C004AFD1A /* ReceiveAssetOperationWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77A6F5AD2A2E0C7C004AFD1A /* ReceiveAssetOperationWireframe.swift */; }; 77A6F5B92A2E2AAD004AFD1A /* BuyAssetOperationPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77A6F5B72A2E2AAD004AFD1A /* BuyAssetOperationPresenter.swift */; }; @@ -1047,6 +1048,7 @@ 77F9FB0D2A9D9C5600820625 /* NominationPoolBondMoreBaseProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77F9FB0C2A9D9C5600820625 /* NominationPoolBondMoreBaseProtocols.swift */; }; 77FDFC462B0DEB34005A3569 /* OpenDAppUrlParsingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FDFC452B0DEB34005A3569 /* OpenDAppUrlParsingService.swift */; }; 77FDFC482B0E1CBD005A3569 /* ImportWalletUrlParsingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FDFC472B0E1CBD005A3569 /* ImportWalletUrlParsingService.swift */; }; + 77FE76402B67682A00ADA73F /* ProxyAccountUpdatingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FE763F2B67682A00ADA73F /* ProxyAccountUpdatingService.swift */; }; 77FF02692B21ECB900B655BC /* ProxyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FF02682B21ECB900B655BC /* ProxyTableViewCell.swift */; }; 77FFB2B12B0D392A00C7C879 /* OpenStakingUrlParsingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FFB2B02B0D392A00C7C879 /* OpenStakingUrlParsingService.swift */; }; 77FFB2B32B0D394700C7C879 /* OpenGovernanceUrlParsingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FFB2B22B0D394700C7C879 /* OpenGovernanceUrlParsingService.swift */; }; @@ -5192,6 +5194,7 @@ 77A0B2F82A3CA40E00CBF653 /* StakingMoreOptionsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StakingMoreOptionsSection.swift; sourceTree = ""; }; 77A4F4002B035027006294BC /* AssetOperationState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetOperationState.swift; sourceTree = ""; }; 77A4F4022B036615006294BC /* Optional+Result.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Optional+Result.swift"; sourceTree = ""; }; + 77A502F02B63E3830062FA51 /* ProxyAccountSubscription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxyAccountSubscription.swift; sourceTree = ""; }; 77A6F5AA2A2E0B31004AFD1A /* ReceiveAssetOperationPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReceiveAssetOperationPresenter.swift; sourceTree = ""; }; 77A6F5AD2A2E0C7C004AFD1A /* ReceiveAssetOperationWireframe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceiveAssetOperationWireframe.swift; sourceTree = ""; }; 77A6F5B72A2E2AAD004AFD1A /* BuyAssetOperationPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BuyAssetOperationPresenter.swift; sourceTree = ""; }; @@ -5314,6 +5317,7 @@ 77F9FB0C2A9D9C5600820625 /* NominationPoolBondMoreBaseProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NominationPoolBondMoreBaseProtocols.swift; sourceTree = ""; }; 77FDFC452B0DEB34005A3569 /* OpenDAppUrlParsingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenDAppUrlParsingService.swift; sourceTree = ""; }; 77FDFC472B0E1CBD005A3569 /* ImportWalletUrlParsingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletUrlParsingService.swift; sourceTree = ""; }; + 77FE763F2B67682A00ADA73F /* ProxyAccountUpdatingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxyAccountUpdatingService.swift; sourceTree = ""; }; 77FF02682B21ECB900B655BC /* ProxyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxyTableViewCell.swift; sourceTree = ""; }; 77FFB2B02B0D392A00C7C879 /* OpenStakingUrlParsingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenStakingUrlParsingService.swift; sourceTree = ""; }; 77FFB2B22B0D394700C7C879 /* OpenGovernanceUrlParsingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGovernanceUrlParsingService.swift; sourceTree = ""; }; @@ -16177,6 +16181,8 @@ 0CC2E5612A6E5C43004092E7 /* NominationPoolsAccountUpdatingService.swift */, 0CE1504F2A6FAC1200B61CC1 /* NominationPoolsPoolSubscriptionService.swift */, 0CAC02FC2B4BFB9400DDEC3A /* WalletRemoteQueryWrapperFactory.swift */, + 77FE763F2B67682A00ADA73F /* ProxyAccountUpdatingService.swift */, + 77A502F02B63E3830062FA51 /* ProxyAccountSubscription.swift */, ); path = Substrate; sourceTree = ""; @@ -23630,6 +23636,7 @@ 848F8B2B2864824200204BC4 /* AssetListChainControlView.swift in Sources */, 4F03B1138E7160AEA00B7793 /* ParaStkCollatorInfoViewFactory.swift in Sources */, 0119531FAE0D22EA9464F84D /* ParaStkYourCollatorsProtocols.swift in Sources */, + 77FE76402B67682A00ADA73F /* ProxyAccountUpdatingService.swift in Sources */, 542588DA751A44C993BC1F27 /* ParaStkYourCollatorsWireframe.swift in Sources */, D6D9D16440AB588F581AF5BA /* ParaStkYourCollatorsPresenter.swift in Sources */, FA62AACACA15CB04275DE957 /* ParaStkYourCollatorsInteractor.swift in Sources */, @@ -24209,6 +24216,7 @@ 77F9FB0B2A9D97A100820625 /* NominationPoolBondMoreSetupWireframe.swift in Sources */, F0C3DCA3CD4F850C16406716 /* GovernanceDelegateSearchViewFactory.swift in Sources */, 0C13DFD52AFA4F1500E5F355 /* SwapIssueCheckParams.swift in Sources */, + 77A502F12B63E3830062FA51 /* ProxyAccountSubscription.swift in Sources */, C98A02D4DEAC6E4CACB9E47E /* StakingRebagConfirmProtocols.swift in Sources */, B09F155D14D146377FB2952A /* StakingRebagConfirmWireframe.swift in Sources */, 840AE2E329C9A715008FF665 /* OptionStringCodable+Empty.swift in Sources */, diff --git a/novawallet/Common/Services/Proxy/ChainProxySyncService.swift b/novawallet/Common/Services/Proxy/ChainProxySyncService.swift index 112c639b89..cd5e074b43 100644 --- a/novawallet/Common/Services/Proxy/ChainProxySyncService.swift +++ b/novawallet/Common/Services/Proxy/ChainProxySyncService.swift @@ -2,7 +2,11 @@ import SubstrateSdk import RobinHood import BigInt -final class ChainProxySyncService: ObservableSyncService, AnyCancellableCleaning { +protocol ChainProxySyncServiceProtocol: ObservableSyncServiceProtocol { + func sync(at blockHash: Data?) +} + +final class ChainProxySyncService: ObservableSyncService, ChainProxySyncServiceProtocol, AnyCancellableCleaning { let walletUpdateMediator: WalletUpdateMediating let metaAccountsRepository: AnyDataProviderRepository let chainRegistry: ChainRegistryProtocol @@ -47,8 +51,33 @@ final class ChainProxySyncService: ObservableSyncService, AnyCancellableCleaning } override func performSyncUp() { - let chainId = chainModel.chainId + performSync(at: nil) + } + + func sync(at blockHash: Data?) { + mutex.lock() + + defer { + mutex.unlock() + } + + guard isActive else { + return + } + + if isSyncing { + stopSyncUp() + + isSyncing = false + } + + isSyncing = true + + performSync(at: blockHash) + } + func performSync(at blockHash: Data?) { + let chainId = chainModel.chainId guard let connection = chainRegistry.getConnection(for: chainId) else { completeImmediate(ChainRegistryError.connectionUnavailable) return @@ -59,22 +88,13 @@ final class ChainProxySyncService: ObservableSyncService, AnyCancellableCleaning return } - performSyncUp( - connection: connection, - runtimeProvider: runtimeProvider - ) - } - - private func performSyncUp( - connection: JSONRPCEngine, - runtimeProvider: RuntimeCodingServiceProtocol - ) { pendingCall.cancel() let proxyListWrapper = proxyOperationFactory.fetchProxyList( requestFactory: requestFactory, connection: connection, - runtimeProvider: runtimeProvider + runtimeProvider: runtimeProvider, + at: blockHash ) let walletsWrapper = createWalletsWrapper(for: chainWalletFilter, chain: chainModel) diff --git a/novawallet/Common/Services/Proxy/ProxyOperationFactory.swift b/novawallet/Common/Services/Proxy/ProxyOperationFactory.swift index aa2b5b2b8b..1db638e852 100644 --- a/novawallet/Common/Services/Proxy/ProxyOperationFactory.swift +++ b/novawallet/Common/Services/Proxy/ProxyOperationFactory.swift @@ -7,7 +7,8 @@ protocol ProxyOperationFactoryProtocol { func fetchProxyList( requestFactory: StorageRequestFactoryProtocol, connection: JSONRPCEngine, - runtimeProvider: RuntimeCodingServiceProtocol + runtimeProvider: RuntimeCodingServiceProtocol, + at blockHash: Data? ) -> CompoundOperationWrapper<[ProxiedAccountId: [ProxyAccount]]> } @@ -15,12 +16,16 @@ final class ProxyOperationFactory: ProxyOperationFactoryProtocol { func fetchProxyList( requestFactory: StorageRequestFactoryProtocol, connection: JSONRPCEngine, - runtimeProvider: RuntimeCodingServiceProtocol + runtimeProvider: RuntimeCodingServiceProtocol, + at blockHash: Data? ) -> CompoundOperationWrapper<[ProxiedAccountId: [ProxyAccount]]> { let request = UnkeyedRemoteStorageRequest(storagePath: Proxy.proxyList) let codingFactoryOperation = runtimeProvider.fetchCoderFactoryOperation() - let options = StorageQueryListOptions(ignoresFailedItems: true) + let options = StorageQueryListOptions( + atBlock: blockHash, + ignoresFailedItems: true + ) let fetchWrapper: CompoundOperationWrapper<[AccountIdKey: ProxyDefinition]> = requestFactory.queryByPrefix( engine: connection, diff --git a/novawallet/Common/Services/Proxy/ProxySyncService.swift b/novawallet/Common/Services/Proxy/ProxySyncService.swift index 145e31d1b5..cca3a0f908 100644 --- a/novawallet/Common/Services/Proxy/ProxySyncService.swift +++ b/novawallet/Common/Services/Proxy/ProxySyncService.swift @@ -13,6 +13,10 @@ protocol ProxySyncServiceProtocol: ApplicationServiceProtocol { func unsubscribeSyncState(_ target: AnyObject) func updateWalletsStatuses() func syncUp() + func syncUp( + chainId: ChainModel.Id, + blockHash: Data? + ) } typealias ProxySyncChainFilter = (ChainModel) -> Bool @@ -32,7 +36,7 @@ final class ProxySyncService { private(set) var isActive: Bool = false - private(set) var updaters: [ChainModel.Id: ObservableSyncServiceProtocol & ApplicationServiceProtocol] = [:] + private(set) var updaters: [ChainModel.Id: ChainProxySyncServiceProtocol & ApplicationServiceProtocol] = [:] private let mutex = NSLock() private var stateObserver = Observable(state: [:]) @@ -272,4 +276,11 @@ extension ProxySyncService: ProxySyncServiceProtocol { func syncUp() { updaters.values.forEach { $0.syncUp() } } + + func syncUp( + chainId: ChainModel.Id, + blockHash: Data? + ) { + updaters[chainId]?.sync(at: blockHash) + } } diff --git a/novawallet/Common/Services/RemoteSubscription/Substrate/ProxyAccountSubscription.swift b/novawallet/Common/Services/RemoteSubscription/Substrate/ProxyAccountSubscription.swift new file mode 100644 index 0000000000..7009b7789b --- /dev/null +++ b/novawallet/Common/Services/RemoteSubscription/Substrate/ProxyAccountSubscription.swift @@ -0,0 +1,113 @@ +import Foundation +import RobinHood +import IrohaCrypto +import SubstrateSdk + +final class ProxyAccountSubscription: WebSocketSubscribing { + let accountId: AccountId + let chainId: ChainModel.Id + let chainRegistry: ChainRegistryProtocol + let proxySyncService: ProxySyncServiceProtocol + let storageFacade: StorageFacadeProtocol + let logger: LoggerProtocol? + + private let mutex = NSLock() + private let operationQueue: OperationQueue + private let workingQueue: DispatchQueue + private var subscription: CallbackBatchStorageSubscription? + private var storageSubscriptionHandler: StorageChildSubscribing? + + private lazy var repository: AnyDataProviderRepository = { + let coreDataRepository: CoreDataRepository = + storageFacade.createRepository() + return AnyDataProviderRepository(coreDataRepository) + }() + + init( + accountId: AccountId, + chainId: ChainModel.Id, + chainRegistry: ChainRegistryProtocol, + proxySyncService: ProxySyncServiceProtocol, + storageFacade: StorageFacadeProtocol, + operationQueue: OperationQueue, + workingQueue: DispatchQueue, + logger: LoggerProtocol? = nil + ) { + self.accountId = accountId + self.chainId = chainId + self.chainRegistry = chainRegistry + self.proxySyncService = proxySyncService + self.operationQueue = operationQueue + self.workingQueue = workingQueue + self.logger = logger + self.storageFacade = storageFacade + + do { + try subscribeRemote(for: accountId) + } catch { + logger?.error(error.localizedDescription) + } + } + + deinit { + unsubscribeRemote() + } + + private func unsubscribeRemote() { + subscription?.unsubscribe() + subscription = nil + } + + private func subscribeRemote(for accountId: AccountId) throws { + guard let connection = chainRegistry.getConnection(for: chainId) else { + throw ChainRegistryError.connectionUnavailable + } + guard let runtimeService = chainRegistry.getRuntimeProvider(for: chainId) else { + throw ChainRegistryError.runtimeMetadaUnavailable + } + + let localKey = try LocalStorageKeyFactory().createFromStoragePath( + Proxy.proxyList, + accountId: accountId, + chainId: chainId + ) + + let request = BatchStorageSubscriptionRequest( + innerRequest: MapSubscriptionRequest( + storagePath: Proxy.proxyList, + localKey: localKey + ) { + BytesCodable(wrappedValue: accountId) + }, + mappingKey: nil + ) + + subscription = CallbackBatchStorageSubscription( + requests: [request], + connection: connection, + runtimeService: runtimeService, + repository: repository, + operationQueue: operationQueue, + callbackQueue: workingQueue + ) { [weak self] result in + self?.mutex.lock() + + self?.handleSubscription(result) + + self?.mutex.unlock() + } + + subscription?.subscribe() + } + + private func handleSubscription(_ result: Result) { + switch result { + case let .success(handler): + if let blockHash = handler.blockHash { + proxySyncService.syncUp(chainId: chainId, blockHash: blockHash) + } + case let .failure(error): + logger?.error(error.localizedDescription) + } + } +} diff --git a/novawallet/Common/Services/RemoteSubscription/Substrate/ProxyAccountUpdatingService.swift b/novawallet/Common/Services/RemoteSubscription/Substrate/ProxyAccountUpdatingService.swift new file mode 100644 index 0000000000..a9c2becb10 --- /dev/null +++ b/novawallet/Common/Services/RemoteSubscription/Substrate/ProxyAccountUpdatingService.swift @@ -0,0 +1,53 @@ +import Foundation + +protocol ProxyAccountUpdatingServiceProtocol { + func setupSubscription( + for accountId: AccountId, + chainId: ChainModel.Id + ) throws + + func clearSubscription() +} + +class ProxyAccountUpdatingService: ProxyAccountUpdatingServiceProtocol { + private var proxySubscription: ProxyAccountSubscription? + + let chainRegistry: ChainRegistryProtocol + let proxySyncService: ProxySyncServiceProtocol + let operationQueue: OperationQueue + let logger: LoggerProtocol? + let storageFacade: StorageFacadeProtocol + + init( + chainRegistry: ChainRegistryProtocol, + proxySyncService: ProxySyncServiceProtocol, + storageFacade: StorageFacadeProtocol, + operationQueue: OperationQueue, + logger: LoggerProtocol? = nil + ) { + self.chainRegistry = chainRegistry + self.proxySyncService = proxySyncService + self.storageFacade = storageFacade + self.operationQueue = operationQueue + self.logger = logger + } + + func setupSubscription( + for accountId: AccountId, + chainId: ChainModel.Id + ) throws { + proxySubscription = ProxyAccountSubscription( + accountId: accountId, + chainId: chainId, + chainRegistry: chainRegistry, + proxySyncService: proxySyncService, + storageFacade: storageFacade, + operationQueue: operationQueue, + workingQueue: .init(label: "com.novawallet.proxy.updating", qos: .userInitiated) + ) + } + + func clearSubscription() { + proxySubscription = nil + } +} diff --git a/novawallet/Common/Services/RemoteSubscription/Substrate/StakingAccountSubscription.swift b/novawallet/Common/Services/RemoteSubscription/Substrate/StakingAccountSubscription.swift index c675de1d75..4999397f08 100644 --- a/novawallet/Common/Services/RemoteSubscription/Substrate/StakingAccountSubscription.swift +++ b/novawallet/Common/Services/RemoteSubscription/Substrate/StakingAccountSubscription.swift @@ -39,7 +39,6 @@ final class StakingAccountSubscription: WebSocketSubscribing { let childSubscriptionFactory: ChildSubscriptionFactoryProtocol let operationQueue: OperationQueue let logger: LoggerProtocol? - let chainHasProxy: Bool private let mutex = NSLock() private var subscription: Subscription? @@ -48,7 +47,6 @@ final class StakingAccountSubscription: WebSocketSubscribing { accountId: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, - chainHasProxy: Bool, chainRegistry: ChainRegistryProtocol, provider: StreamableProvider, childSubscriptionFactory: ChildSubscriptionFactoryProtocol, @@ -58,7 +56,6 @@ final class StakingAccountSubscription: WebSocketSubscribing { self.accountId = accountId self.chainId = chainId self.chainFormat = chainFormat - self.chainHasProxy = chainHasProxy self.chainRegistry = chainRegistry self.provider = provider self.childSubscriptionFactory = childSubscriptionFactory @@ -132,10 +129,6 @@ final class StakingAccountSubscription: WebSocketSubscribing { ) } - if chainHasProxy { - requests.append(.init(storagePath: Proxy.proxyList, accountId: stashId)) - } - return requests } diff --git a/novawallet/Common/Services/RemoteSubscription/Substrate/StakingAccountUpdatingService.swift b/novawallet/Common/Services/RemoteSubscription/Substrate/StakingAccountUpdatingService.swift index 34aa486c32..b706d6dfaf 100644 --- a/novawallet/Common/Services/RemoteSubscription/Substrate/StakingAccountUpdatingService.swift +++ b/novawallet/Common/Services/RemoteSubscription/Substrate/StakingAccountUpdatingService.swift @@ -5,8 +5,7 @@ protocol StakingAccountUpdatingServiceProtocol { func setupSubscription( for accountId: AccountId, chainId: ChainModel.Id, - chainFormat: ChainFormat, - chainHasProxy: Bool + chainFormat: ChainFormat ) throws func clearSubscription() @@ -41,8 +40,7 @@ class StakingAccountUpdatingService: StakingAccountUpdatingServiceProtocol { func setupSubscription( for accountId: AccountId, chainId: ChainModel.Id, - chainFormat: ChainFormat, - chainHasProxy: Bool + chainFormat: ChainFormat ) throws { let address = try accountId.toAddress(using: chainFormat) let stashItemProvider = substrateDataProviderFactory.createStashItemProvider(for: address, chainId: chainId) @@ -51,7 +49,6 @@ class StakingAccountUpdatingService: StakingAccountUpdatingServiceProtocol { accountId: accountId, chainId: chainId, chainFormat: chainFormat, - chainHasProxy: chainHasProxy, chainRegistry: chainRegistry, provider: stashItemProvider, childSubscriptionFactory: childSubscriptionFactory, diff --git a/novawallet/Modules/Staking/Dashboard/StakingDashboardWireframe.swift b/novawallet/Modules/Staking/Dashboard/StakingDashboardWireframe.swift index 47a4caae11..a04617d926 100644 --- a/novawallet/Modules/Staking/Dashboard/StakingDashboardWireframe.swift +++ b/novawallet/Modules/Staking/Dashboard/StakingDashboardWireframe.swift @@ -29,7 +29,10 @@ final class StakingDashboardWireframe: StakingDashboardWireframeProtocol { from view: StakingDashboardViewProtocol?, option: Multistaking.ChainAssetOption ) { - guard let detailsView = StakingMainViewFactory.createView(for: option) else { + guard let detailsView = StakingMainViewFactory.createView( + for: option, + proxySyncService: proxySyncService + ) else { return } diff --git a/novawallet/Modules/Staking/Model/StakingSharedState/RelaychainStakingSharedState.swift b/novawallet/Modules/Staking/Model/StakingSharedState/RelaychainStakingSharedState.swift index 93c842ce3b..485f0b9c1c 100644 --- a/novawallet/Modules/Staking/Model/StakingSharedState/RelaychainStakingSharedState.swift +++ b/novawallet/Modules/Staking/Model/StakingSharedState/RelaychainStakingSharedState.swift @@ -34,6 +34,7 @@ final class RelaychainStakingSharedState: RelaychainStakingSharedStateProtocol { let eraValidatorService: EraValidatorServiceProtocol let rewardCalculatorService: RewardCalculatorServiceProtocol let logger: LoggerProtocol + let proxyRemoteSubscriptionService: ProxyAccountUpdatingServiceProtocol? private var globalSubscriptionId: UUID? @@ -46,6 +47,7 @@ final class RelaychainStakingSharedState: RelaychainStakingSharedStateProtocol { stakingOption: Multistaking.ChainAssetOption, globalRemoteSubscriptionService: StakingRemoteSubscriptionServiceProtocol, accountRemoteSubscriptionService: StakingAccountUpdatingServiceProtocol, + proxyRemoteSubscriptionService: ProxyAccountUpdatingServiceProtocol?, localSubscriptionFactory: StakingLocalSubscriptionFactoryProtocol, proxyLocalSubscriptionFactory: ProxyListLocalSubscriptionFactoryProtocol, eraValidatorService: EraValidatorServiceProtocol, @@ -57,6 +59,7 @@ final class RelaychainStakingSharedState: RelaychainStakingSharedStateProtocol { self.stakingOption = stakingOption self.globalRemoteSubscriptionService = globalRemoteSubscriptionService self.accountRemoteSubscriptionService = accountRemoteSubscriptionService + self.proxyRemoteSubscriptionService = proxyRemoteSubscriptionService self.localSubscriptionFactory = localSubscriptionFactory self.proxyLocalSubscriptionFactory = proxyLocalSubscriptionFactory self.eraValidatorService = eraValidatorService @@ -86,9 +89,14 @@ final class RelaychainStakingSharedState: RelaychainStakingSharedStateProtocol { try accountRemoteSubscriptionService.setupSubscription( for: accountId, chainId: chain.chainId, - chainFormat: chain.chainFormat, - chainHasProxy: chain.hasProxy + chainFormat: chain.chainFormat ) + if chain.hasProxy { + try proxyRemoteSubscriptionService?.setupSubscription( + for: accountId, + chainId: chain.chainId + ) + } logger.debug("Relaychain staking account data subscription succeeded") } else { @@ -117,6 +125,7 @@ final class RelaychainStakingSharedState: RelaychainStakingSharedStateProtocol { timeModel.blockTimeService?.throttle() accountRemoteSubscriptionService.clearSubscription() + proxyRemoteSubscriptionService?.clearSubscription() } func createNetworkInfoOperationFactory( diff --git a/novawallet/Modules/Staking/Model/StakingSharedState/RelaychainStartStakingState.swift b/novawallet/Modules/Staking/Model/StakingSharedState/RelaychainStartStakingState.swift index 0ae944826a..ecc89597f8 100644 --- a/novawallet/Modules/Staking/Model/StakingSharedState/RelaychainStartStakingState.swift +++ b/novawallet/Modules/Staking/Model/StakingSharedState/RelaychainStartStakingState.swift @@ -78,7 +78,7 @@ final class RelaychainStartStakingState: RelaychainStartStakingStateProtocol { relaychainLocalSubscriptionFactory: StakingLocalSubscriptionFactoryProtocol, eraValidatorService: EraValidatorServiceProtocol, relaychainRewardCalculatorService: RewardCalculatorServiceProtocol, - npRemoteSubstriptionService: NominationPoolsRemoteSubscriptionServiceProtocol?, + npRemoteSubscriptionService: NominationPoolsRemoteSubscriptionServiceProtocol?, npAccountSubscriptionServiceFactory: NominationPoolsAccountUpdatingFactoryProtocol?, npLocalSubscriptionFactory: NPoolsLocalSubscriptionFactoryProtocol, activePoolsService: EraNominationPoolsServiceProtocol?, @@ -93,7 +93,7 @@ final class RelaychainStartStakingState: RelaychainStartStakingStateProtocol { self.relaychainLocalSubscriptionFactory = relaychainLocalSubscriptionFactory self.eraValidatorService = eraValidatorService self.relaychainRewardCalculatorService = relaychainRewardCalculatorService - npRemoteSubscriptionService = npRemoteSubstriptionService + self.npRemoteSubscriptionService = npRemoteSubscriptionService self.npAccountSubscriptionServiceFactory = npAccountSubscriptionServiceFactory self.npLocalSubscriptionFactory = npLocalSubscriptionFactory self.activePoolsService = activePoolsService @@ -137,8 +137,7 @@ final class RelaychainStartStakingState: RelaychainStartStakingStateProtocol { try relaychainAccountSubscriptionService.setupSubscription( for: accountId, chainId: chainId, - chainFormat: chainAsset.chain.chainFormat, - chainHasProxy: chainAsset.chain.hasProxy + chainFormat: chainAsset.chain.chainFormat ) npAccountService = try npAccountSubscriptionServiceFactory?.create( diff --git a/novawallet/Modules/Staking/Model/StakingSharedState/StakingSharedStateFactory.swift b/novawallet/Modules/Staking/Model/StakingSharedState/StakingSharedStateFactory.swift index 8d3229cec5..accce90335 100644 --- a/novawallet/Modules/Staking/Model/StakingSharedState/StakingSharedStateFactory.swift +++ b/novawallet/Modules/Staking/Model/StakingSharedState/StakingSharedStateFactory.swift @@ -44,6 +44,7 @@ final class StakingSharedStateFactory { let timeModel: StakingTimeModel let localSubscriptionFactory: StakingLocalSubscriptionFactoryProtocol let proxySubscriptionFactory: ProxyListLocalSubscriptionFactoryProtocol + let proxyRemoteSubscriptionService: ProxyAccountUpdatingServiceProtocol? } struct NominationPoolsServices { @@ -56,6 +57,7 @@ final class StakingSharedStateFactory { let storageFacade: StorageFacadeProtocol let chainRegistry: ChainRegistryProtocol let eventCenter: EventCenterProtocol + let proxySyncService: ProxySyncServiceProtocol? let syncOperationQueue: OperationQueue let repositoryOperationQueue: OperationQueue let logger: LoggerProtocol @@ -63,12 +65,14 @@ final class StakingSharedStateFactory { init( storageFacade: StorageFacadeProtocol, chainRegistry: ChainRegistryProtocol, + proxySyncService: ProxySyncServiceProtocol?, eventCenter: EventCenterProtocol, syncOperationQueue: OperationQueue, repositoryOperationQueue: OperationQueue, logger: LoggerProtocol ) { self.storageFacade = storageFacade + self.proxySyncService = proxySyncService self.chainRegistry = chainRegistry self.eventCenter = eventCenter self.syncOperationQueue = syncOperationQueue @@ -165,6 +169,16 @@ final class StakingSharedStateFactory { operationQueue: syncOperationQueue ) + let proxyRemoteSubscriptionService = proxySyncService.map { + ProxyAccountUpdatingService( + chainRegistry: chainRegistry, + proxySyncService: $0, + storageFacade: storageFacade, + operationQueue: syncOperationQueue, + logger: logger + ) + } + return .init( globalRemoteSubscriptionService: globalServices.globalRemoteSubscriptionService, accountRemoteSubscriptionService: accountRemoteSubscriptionService, @@ -172,7 +186,8 @@ final class StakingSharedStateFactory { rewardCalculatorService: globalServices.rewardCalculatorService, timeModel: globalServices.timeModel, localSubscriptionFactory: globalServices.localSubscriptionFactory, - proxySubscriptionFactory: ProxyListLocalSubscriptionFactory.shared + proxySubscriptionFactory: ProxyListLocalSubscriptionFactory.shared, + proxyRemoteSubscriptionService: proxyRemoteSubscriptionService ) } @@ -265,6 +280,7 @@ extension StakingSharedStateFactory: StakingSharedStateFactoryProtocol { stakingOption: stakingOption, globalRemoteSubscriptionService: services.globalRemoteSubscriptionService, accountRemoteSubscriptionService: services.accountRemoteSubscriptionService, + proxyRemoteSubscriptionService: services.proxyRemoteSubscriptionService, localSubscriptionFactory: services.localSubscriptionFactory, proxyLocalSubscriptionFactory: services.proxySubscriptionFactory, eraValidatorService: services.eraValidatorService, @@ -399,7 +415,7 @@ extension StakingSharedStateFactory: StakingSharedStateFactoryProtocol { relaychainLocalSubscriptionFactory: relaychainServices.localSubscriptionFactory, eraValidatorService: relaychainServices.eraValidatorService, relaychainRewardCalculatorService: relaychainServices.rewardCalculatorService, - npRemoteSubstriptionService: nominationPoolsService.remoteSubscriptionService, + npRemoteSubscriptionService: nominationPoolsService.remoteSubscriptionService, npAccountSubscriptionServiceFactory: nominationPoolsService.accountSubscriptionServiceFactory, npLocalSubscriptionFactory: nominationPoolsService.localSubscriptionFactory, activePoolsService: nominationPoolsService.activePoolsService, diff --git a/novawallet/Modules/Staking/StakingMain/StakingMainViewFactory.swift b/novawallet/Modules/Staking/StakingMain/StakingMainViewFactory.swift index ae7f455865..4b81d54166 100644 --- a/novawallet/Modules/Staking/StakingMain/StakingMainViewFactory.swift +++ b/novawallet/Modules/Staking/StakingMain/StakingMainViewFactory.swift @@ -5,7 +5,10 @@ import SoraKeystore import RobinHood enum StakingMainViewFactory { - static func createView(for stakingOption: Multistaking.ChainAssetOption) -> StakingMainViewProtocol? { + static func createView( + for stakingOption: Multistaking.ChainAssetOption, + proxySyncService: ProxySyncServiceProtocol + ) -> StakingMainViewProtocol? { let settings = SettingsManager.shared let interactor = createInteractor(with: settings, stakingOption: stakingOption) @@ -17,6 +20,7 @@ enum StakingMainViewFactory { let sharedStateFactory = StakingSharedStateFactory( storageFacade: SubstrateDataStorageFacade.shared, chainRegistry: ChainRegistryFacade.sharedRegistry, + proxySyncService: proxySyncService, eventCenter: EventCenter.shared, syncOperationQueue: OperationManagerFacade.sharedDefaultQueue, repositoryOperationQueue: OperationManagerFacade.sharedDefaultQueue, diff --git a/novawallet/Modules/Staking/StartStakingInfo/StartStakingInfoViewFactory.swift b/novawallet/Modules/Staking/StartStakingInfo/StartStakingInfoViewFactory.swift index a5ce8b46d9..d0169de159 100644 --- a/novawallet/Modules/Staking/StartStakingInfo/StartStakingInfoViewFactory.swift +++ b/novawallet/Modules/Staking/StartStakingInfo/StartStakingInfoViewFactory.swift @@ -54,6 +54,7 @@ struct StartStakingInfoViewFactory { let stateFactory = StakingSharedStateFactory( storageFacade: SubstrateDataStorageFacade.shared, chainRegistry: ChainRegistryFacade.sharedRegistry, + proxySyncService: nil, eventCenter: EventCenter.shared, syncOperationQueue: operationQueue, repositoryOperationQueue: operationQueue, @@ -153,6 +154,7 @@ struct StartStakingInfoViewFactory { let stateFactory = StakingSharedStateFactory( storageFacade: SubstrateDataStorageFacade.shared, chainRegistry: ChainRegistryFacade.sharedRegistry, + proxySyncService: nil, eventCenter: EventCenter.shared, syncOperationQueue: operationQueue, repositoryOperationQueue: operationQueue, diff --git a/novawalletIntegrationTests/Proxy/ProxyOperationFactoryTests.swift b/novawalletIntegrationTests/Proxy/ProxyOperationFactoryTests.swift index 22e6c7858e..4544c696ad 100644 --- a/novawalletIntegrationTests/Proxy/ProxyOperationFactoryTests.swift +++ b/novawalletIntegrationTests/Proxy/ProxyOperationFactoryTests.swift @@ -25,7 +25,8 @@ final class ProxyOperationFactoryTests: XCTestCase { ) let wrapper = operationFactory.fetchProxyList(requestFactory: storageRequestFactory, connection: connection, - runtimeProvider: runtimeService) + runtimeProvider: runtimeService, + at: nil) queue.addOperations( wrapper.allOperations, diff --git a/novawalletTests/Mocks/CommonMocks.swift b/novawalletTests/Mocks/CommonMocks.swift index 9e149ed439..1e739c1916 100644 --- a/novawalletTests/Mocks/CommonMocks.swift +++ b/novawalletTests/Mocks/CommonMocks.swift @@ -5792,16 +5792,16 @@ import RobinHood - func setupSubscription(for accountId: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws { + func setupSubscription(for accountId: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws { - return try cuckoo_manager.callThrows("setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws", - parameters: (accountId, chainId, chainFormat, chainHasProxy), - escapingParameters: (accountId, chainId, chainFormat, chainHasProxy), + return try cuckoo_manager.callThrows("setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws", + parameters: (accountId, chainId, chainFormat), + escapingParameters: (accountId, chainId, chainFormat), superclassCall: Cuckoo.MockManager.crashOnProtocolSuperclassCall() , - defaultCall: __defaultImplStub!.setupSubscription(for: accountId, chainId: chainId, chainFormat: chainFormat, chainHasProxy: chainHasProxy)) + defaultCall: __defaultImplStub!.setupSubscription(for: accountId, chainId: chainId, chainFormat: chainFormat)) } @@ -5829,9 +5829,9 @@ import RobinHood } - func setupSubscription(for accountId: M1, chainId: M2, chainFormat: M3, chainHasProxy: M4) -> Cuckoo.ProtocolStubNoReturnThrowingFunction<(AccountId, ChainModel.Id, ChainFormat, Bool)> where M1.MatchedType == AccountId, M2.MatchedType == ChainModel.Id, M3.MatchedType == ChainFormat, M4.MatchedType == Bool { - let matchers: [Cuckoo.ParameterMatcher<(AccountId, ChainModel.Id, ChainFormat, Bool)>] = [wrap(matchable: accountId) { $0.0 }, wrap(matchable: chainId) { $0.1 }, wrap(matchable: chainFormat) { $0.2 }, wrap(matchable: chainHasProxy) { $0.3 }] - return .init(stub: cuckoo_manager.createStub(for: MockStakingAccountUpdatingServiceProtocol.self, method: "setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws", parameterMatchers: matchers)) + func setupSubscription(for accountId: M1, chainId: M2, chainFormat: M3) -> Cuckoo.ProtocolStubNoReturnThrowingFunction<(AccountId, ChainModel.Id, ChainFormat)> where M1.MatchedType == AccountId, M2.MatchedType == ChainModel.Id, M3.MatchedType == ChainFormat { + let matchers: [Cuckoo.ParameterMatcher<(AccountId, ChainModel.Id, ChainFormat)>] = [wrap(matchable: accountId) { $0.0 }, wrap(matchable: chainId) { $0.1 }, wrap(matchable: chainFormat) { $0.2 }] + return .init(stub: cuckoo_manager.createStub(for: MockStakingAccountUpdatingServiceProtocol.self, method: "setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws", parameterMatchers: matchers)) } func clearSubscription() -> Cuckoo.ProtocolStubNoReturnFunction<()> { @@ -5856,9 +5856,9 @@ import RobinHood @discardableResult - func setupSubscription(for accountId: M1, chainId: M2, chainFormat: M3, chainHasProxy: M4) -> Cuckoo.__DoNotUse<(AccountId, ChainModel.Id, ChainFormat, Bool), Void> where M1.MatchedType == AccountId, M2.MatchedType == ChainModel.Id, M3.MatchedType == ChainFormat, M4.MatchedType == Bool { - let matchers: [Cuckoo.ParameterMatcher<(AccountId, ChainModel.Id, ChainFormat, Bool)>] = [wrap(matchable: accountId) { $0.0 }, wrap(matchable: chainId) { $0.1 }, wrap(matchable: chainFormat) { $0.2 }, wrap(matchable: chainHasProxy) { $0.3 }] - return cuckoo_manager.verify("setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation) + func setupSubscription(for accountId: M1, chainId: M2, chainFormat: M3) -> Cuckoo.__DoNotUse<(AccountId, ChainModel.Id, ChainFormat), Void> where M1.MatchedType == AccountId, M2.MatchedType == ChainModel.Id, M3.MatchedType == ChainFormat { + let matchers: [Cuckoo.ParameterMatcher<(AccountId, ChainModel.Id, ChainFormat)>] = [wrap(matchable: accountId) { $0.0 }, wrap(matchable: chainId) { $0.1 }, wrap(matchable: chainFormat) { $0.2 }] + return cuckoo_manager.verify("setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation) } @discardableResult @@ -5878,7 +5878,7 @@ import RobinHood - func setupSubscription(for accountId: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws { + func setupSubscription(for accountId: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws { return DefaultValueRegistry.defaultValue(for: (Void).self) } @@ -5917,16 +5917,16 @@ import RobinHood - override func setupSubscription(for accountId: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws { + override func setupSubscription(for accountId: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws { - return try cuckoo_manager.callThrows("setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws", - parameters: (accountId, chainId, chainFormat, chainHasProxy), - escapingParameters: (accountId, chainId, chainFormat, chainHasProxy), + return try cuckoo_manager.callThrows("setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws", + parameters: (accountId, chainId, chainFormat), + escapingParameters: (accountId, chainId, chainFormat), superclassCall: - super.setupSubscription(for: accountId, chainId: chainId, chainFormat: chainFormat, chainHasProxy: chainHasProxy) + super.setupSubscription(for: accountId, chainId: chainId, chainFormat: chainFormat) , - defaultCall: __defaultImplStub!.setupSubscription(for: accountId, chainId: chainId, chainFormat: chainFormat, chainHasProxy: chainHasProxy)) + defaultCall: __defaultImplStub!.setupSubscription(for: accountId, chainId: chainId, chainFormat: chainFormat)) } @@ -5954,9 +5954,9 @@ import RobinHood } - func setupSubscription(for accountId: M1, chainId: M2, chainFormat: M3, chainHasProxy: M4) -> Cuckoo.ClassStubNoReturnThrowingFunction<(AccountId, ChainModel.Id, ChainFormat, Bool)> where M1.MatchedType == AccountId, M2.MatchedType == ChainModel.Id, M3.MatchedType == ChainFormat, M4.MatchedType == Bool { - let matchers: [Cuckoo.ParameterMatcher<(AccountId, ChainModel.Id, ChainFormat, Bool)>] = [wrap(matchable: accountId) { $0.0 }, wrap(matchable: chainId) { $0.1 }, wrap(matchable: chainFormat) { $0.2 }, wrap(matchable: chainHasProxy) { $0.3 }] - return .init(stub: cuckoo_manager.createStub(for: MockStakingAccountUpdatingService.self, method: "setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws", parameterMatchers: matchers)) + func setupSubscription(for accountId: M1, chainId: M2, chainFormat: M3) -> Cuckoo.ClassStubNoReturnThrowingFunction<(AccountId, ChainModel.Id, ChainFormat)> where M1.MatchedType == AccountId, M2.MatchedType == ChainModel.Id, M3.MatchedType == ChainFormat { + let matchers: [Cuckoo.ParameterMatcher<(AccountId, ChainModel.Id, ChainFormat)>] = [wrap(matchable: accountId) { $0.0 }, wrap(matchable: chainId) { $0.1 }, wrap(matchable: chainFormat) { $0.2 }] + return .init(stub: cuckoo_manager.createStub(for: MockStakingAccountUpdatingService.self, method: "setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws", parameterMatchers: matchers)) } func clearSubscription() -> Cuckoo.ClassStubNoReturnFunction<()> { @@ -5981,9 +5981,9 @@ import RobinHood @discardableResult - func setupSubscription(for accountId: M1, chainId: M2, chainFormat: M3, chainHasProxy: M4) -> Cuckoo.__DoNotUse<(AccountId, ChainModel.Id, ChainFormat, Bool), Void> where M1.MatchedType == AccountId, M2.MatchedType == ChainModel.Id, M3.MatchedType == ChainFormat, M4.MatchedType == Bool { - let matchers: [Cuckoo.ParameterMatcher<(AccountId, ChainModel.Id, ChainFormat, Bool)>] = [wrap(matchable: accountId) { $0.0 }, wrap(matchable: chainId) { $0.1 }, wrap(matchable: chainFormat) { $0.2 }, wrap(matchable: chainHasProxy) { $0.3 }] - return cuckoo_manager.verify("setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation) + func setupSubscription(for accountId: M1, chainId: M2, chainFormat: M3) -> Cuckoo.__DoNotUse<(AccountId, ChainModel.Id, ChainFormat), Void> where M1.MatchedType == AccountId, M2.MatchedType == ChainModel.Id, M3.MatchedType == ChainFormat { + let matchers: [Cuckoo.ParameterMatcher<(AccountId, ChainModel.Id, ChainFormat)>] = [wrap(matchable: accountId) { $0.0 }, wrap(matchable: chainId) { $0.1 }, wrap(matchable: chainFormat) { $0.2 }] + return cuckoo_manager.verify("setupSubscription(for: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation) } @discardableResult @@ -6003,7 +6003,7 @@ import RobinHood - override func setupSubscription(for accountId: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat, chainHasProxy: Bool) throws { + override func setupSubscription(for accountId: AccountId, chainId: ChainModel.Id, chainFormat: ChainFormat) throws { return DefaultValueRegistry.defaultValue(for: (Void).self) } diff --git a/novawalletTests/Mocks/DefaultStub.swift b/novawalletTests/Mocks/DefaultStub.swift index 713c3a2571..5677bf70df 100644 --- a/novawalletTests/Mocks/DefaultStub.swift +++ b/novawalletTests/Mocks/DefaultStub.swift @@ -124,7 +124,7 @@ extension MockStakingRemoteSubscriptionServiceProtocol { extension MockStakingAccountUpdatingServiceProtocol { func applyDefault() -> MockStakingAccountUpdatingServiceProtocol { stub(self) { stub in - stub.setupSubscription(for: any(), chainId: any(), chainFormat: any(), chainHasProxy: any()).thenDoNothing() + stub.setupSubscription(for: any(), chainId: any(), chainFormat: any()).thenDoNothing() stub.clearSubscription().thenDoNothing() } diff --git a/novawalletTests/Mocks/ModuleMocks.swift b/novawalletTests/Mocks/ModuleMocks.swift index 6378ad82d2..8d887e9f8f 100644 --- a/novawalletTests/Mocks/ModuleMocks.swift +++ b/novawalletTests/Mocks/ModuleMocks.swift @@ -1571,6 +1571,21 @@ import RobinHood + func syncUp(chainId: ChainModel.Id, blockHash: Data?) { + + return cuckoo_manager.call("syncUp(chainId: ChainModel.Id, blockHash: Data?)", + parameters: (chainId, blockHash), + escapingParameters: (chainId, blockHash), + superclassCall: + + Cuckoo.MockManager.crashOnProtocolSuperclassCall() + , + defaultCall: __defaultImplStub!.syncUp(chainId: chainId, blockHash: blockHash)) + + } + + + func setup() { return cuckoo_manager.call("setup()", @@ -1628,6 +1643,11 @@ import RobinHood return .init(stub: cuckoo_manager.createStub(for: MockProxySyncServiceProtocol.self, method: "syncUp()", parameterMatchers: matchers)) } + func syncUp(chainId: M1, blockHash: M2) -> Cuckoo.ProtocolStubNoReturnFunction<(ChainModel.Id, Data?)> where M1.MatchedType == ChainModel.Id, M2.OptionalMatchedType == Data { + let matchers: [Cuckoo.ParameterMatcher<(ChainModel.Id, Data?)>] = [wrap(matchable: chainId) { $0.0 }, wrap(matchable: blockHash) { $0.1 }] + return .init(stub: cuckoo_manager.createStub(for: MockProxySyncServiceProtocol.self, method: "syncUp(chainId: ChainModel.Id, blockHash: Data?)", parameterMatchers: matchers)) + } + func setup() -> Cuckoo.ProtocolStubNoReturnFunction<()> { let matchers: [Cuckoo.ParameterMatcher] = [] return .init(stub: cuckoo_manager.createStub(for: MockProxySyncServiceProtocol.self, method: "setup()", parameterMatchers: matchers)) @@ -1678,6 +1698,12 @@ import RobinHood return cuckoo_manager.verify("syncUp()", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation) } + @discardableResult + func syncUp(chainId: M1, blockHash: M2) -> Cuckoo.__DoNotUse<(ChainModel.Id, Data?), Void> where M1.MatchedType == ChainModel.Id, M2.OptionalMatchedType == Data { + let matchers: [Cuckoo.ParameterMatcher<(ChainModel.Id, Data?)>] = [wrap(matchable: chainId) { $0.0 }, wrap(matchable: blockHash) { $0.1 }] + return cuckoo_manager.verify("syncUp(chainId: ChainModel.Id, blockHash: Data?)", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation) + } + @discardableResult func setup() -> Cuckoo.__DoNotUse<(), Void> { let matchers: [Cuckoo.ParameterMatcher] = [] @@ -1725,6 +1751,12 @@ import RobinHood + func syncUp(chainId: ChainModel.Id, blockHash: Data?) { + return DefaultValueRegistry.defaultValue(for: (Void).self) + } + + + func setup() { return DefaultValueRegistry.defaultValue(for: (Void).self) }