Compare commits
No commits in common. "8fa86ff37f85c74bd6585d59f38db2593e11d802" and "d8f389b8dae9ae34b2ae311b4b3a548191ba37d8" have entirely different histories.
8fa86ff37f
...
d8f389b8da
|
@ -6,11 +6,6 @@ and this library adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
# Unreleased
|
||||
|
||||
# 2.1.3 - 2024-03-28
|
||||
|
||||
## Fixed
|
||||
- Orchard subtree roots are now fetched alongside Sapling subtree roots.
|
||||
|
||||
# 2.1.2 - 2024-03-27
|
||||
|
||||
## Fixed
|
||||
|
|
|
@ -176,8 +176,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
|
||||
"state" : {
|
||||
"revision" : "e2d8763f3a963fb0026b6160af2d211b527453cd",
|
||||
"version" : "0.7.4"
|
||||
"revision" : "8838b4f0ee4193349fed09f0248220d4ada271fc",
|
||||
"version" : "0.7.3"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -122,8 +122,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
|
||||
"state" : {
|
||||
"revision" : "e2d8763f3a963fb0026b6160af2d211b527453cd",
|
||||
"version" : "0.7.4"
|
||||
"revision" : "c7e5158edf5e62af15492d30237163b78af35ce9",
|
||||
"version" : "0.7.1"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -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.7.4")
|
||||
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", exact: "0.7.3")
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
|
|
@ -31,55 +31,26 @@ extension UpdateSubtreeRootsAction: Action {
|
|||
logger.debug("Attempt to get subtree roots, this may fail because lightwalletd may not support Spend before Sync.")
|
||||
let stream = service.getSubtreeRoots(request)
|
||||
|
||||
var saplingRoots: [SubtreeRoot] = []
|
||||
var roots: [SubtreeRoot] = []
|
||||
|
||||
do {
|
||||
for try await subtreeRoot in stream {
|
||||
saplingRoots.append(subtreeRoot)
|
||||
roots.append(subtreeRoot)
|
||||
}
|
||||
} catch ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut) {
|
||||
throw ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut)
|
||||
}
|
||||
|
||||
logger.debug("Sapling tree has \(saplingRoots.count) subtrees")
|
||||
logger.debug("Sapling tree has \(roots.count) subtrees")
|
||||
do {
|
||||
try await rustBackend.putSaplingSubtreeRoots(startIndex: UInt64(request.startIndex), roots: saplingRoots)
|
||||
try await rustBackend.putSaplingSubtreeRoots(startIndex: UInt64(request.startIndex), roots: roots)
|
||||
|
||||
await context.update(state: .updateChainTip)
|
||||
} catch {
|
||||
logger.debug("putSaplingSubtreeRoots failed with error \(error.localizedDescription)")
|
||||
throw ZcashError.compactBlockProcessorPutSaplingSubtreeRoots(error)
|
||||
}
|
||||
|
||||
if !saplingRoots.isEmpty {
|
||||
logger.debug("Found Sapling subtree roots, SbS supported, fetching Orchard subtree roots")
|
||||
|
||||
var orchardRequest = GetSubtreeRootsArg()
|
||||
orchardRequest.shieldedProtocol = .orchard
|
||||
|
||||
let stream = service.getSubtreeRoots(orchardRequest)
|
||||
|
||||
var orchardRoots: [SubtreeRoot] = []
|
||||
|
||||
do {
|
||||
for try await subtreeRoot in stream {
|
||||
orchardRoots.append(subtreeRoot)
|
||||
}
|
||||
} catch ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut) {
|
||||
throw ZcashError.serviceSubtreeRootsStreamFailed(LightWalletServiceError.timeOut)
|
||||
}
|
||||
|
||||
logger.debug("Orchard tree has \(orchardRoots.count) subtrees")
|
||||
do {
|
||||
try await rustBackend.putOrchardSubtreeRoots(startIndex: UInt64(orchardRequest.startIndex), roots: orchardRoots)
|
||||
|
||||
await context.update(state: .updateChainTip)
|
||||
} catch {
|
||||
logger.debug("putOrchardSubtreeRoots failed with error \(error.localizedDescription)")
|
||||
throw ZcashError.compactBlockProcessorPutOrchardSubtreeRoots(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
|
|
|
@ -333,15 +333,6 @@ public enum ZcashError: Equatable, Error {
|
|||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// ZRUST0059
|
||||
case rustIsSeedRelevantToAnyDerivedAccount(_ rustError: String)
|
||||
/// Unable to allocate memory required to write blocks when calling ZcashRustBackend.putOrchardSubtreeRoots
|
||||
/// sourcery: code="ZRUST0060"
|
||||
/// ZRUST0060
|
||||
case rustPutOrchardSubtreeRootsAllocationProblem
|
||||
/// Error from rust layer when calling ZcashRustBackend.putOrchardSubtreeRoots
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// sourcery: code="ZRUST0061"
|
||||
/// ZRUST0061
|
||||
case rustPutOrchardSubtreeRoots(_ rustError: String)
|
||||
/// SQLite query failed when fetching all accounts from the database.
|
||||
/// - `sqliteError` is error produced by SQLite library.
|
||||
/// ZADAO0001
|
||||
|
@ -587,9 +578,6 @@ public enum ZcashError: Equatable, Error {
|
|||
/// Getting the `supportedSyncAlgorithm` failed but it's supposed to always provide some value.
|
||||
/// ZCBPEO0021
|
||||
case compactBlockProcessorSupportedSyncAlgorithm
|
||||
/// Put Orchard subtree roots to the DB failed.
|
||||
/// ZCBPEO0022
|
||||
case compactBlockProcessorPutOrchardSubtreeRoots(_ error: Error)
|
||||
/// The synchronizer is unprepared.
|
||||
/// ZSYNCO0001
|
||||
case synchronizerNotPrepared
|
||||
|
@ -703,8 +691,6 @@ public enum ZcashError: Equatable, Error {
|
|||
case .rustProposeTransferFromURI: return "Error from rust layer when calling ZcashRustBackend."
|
||||
case .rustListAccounts: return "Error from rust layer when calling ZcashRustBackend."
|
||||
case .rustIsSeedRelevantToAnyDerivedAccount: return "Error from rust layer when calling ZcashRustBackend.rustIsSeedRelevantToAnyDerivedAccount"
|
||||
case .rustPutOrchardSubtreeRootsAllocationProblem: return "Unable to allocate memory required to write blocks when calling ZcashRustBackend.putOrchardSubtreeRoots"
|
||||
case .rustPutOrchardSubtreeRoots: return "Error from rust layer when calling ZcashRustBackend.putOrchardSubtreeRoots"
|
||||
case .accountDAOGetAll: return "SQLite query failed when fetching all accounts from the database."
|
||||
case .accountDAOGetAllCantDecode: return "Fetched accounts from SQLite but can't decode them."
|
||||
case .accountDAOFindBy: return "SQLite query failed when seaching for accounts in the database."
|
||||
|
@ -783,7 +769,6 @@ public enum ZcashError: Equatable, Error {
|
|||
case .compactBlockProcessorPutSaplingSubtreeRoots: return "Put sapling subtree roots to the DB failed."
|
||||
case .compactBlockProcessorLastScannedHeight: return "Getting the `lastScannedHeight` failed but it's supposed to always provide some value."
|
||||
case .compactBlockProcessorSupportedSyncAlgorithm: return "Getting the `supportedSyncAlgorithm` failed but it's supposed to always provide some value."
|
||||
case .compactBlockProcessorPutOrchardSubtreeRoots: return "Put Orchard 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."
|
||||
|
@ -883,8 +868,6 @@ public enum ZcashError: Equatable, Error {
|
|||
case .rustProposeTransferFromURI: return .rustProposeTransferFromURI
|
||||
case .rustListAccounts: return .rustListAccounts
|
||||
case .rustIsSeedRelevantToAnyDerivedAccount: return .rustIsSeedRelevantToAnyDerivedAccount
|
||||
case .rustPutOrchardSubtreeRootsAllocationProblem: return .rustPutOrchardSubtreeRootsAllocationProblem
|
||||
case .rustPutOrchardSubtreeRoots: return .rustPutOrchardSubtreeRoots
|
||||
case .accountDAOGetAll: return .accountDAOGetAll
|
||||
case .accountDAOGetAllCantDecode: return .accountDAOGetAllCantDecode
|
||||
case .accountDAOFindBy: return .accountDAOFindBy
|
||||
|
@ -963,7 +946,6 @@ public enum ZcashError: Equatable, Error {
|
|||
case .compactBlockProcessorPutSaplingSubtreeRoots: return .compactBlockProcessorPutSaplingSubtreeRoots
|
||||
case .compactBlockProcessorLastScannedHeight: return .compactBlockProcessorLastScannedHeight
|
||||
case .compactBlockProcessorSupportedSyncAlgorithm: return .compactBlockProcessorSupportedSyncAlgorithm
|
||||
case .compactBlockProcessorPutOrchardSubtreeRoots: return .compactBlockProcessorPutOrchardSubtreeRoots
|
||||
case .synchronizerNotPrepared: return .synchronizerNotPrepared
|
||||
case .synchronizerSendMemoToTransparentAddress: return .synchronizerSendMemoToTransparentAddress
|
||||
case .synchronizerShieldFundsInsuficientTransparentFunds: return .synchronizerShieldFundsInsuficientTransparentFunds
|
||||
|
|
|
@ -181,10 +181,6 @@ public enum ZcashErrorCode: String {
|
|||
case rustListAccounts = "ZRUST0058"
|
||||
/// Error from rust layer when calling ZcashRustBackend.rustIsSeedRelevantToAnyDerivedAccount
|
||||
case rustIsSeedRelevantToAnyDerivedAccount = "ZRUST0059"
|
||||
/// Unable to allocate memory required to write blocks when calling ZcashRustBackend.putOrchardSubtreeRoots
|
||||
case rustPutOrchardSubtreeRootsAllocationProblem = "ZRUST0060"
|
||||
/// Error from rust layer when calling ZcashRustBackend.putOrchardSubtreeRoots
|
||||
case rustPutOrchardSubtreeRoots = "ZRUST0061"
|
||||
/// SQLite query failed when fetching all accounts from the database.
|
||||
case accountDAOGetAll = "ZADAO0001"
|
||||
/// Fetched accounts from SQLite but can't decode them.
|
||||
|
@ -341,8 +337,6 @@ public enum ZcashErrorCode: String {
|
|||
case compactBlockProcessorLastScannedHeight = "ZCBPEO0020"
|
||||
/// Getting the `supportedSyncAlgorithm` failed but it's supposed to always provide some value.
|
||||
case compactBlockProcessorSupportedSyncAlgorithm = "ZCBPEO0021"
|
||||
/// Put Orchard subtree roots to the DB failed.
|
||||
case compactBlockProcessorPutOrchardSubtreeRoots = "ZCBPEO0022"
|
||||
/// The synchronizer is unprepared.
|
||||
case synchronizerNotPrepared = "ZSYNCO0001"
|
||||
/// Memos can't be sent to transparent addresses.
|
||||
|
|
|
@ -360,13 +360,6 @@ enum ZcashErrorDefinition {
|
|||
/// - `rustError` contains error generated by the rust layer.
|
||||
// sourcery: code="ZRUST0059"
|
||||
case rustIsSeedRelevantToAnyDerivedAccount(_ rustError: String)
|
||||
/// Unable to allocate memory required to write blocks when calling ZcashRustBackend.putOrchardSubtreeRoots
|
||||
/// sourcery: code="ZRUST0060"
|
||||
case rustPutOrchardSubtreeRootsAllocationProblem
|
||||
/// Error from rust layer when calling ZcashRustBackend.putOrchardSubtreeRoots
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// sourcery: code="ZRUST0061"
|
||||
case rustPutOrchardSubtreeRoots(_ rustError: String)
|
||||
|
||||
// MARK: - Account DAO
|
||||
|
||||
|
@ -661,9 +654,6 @@ enum ZcashErrorDefinition {
|
|||
/// Getting the `supportedSyncAlgorithm` failed but it's supposed to always provide some value.
|
||||
// sourcery: code="ZCBPEO0021"
|
||||
case compactBlockProcessorSupportedSyncAlgorithm
|
||||
/// Put Orchard subtree roots to the DB failed.
|
||||
// sourcery: code="ZCBPEO0022"
|
||||
case compactBlockProcessorPutOrchardSubtreeRoots(_ error: Error)
|
||||
|
||||
// MARK: - SDKSynchronizer
|
||||
|
||||
|
|
|
@ -571,64 +571,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
func putOrchardSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws {
|
||||
var ffiSubtreeRootsVec: [FfiSubtreeRoot] = []
|
||||
|
||||
for root in roots {
|
||||
let hashPtr = UnsafeMutablePointer<UInt8>.allocate(capacity: root.rootHash.count)
|
||||
|
||||
let contiguousHashBytes = ContiguousArray(root.rootHash.bytes)
|
||||
|
||||
let result: Void? = contiguousHashBytes.withContiguousStorageIfAvailable { hashBytesPtr in
|
||||
// swiftlint:disable:next force_unwrapping
|
||||
hashPtr.initialize(from: hashBytesPtr.baseAddress!, count: hashBytesPtr.count)
|
||||
}
|
||||
|
||||
guard result != nil else {
|
||||
defer {
|
||||
hashPtr.deallocate()
|
||||
ffiSubtreeRootsVec.deallocateElements()
|
||||
}
|
||||
throw ZcashError.rustPutOrchardSubtreeRootsAllocationProblem
|
||||
}
|
||||
|
||||
ffiSubtreeRootsVec.append(
|
||||
FfiSubtreeRoot(
|
||||
root_hash_ptr: hashPtr,
|
||||
root_hash_ptr_len: UInt(contiguousHashBytes.count),
|
||||
completing_block_height: UInt32(root.completingBlockHeight)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
var contiguousFfiRoots = ContiguousArray(ffiSubtreeRootsVec)
|
||||
|
||||
let len = UInt(contiguousFfiRoots.count)
|
||||
|
||||
let rootsPtr = UnsafeMutablePointer<FfiSubtreeRoots>.allocate(capacity: 1)
|
||||
|
||||
defer {
|
||||
ffiSubtreeRootsVec.deallocateElements()
|
||||
rootsPtr.deallocate()
|
||||
}
|
||||
|
||||
try contiguousFfiRoots.withContiguousMutableStorageIfAvailable { ptr in
|
||||
var roots = FfiSubtreeRoots()
|
||||
roots.ptr = ptr.baseAddress
|
||||
roots.len = len
|
||||
|
||||
rootsPtr.initialize(to: roots)
|
||||
|
||||
globalDBLock.lock()
|
||||
let res = zcashlc_put_orchard_subtree_roots(dbData.0, dbData.1, startIndex, rootsPtr, networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard res else {
|
||||
throw ZcashError.rustPutOrchardSubtreeRoots(lastErrorMessage(fallback: "`putOrchardSubtreeRoots` failed with unknown error"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateChainTip(height: Int32) async throws {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_update_chain_tip(dbData.0, dbData.1, height, networkType.networkId)
|
||||
|
|
|
@ -133,8 +133,6 @@ protocol ZcashRustBackendWelding {
|
|||
|
||||
func putSaplingSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws
|
||||
|
||||
func putOrchardSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws
|
||||
|
||||
/// Updates the wallet's view of the blockchain.
|
||||
///
|
||||
/// This method is used to provide the wallet with information about the state of the blockchain,
|
||||
|
|
|
@ -70,7 +70,6 @@ final class UpdateSubtreeRootsActionTests: ZcashTestCase {
|
|||
}
|
||||
}
|
||||
await tupple.rustBackendMock.setPutSaplingSubtreeRootsStartIndexRootsClosure({ _, _ in })
|
||||
await tupple.rustBackendMock.setPutOrchardSubtreeRootsStartIndexRootsClosure({ _, _ in })
|
||||
|
||||
do {
|
||||
let context = ActionContextMock.default()
|
||||
|
@ -78,13 +77,13 @@ final class UpdateSubtreeRootsActionTests: ZcashTestCase {
|
|||
let nextContext = try await updateSubtreeRootsActionAction.run(with: context) { _ in }
|
||||
|
||||
let acResult = nextContext.checkStateIs(.updateChainTip)
|
||||
XCTAssertTrue(acResult == .called(2), "Check of state failed with '\(acResult)'")
|
||||
XCTAssertTrue(acResult == .true, "Check of state failed with '\(acResult)'")
|
||||
} catch {
|
||||
XCTFail("testUpdateSubtreeRootsAction_RootsAvailablePutRootsSuccess is not expected to fail. \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func testUpdateSubtreeRootsAction_RootsAvailablePutSaplingRootsFailure() async throws {
|
||||
func testUpdateSubtreeRootsAction_RootsAvailablePutRootsFailure() async throws {
|
||||
let loggerMock = LoggerMock()
|
||||
|
||||
loggerMock.infoFileFunctionLineClosure = { _, _, _, _ in }
|
||||
|
@ -99,7 +98,6 @@ final class UpdateSubtreeRootsActionTests: ZcashTestCase {
|
|||
}
|
||||
}
|
||||
await tupple.rustBackendMock.setPutSaplingSubtreeRootsStartIndexRootsThrowableError("putSaplingFailed")
|
||||
await tupple.rustBackendMock.setPutOrchardSubtreeRootsStartIndexRootsClosure({ _, _ in })
|
||||
|
||||
do {
|
||||
let context = ActionContextMock.default()
|
||||
|
@ -113,37 +111,7 @@ final class UpdateSubtreeRootsActionTests: ZcashTestCase {
|
|||
XCTFail("testUpdateSubtreeRootsAction_RootsAvailablePutRootsFailure is not expected to fail. \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func testUpdateSubtreeRootsAction_RootsAvailablePutOrchardRootsFailure() async throws {
|
||||
let loggerMock = LoggerMock()
|
||||
|
||||
loggerMock.infoFileFunctionLineClosure = { _, _, _, _ in }
|
||||
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
|
||||
|
||||
let tupple = setupAction(loggerMock)
|
||||
let updateSubtreeRootsActionAction = tupple.action
|
||||
tupple.serviceMock.getSubtreeRootsClosure = { _ in
|
||||
AsyncThrowingStream { continuation in
|
||||
continuation.yield(SubtreeRoot())
|
||||
continuation.finish()
|
||||
}
|
||||
}
|
||||
await tupple.rustBackendMock.setPutSaplingSubtreeRootsStartIndexRootsClosure({ _, _ in })
|
||||
await tupple.rustBackendMock.setPutOrchardSubtreeRootsStartIndexRootsThrowableError("putOrchardFailed")
|
||||
|
||||
do {
|
||||
let context = ActionContextMock.default()
|
||||
|
||||
_ = try await updateSubtreeRootsActionAction.run(with: context) { _ in }
|
||||
|
||||
XCTFail("updateSubtreeRootsActionAction.run(with:) is excpected to fail but didn't.")
|
||||
} catch ZcashError.compactBlockProcessorPutOrchardSubtreeRoots {
|
||||
// this is expected result of this test
|
||||
} catch {
|
||||
XCTFail("testUpdateSubtreeRootsAction_RootsAvailablePutRootsFailure is not expected to fail. \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// swiftlint:disable large_tuple
|
||||
private func setupAction(
|
||||
_ loggerMock: LoggerMock = LoggerMock()
|
||||
|
|
|
@ -2722,31 +2722,6 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
try await putSaplingSubtreeRootsStartIndexRootsClosure!(startIndex, roots)
|
||||
}
|
||||
|
||||
// MARK: - putOrchardSubtreeRoots
|
||||
|
||||
var putOrchardSubtreeRootsStartIndexRootsThrowableError: Error?
|
||||
func setPutOrchardSubtreeRootsStartIndexRootsThrowableError(_ param: Error?) async {
|
||||
putOrchardSubtreeRootsStartIndexRootsThrowableError = param
|
||||
}
|
||||
var putOrchardSubtreeRootsStartIndexRootsCallsCount = 0
|
||||
var putOrchardSubtreeRootsStartIndexRootsCalled: Bool {
|
||||
return putOrchardSubtreeRootsStartIndexRootsCallsCount > 0
|
||||
}
|
||||
var putOrchardSubtreeRootsStartIndexRootsReceivedArguments: (startIndex: UInt64, roots: [SubtreeRoot])?
|
||||
var putOrchardSubtreeRootsStartIndexRootsClosure: ((UInt64, [SubtreeRoot]) async throws -> Void)?
|
||||
func setPutOrchardSubtreeRootsStartIndexRootsClosure(_ param: ((UInt64, [SubtreeRoot]) async throws -> Void)?) async {
|
||||
putOrchardSubtreeRootsStartIndexRootsClosure = param
|
||||
}
|
||||
|
||||
func putOrchardSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws {
|
||||
if let error = putOrchardSubtreeRootsStartIndexRootsThrowableError {
|
||||
throw error
|
||||
}
|
||||
putOrchardSubtreeRootsStartIndexRootsCallsCount += 1
|
||||
putOrchardSubtreeRootsStartIndexRootsReceivedArguments = (startIndex: startIndex, roots: roots)
|
||||
try await putOrchardSubtreeRootsStartIndexRootsClosure!(startIndex, roots)
|
||||
}
|
||||
|
||||
// MARK: - updateChainTip
|
||||
|
||||
var updateChainTipHeightThrowableError: Error?
|
||||
|
|
Loading…
Reference in New Issue