ZcashLightClientKit/Tests/TestUtils/DarkSideWalletService.swift

207 lines
7.6 KiB
Swift
Raw Normal View History

//
// DarkSideWalletService.swift
// ZcashLightClientKit-Unit-Tests
//
// Created by Francisco Gindre on 3/23/20.
//
import Foundation
@testable import ZcashLightClientKit
import GRPC
enum DarksideDataset: String {
case afterLargeReorg = "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/after-large-large.txt"
2021-09-23 06:26:41 -07:00
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"
/**
2021-09-23 06:26:41 -07:00
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"
/**
2021-09-23 06:26:41 -07:00
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"
/*
2021-09-23 06:26:41 -07:00
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"
}
class DarksideWalletService: LightWalletService {
2021-09-23 06:26:41 -07:00
var channel: Channel
var service: LightWalletService
2021-09-23 06:26:41 -07:00
var darksideService: DarksideStreamerClient
init(endpoint: LightWalletEndpoint) {
self.channel = ChannelProvider().channel()
self.service = LightWalletServiceFactory(endpoint: endpoint, connectionStateChange: { _, _ in }).make()
2021-09-23 06:26:41 -07:00
self.darksideService = DarksideStreamerClient(channel: channel)
}
init(service: LightWalletService) {
2021-09-23 06:26:41 -07:00
self.channel = ChannelProvider().channel()
self.darksideService = DarksideStreamerClient(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 closeConnection() {
2021-04-02 15:18:16 -07:00
}
func fetchUTXOs(for tAddress: String, height: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
service.fetchUTXOs(for: tAddress, height: height)
2021-04-02 15:18:16 -07:00
}
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]? {
2021-09-23 06:26:41 -07:00
var txs: [RawTransaction] = []
let response = try darksideService.getIncomingTransactions(
Empty(),
handler: { txs.append($0) }
)
.status
.wait()
switch response.code {
2021-09-23 06:26:41 -07:00
case .ok:
return !txs.isEmpty ? txs : nil
default:
throw response
}
}
2020-11-05 14:02:01 -08:00
func reset(saplingActivation: BlockHeight, branchID: String = "d3adb33f", chainName: String = "test") throws {
var metaState = DarksideMetaState()
metaState.saplingActivation = Int32(saplingActivation)
2021-05-18 14:22:29 -07:00
metaState.branchID = branchID
metaState.chainName = chainName
// 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)
emptyBlocks.height = Int32(height)
emptyBlocks.nonce = Int32(nonce)
_ = try darksideService.stageBlocksCreate(emptyBlocks).response.wait()
}
func stageTransaction(_ rawTransaction: RawTransaction, at height: BlockHeight) throws {
2021-09-23 06:26:41 -07:00
var transaction = rawTransaction
transaction.height = UInt64(height)
_ = try darksideService.stageTransactionsStream()
.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()
}
func getInfo() async throws -> LightWalletdInfo {
try await service.getInfo()
}
func blockRange(_ range: CompactBlockRange) -> AsyncThrowingStream<ZcashCompactBlock, Error> {
service.blockRange(range)
}
/// Darskside lightwalletd should do a fake submission, by sending over the tx, retrieving it and including it in a new block
func submit(spendTransaction: Data) async throws -> LightWalletServiceResponse {
try await service.submit(spendTransaction: spendTransaction)
}
func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched {
try await service.fetchTransaction(txId: txId)
}
}
2021-07-28 09:59:10 -07:00
2021-09-23 06:26:41 -07:00
enum DarksideWalletDConstants: NetworkConstants {
- [#679] Implementation of the File-system based block cache (#679) Closes https://github.com/zcash/ZcashLightClientKit/issues/697 Closes https://github.com/zcash/ZcashLightClientKit/issues/720 Closes https://github.com/zcash/ZcashLightClientKit/issues/587 Closes https://github.com/zcash/ZcashLightClientKit/issues/667 Closes https://github.com/zcash/ZcashLightClientKit/issues/443 Closes https://github.com/zcash/ZcashLightClientKit/issues/754 - [#790] Fix ShieldFundsTests Closes #790 Removes comments on `ShieldFundsTests` since those issues have been fixed Depends on zcash-light-client-ffi changes that adopt newer versions of librustzcash crates `zcash_primitives 0.10`, `zcash_client_backend 0.7`, `zcash_proofs 0.10`, `zcash_client_sqlite 0.5.0`. Also allows wallets to define a shielding_threshold and will set foundations to customize minimum confirmations for balances, spends and shielding operations. **Test Bootstrapping** - `ZcashCompactBlockDescriptor`: struct that holds functions to describe blocks as filenames and compare those filenames `ZcashCompactBlockDescriptor.live` has the actual implementation but it can be replaced by mocks if needed on Tests main implementations are held under `FSCompactBlockRepository.filenameDescription` and `FSCompactBlockRepository.filenameComparison` on a separate extention `DirectoryListingProviders` provide two default implementations of listing a directory deterministically. `FileManager` does not define a sorting and needs to be done in-memory by calling `.sorted()` on the resulting collection. If this is a big toll on performance it can be changed to a POSIX implementation but this is good for now. `ZcashCompactBlockDescriptor` adds a `height` helper function to turn a filename into the height of the block stored. Implemented `func latestHeight() throws -> BlockHeight ` that returns the blockheight by querying the cache directory in a sorted fashion and getting the last value and turning the filename into a `BlockHeight` Added `Meta` struct to ZcashCompactBlock. Tests implemented: - `filterBlockFiles` - `testClearTheCache` - `testLatestHeightEmptyCacheThrows` - `testLatestHeightEmptyCacheThrowsAsync` - `testRewindEmptyCacheDoesNothing` - `testRewindEmptyCacheDoesNothingAsync` - `testWhenBlockIsStoredItFollowsTheDescribedFormat` - `testWhenBlockIsStoredItFollowsTheFilenameConvention` - `testGetLatestHeight` - `testRewindDeletesTheRightBlocks` test - `testPerformanceExample` test. This isn't a real performance test because the API doesn't work with async/await yet adopts `shield_funds` shielding threshold parameter Implements `initBlockMetadataDb` and fix tests Renames dbCache parameter to `fsBlockDbRoot`. Builds but tests don't pass. Removes cacheDb uses from code. Testing utilities still persist. Added needed information in MIGRATING and CHANGELOG. Added helper to perform deletion of legacy db and creation a the new file system backed cache. Renames parameters and changes code where needed. Network Constants turned into `enum` with static methods. DeletelastDownloadedBlock helper from initializer Removes CompactBlockStorage and CompactBlockEntity. Implements `latestCachedBlockHeight` on rustbackend. *Replaces dependencies on ZcashRustWelding with `FSMetadataStore`* This allows the tests to not depend in a particular implementation of either the MockRustBackend of or ZcashRustBackend. Also provides a way to test errors properly and switch implementations of critical areas like `writeBlocks`.
2023-02-02 08:58:12 -08:00
static var defaultFsBlockDbRootName = "fs_cache"
2021-09-15 05:21:29 -07:00
static var saplingActivationHeight: BlockHeight {
2021-07-28 09:59:10 -07:00
663150
}
2021-09-15 05:21:29 -07:00
static var defaultDataDbName: String {
ZcashSDKMainnetConstants.defaultDataDbName
2021-07-28 09:59:10 -07:00
}
2021-09-15 05:21:29 -07:00
static var defaultCacheDbName: String {
ZcashSDKMainnetConstants.defaultCacheDbName
2021-07-28 09:59:10 -07:00
}
2021-09-15 05:21:29 -07:00
static var defaultPendingDbName: String {
ZcashSDKMainnetConstants.defaultPendingDbName
2021-07-28 09:59:10 -07:00
}
2021-09-15 05:21:29 -07:00
static var defaultDbNamePrefix: String {
ZcashSDKMainnetConstants.defaultDbNamePrefix
2021-07-28 09:59:10 -07:00
}
2021-09-15 05:21:29 -07:00
static var feeChangeHeight: BlockHeight {
ZcashSDKMainnetConstants.feeChangeHeight
2021-07-28 09:59:10 -07:00
}
}
2021-09-23 06:26:41 -07:00
2021-07-28 09:59:10 -07:00
class DarksideWalletDNetwork: ZcashNetwork {
var constants: NetworkConstants.Type = DarksideWalletDConstants.self
var networkType = NetworkType.mainnet
}