Skip to content

Commit

Permalink
Merge pull request #1393 from Electric-Coin-Company/feature-2.1.0
Browse files Browse the repository at this point in the history
Feature branch for SDK 2.1.0
  • Loading branch information
LukasKorba authored Mar 26, 2024
2 parents 6207cc9 + c3e6201 commit b183b10
Show file tree
Hide file tree
Showing 46 changed files with 482 additions and 469 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,29 @@ Possible errors:
- `ZcashError.rustProposeTransferFromURI`
- Other errors that `sentToAddress` can throw

## Removed

- `SDKSynchronizer.latestUTXOs`

## Checkpoints

Mainnet

````
Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/2430000.json
...
Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/2447500.json
````


Testnet

````
Sources/ZcashLightClientKit/Resources/checkpoints/testnet/2750000.json
...
Sources/ZcashLightClientKit/Resources/checkpoints/testnet/2770000.json
````

# 2.0.11 - 2024-03-08

## Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
"state" : {
"revision" : "7c801be1f445402a433b32835a50d832e8a50437",
"version" : "0.6.0"
"revision" : "c7e5158edf5e62af15492d30237163b78af35ce9",
"version" : "0.7.1"
}
}
],
Expand Down
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
"state" : {
"revision" : "7c801be1f445402a433b32835a50d832e8a50437",
"version" : "0.6.0"
"revision" : "c7e5158edf5e62af15492d30237163b78af35ce9",
"version" : "0.7.1"
}
}
],
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.19.1"),
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1"),
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", exact: "0.6.0")
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", exact: "0.7.1")
],
targets: [
.target(
Expand Down
31 changes: 9 additions & 22 deletions Sources/ZcashLightClientKit/Block/CompactBlockProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ actor CompactBlockProcessor {
private let configProvider: ConfigProvider
private var afterSyncHooksManager = AfterSyncHooksManager()

private let accountRepository: AccountRepository
var blockDownloaderService: BlockDownloaderService
private var latestBlocksDataProvider: LatestBlocksDataProvider
private let logger: Logger
Expand Down Expand Up @@ -142,20 +141,6 @@ actor CompactBlockProcessor {
}
}

/// Initializes a CompactBlockProcessor instance
/// - Parameters:
/// - service: concrete implementation of `LightWalletService` protocol
/// - storage: concrete implementation of `CompactBlockRepository` protocol
/// - backend: a class that complies to `ZcashRustBackendWelding`
/// - config: `Configuration` struct for this processor
init(container: DIContainer, config: Configuration) {
self.init(
container: container,
config: config,
accountRepository: AccountRepositoryBuilder.build(dataDbURL: config.dataDb, readOnly: true, logger: container.resolve(Logger.self))
)
}

/// Initializes a CompactBlockProcessor instance from an Initialized object
/// - Parameters:
/// - initializer: an instance that complies to CompactBlockDownloading protocol
Expand All @@ -171,20 +156,23 @@ actor CompactBlockProcessor {
saplingParamsSourceURL: initializer.saplingParamsSourceURL,
walletBirthdayProvider: walletBirthdayProvider,
network: initializer.network
),
accountRepository: initializer.accountRepository
)
)
}

/// Initializes a CompactBlockProcessor instance
/// - Parameters:
/// - service: concrete implementation of `LightWalletService` protocol
/// - storage: concrete implementation of `CompactBlockRepository` protocol
/// - backend: a class that complies to `ZcashRustBackendWelding`
/// - config: `Configuration` struct for this processor
init(
container: DIContainer,
config: Configuration,
accountRepository: AccountRepository
config: Configuration
) {
Dependencies.setupCompactBlockProcessor(
in: container,
config: config,
accountRepository: accountRepository
config: config
)

let configProvider = ConfigProvider(config: config)
Expand All @@ -200,7 +188,6 @@ actor CompactBlockProcessor {
self.storage = container.resolve(CompactBlockRepository.self)
self.config = config
self.transactionRepository = container.resolve(TransactionRepository.self)
self.accountRepository = accountRepository
self.fileManager = container.resolve(ZcashFileManager.self)
self.configProvider = configProvider
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ protocol UTXOFetcher {
}

struct UTXOFetcherImpl {
let accountRepository: AccountRepository
let blockDownloaderService: BlockDownloaderService
let config: UTXOFetcherConfig
let rustBackend: ZcashRustBackendWelding
Expand All @@ -37,8 +36,7 @@ extension UTXOFetcherImpl: UTXOFetcher {
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]) {
try Task.checkCancellation()

let accounts = try accountRepository.getAll()
.map { $0.account }
let accounts = try await rustBackend.listAccounts()

var tAddresses: [TransparentAddress] = []
for account in accounts {
Expand Down
5 changes: 4 additions & 1 deletion Sources/ZcashLightClientKit/Block/Scan/BlockScanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ protocol BlockScanner {
struct BlockScannerImpl {
let config: BlockScannerConfig
let rustBackend: ZcashRustBackendWelding
let service: LightWalletService
let transactionRepository: TransactionRepository
let metrics: SDKMetrics
let logger: Logger
Expand Down Expand Up @@ -56,7 +57,9 @@ extension BlockScannerImpl: BlockScanner {
let scanSummary: ScanSummary
let scanStartTime = Date()
do {
scanSummary = try await self.rustBackend.scanBlocks(fromHeight: Int32(startHeight), limit: batchSize)
let fromState = try await service.getTreeState(BlockID(height: startHeight - 1))

scanSummary = try await self.rustBackend.scanBlocks(fromHeight: Int32(startHeight), fromState: fromState, limit: batchSize)
} catch {
logger.debug("block scanning failed with error: \(String(describing: error))")
throw error
Expand Down
155 changes: 0 additions & 155 deletions Sources/ZcashLightClientKit/DAO/UnspentTransactionOutputDao.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,12 @@
import Foundation

struct UTXO: Decodable, Encodable {
enum CodingKeys: String, CodingKey {
case id = "id_utxo"
case address
case prevoutTxId = "prevout_txid"
case prevoutIndex = "prevout_idx"
case script
case valueZat = "value_zat"
case height
case spentInTx = "spent_in_tx"
}

let id: Int?
let address: String
var prevoutTxId: Data
var prevoutIndex: Int
let script: Data
let valueZat: Int
let height: Int
let spentInTx: Int?
}

extension UTXO: UnspentTransactionOutputEntity {
Expand All @@ -48,145 +35,3 @@ extension UTXO: UnspentTransactionOutputEntity {
}
}
}

extension UnspentTransactionOutputEntity {
/**
As UTXO, with id and spentIntTx set to __nil__
*/
func asUTXO() -> UTXO {
UTXO(
id: nil,
address: address,
prevoutTxId: txid,
prevoutIndex: index,
script: script,
valueZat: valueZat,
height: height,
spentInTx: nil
)
}
}
import SQLite
class UnspentTransactionOutputSQLDAO: UnspentTransactionOutputRepository {
enum TableColumns {
static let id = Expression<Int>("id_utxo")
static let address = Expression<String>("address")
static let txid = Expression<Blob>("prevout_txid")
static let index = Expression<Int>("prevout_idx")
static let script = Expression<Blob>("script")
static let valueZat = Expression<Int>("value_zat")
static let height = Expression<Int>("height")
static let spentInTx = Expression<Int?>("spent_in_tx")
}

let table = Table("utxos")

let dbProvider: ConnectionProvider

init(dbProvider: ConnectionProvider) {
self.dbProvider = dbProvider
}

/// - Throws: `unspentTransactionOutputDAOCreateTable` if creation table fails.
func initialise() async throws {
try await createTableIfNeeded()
}

private func createTableIfNeeded() async throws {
let stringStatement =
"""
CREATE TABLE IF NOT EXISTS utxos (
id_utxo INTEGER PRIMARY KEY,
address TEXT NOT NULL,
prevout_txid BLOB NOT NULL,
prevout_idx INTEGER NOT NULL,
script BLOB NOT NULL,
value_zat INTEGER NOT NULL,
height INTEGER NOT NULL,
spent_in_tx INTEGER,
FOREIGN KEY (spent_in_tx) REFERENCES transactions(id_tx),
CONSTRAINT tx_outpoint UNIQUE (prevout_txid, prevout_idx)
)
"""
do {
globalDBLock.lock()
defer { globalDBLock.unlock() }

try dbProvider.connection().run(stringStatement)
} catch {
throw ZcashError.unspentTransactionOutputDAOCreateTable(error)
}
}

/// - Throws: `unspentTransactionOutputDAOStore` if sqlite query fails.
func store(utxos: [UnspentTransactionOutputEntity]) async throws {
do {
globalDBLock.lock()
defer { globalDBLock.unlock() }

let db = try dbProvider.connection()
try db.transaction {
for utxo in utxos.map({ $0 as? UTXO ?? $0.asUTXO() }) {
try db.run(table.insert(utxo))
}
}
} catch {
throw ZcashError.unspentTransactionOutputDAOStore(error)
}
}

/// - Throws: `unspentTransactionOutputDAOClearAll` if sqlite query fails.
func clearAll(address: String?) async throws {
do {
globalDBLock.lock()
defer { globalDBLock.unlock() }

if let tAddr = address {
try dbProvider.connection().run(table.filter(TableColumns.address == tAddr).delete())
} else {
try dbProvider.connection().run(table.delete())
}
} catch {
throw ZcashError.unspentTransactionOutputDAOClearAll(error)
}
}

/// - Throws:
/// - `unspentTransactionOutputDAOClearAll` if the data fetched from the DB can't be decoded to `UTXO` object.
/// - `unspentTransactionOutputDAOGetAll` if sqlite query fails.
func getAll(address: String?) async throws -> [UnspentTransactionOutputEntity] {
do {
if let tAddress = address {
let allTxs: [UTXO] = try dbProvider.connection()
.prepare(table.filter(TableColumns.address == tAddress))
.map { row in
do {
return try row.decode()
} catch {
throw ZcashError.unspentTransactionOutputDAOGetAllCantDecode(error)
}
}
return allTxs
} else {
let allTxs: [UTXO] = try dbProvider.connection()
.prepare(table)
.map { row in
try row.decode()
}
return allTxs
}
} catch {
if let error = error as? ZcashError {
throw error
} else {
throw ZcashError.unspentTransactionOutputDAOGetAll(error)
}
}
}
}

enum UTXORepositoryBuilder {
static func build(initializer: Initializer) -> UnspentTransactionOutputRepository {
return UnspentTransactionOutputSQLDAO(dbProvider: SimpleConnectionProvider(path: initializer.dataDbURL.path))
}
}
Loading

0 comments on commit b183b10

Please sign in to comment.