[#1165] draft
draft [#1165] Step 1 - Download note commitment tree data from lightwalletd - code cleanup after draft [#1165] Step 1 - Download note commitment tree data from lightwalletd - UpdateSubtreeRootsAction added, ensuring the roots are downloaded and stored in the DB [#1165] Step 1 - Download note commitment tree data from lightwalletd - added ZcashError for putSaplingSubtreeRoots failure - cleaned up action [#1165] Step 1 - Download note commitment tree data from lightwalletd - demo app config temporarily updated to Nighthawk server [#1165] Step 1 - Download note commitment tree data from lightwalletd - file header updated [#1165] Step 1 - Download note commitment tree data from lightwalletd (#1174) - demo app config cleaned up [#1165] Step 1 - Download note commitment tree data from lightwalletd (#1174) - offline tests fixed
This commit is contained in:
parent
d446c6d336
commit
7694b04d42
|
@ -18,14 +18,14 @@ enum DemoAppConfig {
|
|||
let seed: [UInt8]
|
||||
}
|
||||
|
||||
static let host = ZcashSDK.isMainnet ? "lightwalletd.electriccoin.co" : "lightwalletd.testnet.electriccoin.co"
|
||||
static let host = ZcashSDK.isMainnet ? "mainnet.lightwalletd.com" : "testnet.lightwalletd.com"
|
||||
static let port: Int = 9067
|
||||
|
||||
static let defaultBirthdayHeight: BlockHeight = ZcashSDK.isMainnet ? 935000 : 1386000
|
||||
static let defaultSeed = try! Mnemonic.deterministicSeedBytes(from: """
|
||||
live combine flight accident slow soda mind bright absent bid hen shy decade biology amazing mix enlist ensure biology rhythm snap duty soap armor
|
||||
""")
|
||||
|
||||
|
||||
static let otherSynchronizers: [SynchronizerInitData] = [
|
||||
SynchronizerInitData(
|
||||
alias: .custom("alt-sync-1"),
|
||||
|
|
|
@ -34,6 +34,7 @@ enum CBPState: CaseIterable {
|
|||
case idle
|
||||
case migrateLegacyCacheDB
|
||||
case validateServer
|
||||
case updateSubtreeRoots
|
||||
case computeSyncControlData
|
||||
case download
|
||||
case scan
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// UpdateSubtreeRootsAction.swift
|
||||
//
|
||||
//
|
||||
// Created by Lukas Korba on 01.08.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
final class UpdateSubtreeRootsAction {
|
||||
let rustBackend: ZcashRustBackendWelding
|
||||
let service: LightWalletService
|
||||
let logger: Logger
|
||||
|
||||
init(container: DIContainer) {
|
||||
service = container.resolve(LightWalletService.self)
|
||||
rustBackend = container.resolve(ZcashRustBackendWelding.self)
|
||||
logger = container.resolve(Logger.self)
|
||||
}
|
||||
}
|
||||
|
||||
extension UpdateSubtreeRootsAction: Action {
|
||||
var removeBlocksCacheWhenFailed: Bool { false }
|
||||
|
||||
func run(with context: ActionContext, didUpdate: @escaping (CompactBlockProcessor.Event) async -> Void) async throws -> ActionContext {
|
||||
var request = GetSubtreeRootsArg()
|
||||
request.shieldedProtocol = .sapling
|
||||
request.maxEntries = 65536
|
||||
|
||||
logger.info("Attempt to get subtree roots, this may fail because lightwalletd may not support DAG sync.")
|
||||
let stream = service.getSubtreeRoots(request)
|
||||
|
||||
var roots: [SubtreeRoot] = []
|
||||
var err: Error?
|
||||
|
||||
do {
|
||||
for try await subtreeRoot in stream {
|
||||
roots.append(subtreeRoot)
|
||||
}
|
||||
} catch {
|
||||
logger.debug("getSubtreeRoots failed with error \(error.localizedDescription)")
|
||||
err = error
|
||||
}
|
||||
|
||||
// In case of error, the lightwalletd doesn't support DAG sync -> switching to linear sync.
|
||||
// Likewise, no subtree roots results in switching to linear sync.
|
||||
if err != nil || roots.isEmpty {
|
||||
logger.info("DAG sync is not possible, switching to linear sync.")
|
||||
await context.update(state: .computeSyncControlData)
|
||||
} else {
|
||||
logger.info("Sapling tree has \(roots.count) subtrees")
|
||||
do {
|
||||
try await rustBackend.putSaplingSubtreeRoots(startIndex: UInt64(request.startIndex), roots: roots)
|
||||
|
||||
// TODO: [#1167] Switching back to linear sync for now before step 3 & 4 are implemented
|
||||
// https://github.com/zcash/ZcashLightClientKit/issues/1167
|
||||
await context.update(state: .computeSyncControlData)
|
||||
} catch {
|
||||
logger.debug("putSaplingSubtreeRoots failed with error \(error.localizedDescription)")
|
||||
throw ZcashError.compactBlockProcessorPutSaplingSubtreeRoots(error)
|
||||
}
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
func stop() async { }
|
||||
}
|
|
@ -52,7 +52,7 @@ extension ValidateServerAction: Action {
|
|||
throw ZcashError.compactBlockProcessorWrongConsensusBranchId(localBranch, remoteBranchID)
|
||||
}
|
||||
|
||||
await context.update(state: .computeSyncControlData)
|
||||
await context.update(state: .updateSubtreeRoots)
|
||||
return context
|
||||
}
|
||||
|
||||
|
|
|
@ -214,6 +214,8 @@ actor CompactBlockProcessor {
|
|||
action = MigrateLegacyCacheDBAction(container: container, configProvider: configProvider)
|
||||
case .validateServer:
|
||||
action = ValidateServerAction(container: container, configProvider: configProvider)
|
||||
case .updateSubtreeRoots:
|
||||
action = UpdateSubtreeRootsAction(container: container)
|
||||
case .computeSyncControlData:
|
||||
action = ComputeSyncControlDataAction(container: container, configProvider: configProvider)
|
||||
case .download:
|
||||
|
@ -585,6 +587,8 @@ extension CompactBlockProcessor {
|
|||
break
|
||||
case .validateServer:
|
||||
break
|
||||
case .updateSubtreeRoots:
|
||||
break
|
||||
case .computeSyncControlData:
|
||||
break
|
||||
case .download:
|
||||
|
|
|
@ -58,6 +58,9 @@ public enum ZcashError: Equatable, Error {
|
|||
/// LightWalletService.blockStream failed.
|
||||
/// ZSRVC0000
|
||||
case serviceBlockStreamFailed(_ error: LightWalletServiceError)
|
||||
/// LightWalletService.getSubtreeRoots failed.
|
||||
/// ZSRVC0009
|
||||
case serviceSubtreeRootsStreamFailed(_ error: LightWalletServiceError)
|
||||
/// SimpleConnectionProvider init of Connection failed.
|
||||
/// ZSCPC0001
|
||||
case simpleConnectionProvider(_ error: Error)
|
||||
|
@ -277,18 +280,22 @@ public enum ZcashError: Equatable, Error {
|
|||
/// ZRUST0045
|
||||
case rustGetTransparentReceiverInvalidReceiver
|
||||
/// Unable to allocate memory required to write blocks when calling ZcashRustBackend.putSaplingSubtreeRoots
|
||||
/// sourcery: code="ZRUST0046"
|
||||
/// ZRUST0046
|
||||
case rustPutSaplingSubtreeRootsAllocationProblem
|
||||
/// Error from rust layer when calling ZcashRustBackend.putSaplingSubtreeRoots
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// sourcery: code="ZRUST0047"
|
||||
/// ZRUST0047
|
||||
case rustPutSaplingSubtreeRoots(_ rustError: String)
|
||||
/// Error from rust layer when calling ZcashRustBackend.updateChainTip
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// sourcery: code="ZRUST0048"
|
||||
/// ZRUST0048
|
||||
case rustUpdateChainTip(_ rustError: String)
|
||||
/// Error from rust layer when calling ZcashRustBackend.suggestScanRanges
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// sourcery: code="ZRUST0049"
|
||||
/// ZRUST0049
|
||||
case rustSuggestScanRanges(_ rustError: String)
|
||||
/// Invalid transaction ID length when calling ZcashRustBackend.getMemo
|
||||
|
@ -530,6 +537,9 @@ public enum ZcashError: Equatable, Error {
|
|||
/// Rewind of DownloadBlockAction failed as no action is possible to unwrapp.
|
||||
/// ZCBPEO0018
|
||||
case compactBlockProcessorDownloadBlockActionRewind
|
||||
/// Put sapling subtree roots to the DB failed.
|
||||
/// ZCBPEO0019
|
||||
case compactBlockProcessorPutSaplingSubtreeRoots(_ error: Error)
|
||||
/// The synchronizer is unprepared.
|
||||
/// ZSYNCO0001
|
||||
case synchronizerNotPrepared
|
||||
|
@ -566,6 +576,7 @@ public enum ZcashError: Equatable, Error {
|
|||
case .serviceFetchTransactionFailed: return "LightWalletService.fetchTransaction failed."
|
||||
case .serviceFetchUTXOsFailed: return "LightWalletService.fetchUTXOs failed."
|
||||
case .serviceBlockStreamFailed: return "LightWalletService.blockStream failed."
|
||||
case .serviceSubtreeRootsStreamFailed: return "LightWalletService.getSubtreeRoots failed."
|
||||
case .simpleConnectionProvider: return "SimpleConnectionProvider init of Connection failed."
|
||||
case .saplingParamsInvalidSpendParams: return "Downloaded file with sapling spending parameters isn't valid."
|
||||
case .saplingParamsInvalidOutputParams: return "Downloaded file with sapling output parameters isn't valid."
|
||||
|
@ -623,7 +634,7 @@ public enum ZcashError: Equatable, Error {
|
|||
case .rustGetSaplingReceiverInvalidReceiver: return "Sapling receiver generated by rust layer is invalid when calling ZcashRustBackend.getSaplingReceiver"
|
||||
case .rustGetTransparentReceiverInvalidAddress: return "Error from rust layer when calling ZcashRustBackend.getTransparentReceiver"
|
||||
case .rustGetTransparentReceiverInvalidReceiver: return "Transparent receiver generated by rust layer is invalid when calling ZcashRustBackend.getTransparentReceiver"
|
||||
case .rustPutSaplingSubtreeRootsAllocationProblem: return "Unable to allocate memory required to store subtree roots when calling ZcashRustBackend.putSaplingSubtreeRoots"
|
||||
case .rustPutSaplingSubtreeRootsAllocationProblem: return "Unable to allocate memory required to write blocks when calling ZcashRustBackend.putSaplingSubtreeRoots"
|
||||
case .rustPutSaplingSubtreeRoots: return "Error from rust layer when calling ZcashRustBackend.putSaplingSubtreeRoots"
|
||||
case .rustUpdateChainTip: return "Error from rust layer when calling ZcashRustBackend.updateChainTip"
|
||||
case .rustSuggestScanRanges: return "Error from rust layer when calling ZcashRustBackend.suggestScanRanges"
|
||||
|
@ -703,6 +714,7 @@ public enum ZcashError: Equatable, Error {
|
|||
case .compactBlockProcessorChainName: return "Chain name does not match. Expected either 'test' or 'main'. This is probably an API or programming error."
|
||||
case .compactBlockProcessorConsensusBranchID: return "Consensus BranchIDs don't match this is probably an API or programming error."
|
||||
case .compactBlockProcessorDownloadBlockActionRewind: return "Rewind of DownloadBlockAction failed as no action is possible to unwrapp."
|
||||
case .compactBlockProcessorPutSaplingSubtreeRoots: return "Put sapling subtree roots to the DB failed."
|
||||
case .synchronizerNotPrepared: return "The synchronizer is unprepared."
|
||||
case .synchronizerSendMemoToTransparentAddress: return "Memos can't be sent to transparent addresses."
|
||||
case .synchronizerShieldFundsInsuficientTransparentFunds: return "There is not enough transparent funds to cover fee for the shielding."
|
||||
|
@ -729,6 +741,7 @@ public enum ZcashError: Equatable, Error {
|
|||
case .serviceFetchTransactionFailed: return .serviceFetchTransactionFailed
|
||||
case .serviceFetchUTXOsFailed: return .serviceFetchUTXOsFailed
|
||||
case .serviceBlockStreamFailed: return .serviceBlockStreamFailed
|
||||
case .serviceSubtreeRootsStreamFailed: return .serviceSubtreeRootsStreamFailed
|
||||
case .simpleConnectionProvider: return .simpleConnectionProvider
|
||||
case .saplingParamsInvalidSpendParams: return .saplingParamsInvalidSpendParams
|
||||
case .saplingParamsInvalidOutputParams: return .saplingParamsInvalidOutputParams
|
||||
|
@ -866,6 +879,7 @@ public enum ZcashError: Equatable, Error {
|
|||
case .compactBlockProcessorChainName: return .compactBlockProcessorChainName
|
||||
case .compactBlockProcessorConsensusBranchID: return .compactBlockProcessorConsensusBranchID
|
||||
case .compactBlockProcessorDownloadBlockActionRewind: return .compactBlockProcessorDownloadBlockActionRewind
|
||||
case .compactBlockProcessorPutSaplingSubtreeRoots: return .compactBlockProcessorPutSaplingSubtreeRoots
|
||||
case .synchronizerNotPrepared: return .synchronizerNotPrepared
|
||||
case .synchronizerSendMemoToTransparentAddress: return .synchronizerSendMemoToTransparentAddress
|
||||
case .synchronizerShieldFundsInsuficientTransparentFunds: return .synchronizerShieldFundsInsuficientTransparentFunds
|
||||
|
|
|
@ -39,6 +39,8 @@ public enum ZcashErrorCode: String {
|
|||
case serviceFetchUTXOsFailed = "ZSRVC0008"
|
||||
/// LightWalletService.blockStream failed.
|
||||
case serviceBlockStreamFailed = "ZSRVC0000"
|
||||
/// LightWalletService.getSubtreeRoots failed.
|
||||
case serviceSubtreeRootsStreamFailed = "ZSRVC0009"
|
||||
/// SimpleConnectionProvider init of Connection failed.
|
||||
case simpleConnectionProvider = "ZSCPC0001"
|
||||
/// Downloaded file with sapling spending parameters isn't valid.
|
||||
|
@ -313,6 +315,8 @@ public enum ZcashErrorCode: String {
|
|||
case compactBlockProcessorConsensusBranchID = "ZCBPEO0017"
|
||||
/// Rewind of DownloadBlockAction failed as no action is possible to unwrapp.
|
||||
case compactBlockProcessorDownloadBlockActionRewind = "ZCBPEO0018"
|
||||
/// Put sapling subtree roots to the DB failed.
|
||||
case compactBlockProcessorPutSaplingSubtreeRoots = "ZCBPEO0019"
|
||||
/// The synchronizer is unprepared.
|
||||
case synchronizerNotPrepared = "ZSYNCO0001"
|
||||
/// Memos can't be sent to transparent addresses.
|
||||
|
|
|
@ -77,6 +77,9 @@ enum ZcashErrorDefinition {
|
|||
/// LightWalletService.blockStream failed.
|
||||
// sourcery: code="ZSRVC0000"
|
||||
case serviceBlockStreamFailed(_ error: LightWalletServiceError)
|
||||
/// LightWalletService.getSubtreeRoots failed.
|
||||
// sourcery: code="ZSRVC0009"
|
||||
case serviceSubtreeRootsStreamFailed(_ error: LightWalletServiceError)
|
||||
|
||||
// MARK: SQLite connection
|
||||
|
||||
|
@ -307,6 +310,21 @@ enum ZcashErrorDefinition {
|
|||
/// Transparent receiver generated by rust layer is invalid when calling ZcashRustBackend.getTransparentReceiver
|
||||
// sourcery: code="ZRUST0045"
|
||||
case rustGetTransparentReceiverInvalidReceiver
|
||||
/// Unable to allocate memory required to write blocks when calling ZcashRustBackend.putSaplingSubtreeRoots
|
||||
/// sourcery: code="ZRUST0046"
|
||||
case rustPutSaplingSubtreeRootsAllocationProblem
|
||||
/// Error from rust layer when calling ZcashRustBackend.putSaplingSubtreeRoots
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// sourcery: code="ZRUST0047"
|
||||
case rustPutSaplingSubtreeRoots(_ rustError: String)
|
||||
/// Error from rust layer when calling ZcashRustBackend.updateChainTip
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// sourcery: code="ZRUST0048"
|
||||
case rustUpdateChainTip(_ rustError: String)
|
||||
/// Error from rust layer when calling ZcashRustBackend.suggestScanRanges
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// sourcery: code="ZRUST0049"
|
||||
case rustSuggestScanRanges(_ rustError: String)
|
||||
|
||||
// MARK: - Account DAO
|
||||
|
||||
|
@ -592,6 +610,9 @@ enum ZcashErrorDefinition {
|
|||
/// Rewind of DownloadBlockAction failed as no action is possible to unwrapp.
|
||||
// sourcery: code="ZCBPEO0018"
|
||||
case compactBlockProcessorDownloadBlockActionRewind
|
||||
/// Put sapling subtree roots to the DB failed.
|
||||
// sourcery: code="ZCBPEO0019"
|
||||
case compactBlockProcessorPutSaplingSubtreeRoots(_ error: Error)
|
||||
|
||||
// MARK: - SDKSynchronizer
|
||||
|
||||
|
|
|
@ -262,6 +262,21 @@ extension LightWalletGRPCService: LightWalletService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getSubtreeRoots(_ request: GetSubtreeRootsArg) -> AsyncThrowingStream<SubtreeRoot, Error> {
|
||||
let stream = compactTxStreamer.getSubtreeRoots(request)
|
||||
var iterator = stream.makeAsyncIterator()
|
||||
|
||||
return AsyncThrowingStream() {
|
||||
do {
|
||||
guard let subtreeRoot = try await iterator.next() else { return nil }
|
||||
return subtreeRoot
|
||||
} catch {
|
||||
let serviceError = error.mapToServiceError()
|
||||
throw ZcashError.serviceSubtreeRootsStreamFailed(serviceError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func closeConnection() {
|
||||
_ = channel.close()
|
||||
|
|
|
@ -193,4 +193,11 @@ protocol LightWalletService: AnyObject {
|
|||
) -> AsyncThrowingStream<ZcashCompactBlock, Error>
|
||||
|
||||
func closeConnection()
|
||||
|
||||
/// Returns a stream of information about roots of subtrees of the Sapling and Orchard
|
||||
/// note commitment trees.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - request: Request to send to GetSubtreeRoots.
|
||||
func getSubtreeRoots(_ request: GetSubtreeRootsArg) -> AsyncThrowingStream<SubtreeRoot, Error>
|
||||
}
|
||||
|
|
|
@ -166,6 +166,10 @@ protocol ZcashRustBackendWelding {
|
|||
/// - Throws: `rustRewindCacheToHeight` if rust layer returns error.
|
||||
func rewindCacheToHeight(height: Int32) async throws
|
||||
|
||||
func putSaplingSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws
|
||||
|
||||
func updateChainTip(height: Int32) async throws
|
||||
|
||||
/// Returns a list of suggested scan ranges based upon the current wallet state.
|
||||
///
|
||||
/// This method should only be used in cases where the `CompactBlock` data that will be
|
||||
|
|
|
@ -141,7 +141,7 @@ public class SDKSynchronizer: Synchronizer {
|
|||
if case .seedRequired = try await self.initializer.initialize(with: seed, viewingKeys: viewingKeys, walletBirthday: walletBirthday) {
|
||||
return .seedRequired
|
||||
}
|
||||
|
||||
|
||||
await latestBlocksDataProvider.updateWalletBirthday(initializer.walletBirthday)
|
||||
await latestBlocksDataProvider.updateScannedData()
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ final class ValidateServerActionTests: ZcashTestCase {
|
|||
let nextContext = try await validateServerAction.run(with: .init(state: .validateServer)) { _ in }
|
||||
let nextState = await nextContext.state
|
||||
XCTAssertTrue(
|
||||
nextState == .computeSyncControlData,
|
||||
"nextContext after .validateServer is expected to be .computeSyncControlData but received \(nextState)"
|
||||
nextState == .updateSubtreeRoots,
|
||||
"nextContext after .validateServer is expected to be .updateSubtreeRoots but received \(nextState)"
|
||||
)
|
||||
} catch {
|
||||
XCTFail("testValidateServerAction_NextAction is not expected to fail. \(error)")
|
||||
|
|
|
@ -13,27 +13,27 @@ enum DarksideDataset: String {
|
|||
case afterLargeReorg = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/after-large-large.txt"
|
||||
case afterSmallReorg = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/after-small-reorg.txt"
|
||||
case beforeReOrg = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/before-reorg.txt"
|
||||
|
||||
|
||||
/**
|
||||
see
|
||||
https://github.com/zcash-hackworks/darksidewalletd-test-data/tree/master/tx-index-reorg
|
||||
*/
|
||||
see
|
||||
https://github.com/zcash-hackworks/darksidewalletd-test-data/tree/master/tx-index-reorg
|
||||
*/
|
||||
case txIndexChangeBefore = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/tx-index-reorg/before-reorg.txt"
|
||||
|
||||
|
||||
case txIndexChangeAfter = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/tx-index-reorg/after-reorg.txt"
|
||||
|
||||
|
||||
/**
|
||||
See https://github.com/zcash-hackworks/darksidewalletd-test-data/tree/master/tx-height-reorg
|
||||
*/
|
||||
See https://github.com/zcash-hackworks/darksidewalletd-test-data/tree/master/tx-height-reorg
|
||||
*/
|
||||
case txHeightReOrgBefore = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/tx-height-reorg/before-reorg.txt"
|
||||
|
||||
|
||||
case txHeightReOrgAfter = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/tx-height-reorg/after-reorg.txt"
|
||||
|
||||
|
||||
/*
|
||||
see: https://github.com/zcash-hackworks/darksidewalletd-test-data/tree/master/tx-remove-reorg
|
||||
*/
|
||||
see: https://github.com/zcash-hackworks/darksidewalletd-test-data/tree/master/tx-remove-reorg
|
||||
*/
|
||||
case txReOrgRemovesInboundTxBefore = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/tx-remove-reorg/before-reorg.txt"
|
||||
|
||||
|
||||
case txReOrgRemovesInboundTxAfter = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/tx-remove-reorg/after-reorg.txt"
|
||||
}
|
||||
|
||||
|
@ -45,34 +45,34 @@ class DarksideWalletService: LightWalletService {
|
|||
var channel: Channel
|
||||
var service: LightWalletService
|
||||
var darksideService: DarksideStreamerNIOClient
|
||||
|
||||
|
||||
init(endpoint: LightWalletEndpoint) {
|
||||
self.channel = ChannelProvider().channel(endpoint: endpoint)
|
||||
self.service = LightWalletServiceFactory(endpoint: endpoint).make()
|
||||
self.darksideService = DarksideStreamerNIOClient(channel: channel)
|
||||
}
|
||||
|
||||
|
||||
init(endpoint: LightWalletEndpoint, service: LightWalletService) {
|
||||
self.channel = ChannelProvider().channel(endpoint: endpoint)
|
||||
self.darksideService = DarksideStreamerNIOClient(channel: channel)
|
||||
self.service = service
|
||||
}
|
||||
|
||||
|
||||
convenience init() {
|
||||
self.init(endpoint: LightWalletEndpointBuilder.default)
|
||||
}
|
||||
|
||||
|
||||
func blockStream(startHeight: BlockHeight, endHeight: BlockHeight) -> AsyncThrowingStream<ZcashCompactBlock, Error> {
|
||||
service.blockStream(startHeight: startHeight, endHeight: endHeight)
|
||||
}
|
||||
|
||||
|
||||
func latestBlock() async throws -> ZcashLightClientKit.BlockID {
|
||||
throw "Not mocked"
|
||||
}
|
||||
|
||||
func closeConnection() {
|
||||
}
|
||||
|
||||
|
||||
func fetchUTXOs(for tAddress: String, height: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
|
||||
service.fetchUTXOs(for: tAddress, height: height)
|
||||
}
|
||||
|
@ -80,40 +80,40 @@ class DarksideWalletService: LightWalletService {
|
|||
func fetchUTXOs(for tAddresses: [String], height: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
|
||||
service.fetchUTXOs(for: tAddresses, height: height)
|
||||
}
|
||||
|
||||
|
||||
func latestBlockHeight() async throws -> BlockHeight {
|
||||
try await service.latestBlockHeight()
|
||||
}
|
||||
|
||||
|
||||
func useDataset(_ datasetUrl: String) throws {
|
||||
try useDataset(from: datasetUrl)
|
||||
}
|
||||
|
||||
|
||||
func useDataset(from urlString: String) throws {
|
||||
var blocksUrl = DarksideBlocksURL()
|
||||
blocksUrl.url = urlString
|
||||
_ = try darksideService.stageBlocks(blocksUrl, callOptions: nil).response.wait()
|
||||
}
|
||||
|
||||
|
||||
func applyStaged(nextLatestHeight: BlockHeight) throws {
|
||||
var darksideHeight = DarksideHeight()
|
||||
darksideHeight.height = Int32(nextLatestHeight)
|
||||
_ = try darksideService.applyStaged(darksideHeight).response.wait()
|
||||
}
|
||||
|
||||
|
||||
func clearIncomingTransactions() throws {
|
||||
_ = try darksideService.clearIncomingTransactions(Empty()).response.wait()
|
||||
}
|
||||
|
||||
|
||||
func getIncomingTransactions() throws -> [RawTransaction]? {
|
||||
var txs: [RawTransaction] = []
|
||||
let response = try darksideService.getIncomingTransactions(
|
||||
Empty(),
|
||||
handler: { txs.append($0) }
|
||||
)
|
||||
.status
|
||||
.wait()
|
||||
|
||||
.status
|
||||
.wait()
|
||||
|
||||
switch response.code {
|
||||
case .ok:
|
||||
return !txs.isEmpty ? txs : nil
|
||||
|
@ -121,7 +121,7 @@ class DarksideWalletService: LightWalletService {
|
|||
throw response
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func reset(saplingActivation: BlockHeight, branchID: String = "d3adb33f", chainName: String = "test") throws {
|
||||
var metaState = DarksideMetaState()
|
||||
metaState.saplingActivation = Int32(saplingActivation)
|
||||
|
@ -130,7 +130,7 @@ class DarksideWalletService: LightWalletService {
|
|||
// TODO: [#718] complete meta state correctly, https://github.com/zcash/ZcashLightClientKit/issues/718
|
||||
_ = try darksideService.reset(metaState).response.wait()
|
||||
}
|
||||
|
||||
|
||||
func stageBlocksCreate(from height: BlockHeight, count: Int = 1, nonce: Int = 0) throws {
|
||||
var emptyBlocks = DarksideEmptyBlocks()
|
||||
emptyBlocks.count = Int32(count)
|
||||
|
@ -138,7 +138,7 @@ class DarksideWalletService: LightWalletService {
|
|||
emptyBlocks.nonce = Int32(nonce)
|
||||
_ = try darksideService.stageBlocksCreate(emptyBlocks).response.wait()
|
||||
}
|
||||
|
||||
|
||||
func stageTransaction(_ rawTransaction: RawTransaction, at height: BlockHeight) throws {
|
||||
var transaction = rawTransaction
|
||||
transaction.height = UInt64(height)
|
||||
|
@ -146,18 +146,18 @@ class DarksideWalletService: LightWalletService {
|
|||
.sendMessage(transaction)
|
||||
.wait()
|
||||
}
|
||||
|
||||
|
||||
func stageTransaction(from url: String, at height: BlockHeight) throws {
|
||||
var txUrl = DarksideTransactionsURL()
|
||||
txUrl.height = Int32(height)
|
||||
txUrl.url = url
|
||||
_ = try darksideService.stageTransactions(txUrl, callOptions: nil).response.wait()
|
||||
}
|
||||
|
||||
|
||||
func addUTXO(_ utxo: GetAddressUtxosReply) throws {
|
||||
_ = try darksideService.addAddressUtxo(utxo, callOptions: nil).response.wait()
|
||||
}
|
||||
|
||||
|
||||
func clearAddedUTXOs() throws {
|
||||
_ = try darksideService.clearAddressUtxo(Empty(), callOptions: nil).response.wait()
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ class DarksideWalletService: LightWalletService {
|
|||
func getInfo() async throws -> LightWalletdInfo {
|
||||
try await service.getInfo()
|
||||
}
|
||||
|
||||
|
||||
func blockRange(_ range: CompactBlockRange) -> AsyncThrowingStream<ZcashCompactBlock, Error> {
|
||||
service.blockRange(range)
|
||||
}
|
||||
|
@ -178,27 +178,31 @@ class DarksideWalletService: LightWalletService {
|
|||
func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched {
|
||||
try await service.fetchTransaction(txId: txId)
|
||||
}
|
||||
|
||||
func getSubtreeRoots(_ request: ZcashLightClientKit.GetSubtreeRootsArg) -> AsyncThrowingStream<ZcashLightClientKit.SubtreeRoot, Error> {
|
||||
service.getSubtreeRoots(request)
|
||||
}
|
||||
}
|
||||
|
||||
enum DarksideWalletDConstants: NetworkConstants {
|
||||
static let defaultFsBlockDbRootName = "fs_cache"
|
||||
|
||||
|
||||
static var saplingActivationHeight: BlockHeight {
|
||||
663150
|
||||
}
|
||||
|
||||
|
||||
static var defaultDataDbName: String {
|
||||
ZcashSDKMainnetConstants.defaultDataDbName
|
||||
}
|
||||
|
||||
|
||||
static var defaultCacheDbName: String {
|
||||
ZcashSDKMainnetConstants.defaultCacheDbName
|
||||
}
|
||||
|
||||
|
||||
static var defaultDbNamePrefix: String {
|
||||
ZcashSDKMainnetConstants.defaultDbNamePrefix
|
||||
}
|
||||
|
||||
|
||||
static var feeChangeHeight: BlockHeight {
|
||||
ZcashSDKMainnetConstants.feeChangeHeight
|
||||
}
|
||||
|
|
|
@ -78,4 +78,8 @@ class MockLightWalletService: LightWalletService {
|
|||
func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched {
|
||||
return ZcashTransaction.Fetched(rawID: Data(), minedHeight: -1, raw: Data())
|
||||
}
|
||||
|
||||
func getSubtreeRoots(_ request: ZcashLightClientKit.GetSubtreeRootsArg) -> AsyncThrowingStream<ZcashLightClientKit.SubtreeRoot, Error> {
|
||||
service.getSubtreeRoots(request)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -820,6 +820,26 @@ class LightWalletServiceMock: LightWalletService {
|
|||
closeConnectionClosure!()
|
||||
}
|
||||
|
||||
// MARK: - getSubtreeRoots
|
||||
|
||||
var getSubtreeRootsCallsCount = 0
|
||||
var getSubtreeRootsCalled: Bool {
|
||||
return getSubtreeRootsCallsCount > 0
|
||||
}
|
||||
var getSubtreeRootsReceivedRequest: GetSubtreeRootsArg?
|
||||
var getSubtreeRootsReturnValue: AsyncThrowingStream<SubtreeRoot, Error>!
|
||||
var getSubtreeRootsClosure: ((GetSubtreeRootsArg) -> AsyncThrowingStream<SubtreeRoot, Error>)?
|
||||
|
||||
func getSubtreeRoots(_ request: GetSubtreeRootsArg) -> AsyncThrowingStream<SubtreeRoot, Error> {
|
||||
getSubtreeRootsCallsCount += 1
|
||||
getSubtreeRootsReceivedRequest = request
|
||||
if let closure = getSubtreeRootsClosure {
|
||||
return closure(request)
|
||||
} else {
|
||||
return getSubtreeRootsReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
class LightWalletdInfoMock: LightWalletdInfo {
|
||||
|
||||
|
@ -2574,6 +2594,56 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
try await rewindCacheToHeightHeightClosure!(height)
|
||||
}
|
||||
|
||||
// MARK: - putSaplingSubtreeRoots
|
||||
|
||||
var putSaplingSubtreeRootsStartIndexRootsThrowableError: Error?
|
||||
func setPutSaplingSubtreeRootsStartIndexRootsThrowableError(_ param: Error?) async {
|
||||
putSaplingSubtreeRootsStartIndexRootsThrowableError = param
|
||||
}
|
||||
var putSaplingSubtreeRootsStartIndexRootsCallsCount = 0
|
||||
var putSaplingSubtreeRootsStartIndexRootsCalled: Bool {
|
||||
return putSaplingSubtreeRootsStartIndexRootsCallsCount > 0
|
||||
}
|
||||
var putSaplingSubtreeRootsStartIndexRootsReceivedArguments: (startIndex: UInt64, roots: [SubtreeRoot])?
|
||||
var putSaplingSubtreeRootsStartIndexRootsClosure: ((UInt64, [SubtreeRoot]) async throws -> Void)?
|
||||
func setPutSaplingSubtreeRootsStartIndexRootsClosure(_ param: ((UInt64, [SubtreeRoot]) async throws -> Void)?) async {
|
||||
putSaplingSubtreeRootsStartIndexRootsClosure = param
|
||||
}
|
||||
|
||||
func putSaplingSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws {
|
||||
if let error = putSaplingSubtreeRootsStartIndexRootsThrowableError {
|
||||
throw error
|
||||
}
|
||||
putSaplingSubtreeRootsStartIndexRootsCallsCount += 1
|
||||
putSaplingSubtreeRootsStartIndexRootsReceivedArguments = (startIndex: startIndex, roots: roots)
|
||||
try await putSaplingSubtreeRootsStartIndexRootsClosure!(startIndex, roots)
|
||||
}
|
||||
|
||||
// MARK: - updateChainTip
|
||||
|
||||
var updateChainTipHeightThrowableError: Error?
|
||||
func setUpdateChainTipHeightThrowableError(_ param: Error?) async {
|
||||
updateChainTipHeightThrowableError = param
|
||||
}
|
||||
var updateChainTipHeightCallsCount = 0
|
||||
var updateChainTipHeightCalled: Bool {
|
||||
return updateChainTipHeightCallsCount > 0
|
||||
}
|
||||
var updateChainTipHeightReceivedHeight: Int32?
|
||||
var updateChainTipHeightClosure: ((Int32) async throws -> Void)?
|
||||
func setUpdateChainTipHeightClosure(_ param: ((Int32) async throws -> Void)?) async {
|
||||
updateChainTipHeightClosure = param
|
||||
}
|
||||
|
||||
func updateChainTip(height: Int32) async throws {
|
||||
if let error = updateChainTipHeightThrowableError {
|
||||
throw error
|
||||
}
|
||||
updateChainTipHeightCallsCount += 1
|
||||
updateChainTipHeightReceivedHeight = height
|
||||
try await updateChainTipHeightClosure!(height)
|
||||
}
|
||||
|
||||
// MARK: - suggestScanRanges
|
||||
|
||||
var suggestScanRangesThrowableError: Error?
|
||||
|
|
Loading…
Reference in New Issue