Skip to content

Commit

Permalink
Update to preview zcash-light-client-ffi release fix for with note …
Browse files Browse the repository at this point in the history
…commitment tree corruption.
  • Loading branch information
nuttycom committed Sep 28, 2024
1 parent af9383b commit c11c8b0
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,9 @@
{
"identity" : "zcash-light-client-ffi",
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
"location" : "https://github.com/Electric-Coin-Company/zcash-light-client-ffi",
"state" : {
"revision" : "8ed5b08d59ff5e7e11240be29b084dedbdf2f268",
"version" : "0.9.1"
"revision" : "a61f82942c1dad9161f346123f292a93081c7e36"
}
}
],
Expand Down
25 changes: 12 additions & 13 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/grpc/grpc-swift.git",
"state" : {
"revision" : "6ade19f0b57f5fc436dfecfced83f3c84d1095b9",
"version" : "1.21.0"
"revision" : "07123ed731671e800ab8d641006613612e954746",
"version" : "1.23.1"
}
},
{
"identity" : "sqlite.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/stephencelis/SQLite.swift.git",
"state" : {
"revision" : "7a2e3cd27de56f6d396e84f63beefd0267b55ccb",
"version" : "0.14.1"
"revision" : "a95fc6df17d108bd99210db5e8a9bac90fe984b8",
"version" : "0.15.3"
}
},
{
Expand Down Expand Up @@ -59,8 +59,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "635b2589494c97e48c62514bc8b37ced762e0a62",
"version" : "2.63.0"
"revision" : "1b33db2dea6a64d5b619b9e888175133c6d7f410",
"version" : "2.73.0"
}
},
{
Expand All @@ -77,8 +77,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "0904bf0feb5122b7e5c3f15db7df0eabe623dd87",
"version" : "1.30.0"
"revision" : "b5f7062b60e4add1e8c343ba4eb8da2e324b3a94",
"version" : "1.34.0"
}
},
{
Expand All @@ -104,8 +104,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "65e8f29b2d63c4e38e736b25c27b83e012159be8",
"version" : "1.25.2"
"revision" : "edb6ed4919f7756157fe02f2552b7e3850a538e5",
"version" : "1.28.1"
}
},
{
Expand All @@ -120,10 +120,9 @@
{
"identity" : "zcash-light-client-ffi",
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
"location" : "https://github.com/Electric-Coin-Company/zcash-light-client-ffi",
"state" : {
"revision" : "8ed5b08d59ff5e7e11240be29b084dedbdf2f268",
"version" : "0.9.1"
"revision" : "a61f82942c1dad9161f346123f292a93081c7e36"
}
}
],
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.23.0"),
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.3"),
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", exact: "0.9.1")
.package(url: "https://github.com/Electric-Coin-Company/zcash-light-client-ffi", revision: "a61f82942c1dad9161f346123f292a93081c7e36")
],
targets: [
.target(
Expand Down
20 changes: 17 additions & 3 deletions Sources/ZcashLightClientKit/Block/Actions/RewindAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,28 @@ extension RewindAction: Action {
var removeBlocksCacheWhenFailed: Bool { false }

func run(with context: ActionContext, didUpdate: @escaping (CompactBlockProcessor.Event) async -> Void) async throws -> ActionContext {
guard let rewindHeight = await context.requestedRewindHeight else {
guard let requestedRewindHeight = await context.requestedRewindHeight else {
return await update(context: context)
}
var rewindHeight = BlockHeight(requestedRewindHeight)

logger.debug("Executing rewind.")
let rewindResult = try await rustBackend.rewindToHeight(height: rewindHeight)
switch rewindResult {
case let .success(height):
rewindHeight = height
case let .requestedHeightTooLow(safeHeight):
let retryResult = try await rustBackend.rewindToHeight(height: safeHeight)
switch retryResult {
case let .success(height):
rewindHeight = height
default:
throw ZcashError.rustRewindToHeight(Int32(safeHeight), lastErrorMessage(fallback: "`rewindToHeight` unable to rewind"))
}
}

await downloader.rewind(latestDownloadedBlockHeight: rewindHeight)
try await rustBackend.rewindToHeight(height: Int32(rewindHeight))


// clear cache
try await downloaderService.rewind(to: rewindHeight)

Expand Down
30 changes: 15 additions & 15 deletions Sources/ZcashLightClientKit/Block/CompactBlockProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -320,22 +320,22 @@ extension CompactBlockProcessor {
private func doRewind(context: AfterSyncHooksManager.RewindContext) async throws {
logger.debug("Executing rewind.")
let lastDownloaded = await latestBlocksDataProvider.maxScannedHeight
let height = Int32(context.height ?? lastDownloaded)

let nearestHeight: Int32
do {
nearestHeight = try await rustBackend.getNearestRewindHeight(height: height)
} catch {
await failure(error)
return await context.completion(.failure(error))
}

// FIXME: [#719] this should be done on the rust layer, https://github.com/zcash/ZcashLightClientKit/issues/719
let rewindHeight = max(Int32(nearestHeight - 1), Int32(config.walletBirthday))

var rewindHeight = BlockHeight(Int32(context.height ?? lastDownloaded) - 10)
do {
try await rewindDownloadBlockAction(to: BlockHeight(rewindHeight))
try await rustBackend.rewindToHeight(height: rewindHeight)
let rewindResult = try await rustBackend.rewindToHeight(height: rewindHeight)
switch rewindResult {
case let .success(height):
rewindHeight = height
case let .requestedHeightTooLow(safeHeight):
let retryResult = try await rustBackend.rewindToHeight(height: safeHeight)
switch retryResult {
case let .success(height):
rewindHeight = height
default:
throw ZcashError.rustRewindToHeight(Int32(safeHeight), lastErrorMessage(fallback: "`rewindToHeight` unable to rewind"))
}
}
try await rewindDownloadBlockAction(to: rewindHeight)
} catch {
await failure(error)
return await context.completion(.failure(error))
Expand Down
31 changes: 10 additions & 21 deletions Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift
Original file line number Diff line number Diff line change
Expand Up @@ -243,22 +243,6 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
return UnifiedAddress(validatedEncoding: address, networkType: networkType)
}

@DBActor
func getNearestRewindHeight(height: Int32) async throws -> Int32 {
let result = zcashlc_get_nearest_rewind_height(
dbData.0,
dbData.1,
height,
networkType.networkId
)

guard result > 0 else {
throw ZcashError.rustGetNearestRewindHeight(lastErrorMessage(fallback: "`getNearestRewindHeight` failed with unknown error"))
}

return result
}

@DBActor
func getNextAvailableAddress(account: Int32) async throws -> UnifiedAddress {
let addressCStr = zcashlc_get_next_available_address(
Expand Down Expand Up @@ -501,11 +485,16 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
}

@DBActor
func rewindToHeight(height: Int32) async throws {
let result = zcashlc_rewind_to_height(dbData.0, dbData.1, height, networkType.networkId)

guard result else {
throw ZcashError.rustRewindToHeight(height, lastErrorMessage(fallback: "`rewindToHeight` failed with unknown error"))
func rewindToHeight(height: BlockHeight) async throws -> RewindResult {
var safeRewindHeight: UInt32 = 0
let result = zcashlc_rewind_to_height(dbData.0, dbData.1, UInt32(height), networkType.networkId, &safeRewindHeight)

if result >= 0 {
return .success(BlockHeight(result))
} else if result == -1 && safeRewindHeight > 0 {
return .requestedHeightTooLow(BlockHeight(safeRewindHeight))
} else {
throw ZcashError.rustRewindToHeight(Int32(height), lastErrorMessage(fallback: "`rewindToHeight` failed with unknown error"))
}
}

Expand Down
27 changes: 13 additions & 14 deletions Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ public enum DbInitResult {
case seedNotRelevant
}

/// Enumeration of potential return states for database rewind.
///
public enum RewindResult {
/// The rewind succeeded. The associated block height indicates the maximum height of
/// stored block data retained by the database; this may be less than the block height that
/// was requested.
case success(BlockHeight)
/// The rewind did not succeed but the caller may re-attempt given the associated block height.
case requestedHeightTooLow(BlockHeight)
}

protocol ZcashRustBackendWelding {
/// Returns a list of the accounts in the wallet.
func listAccounts() async throws -> [Int32]
Expand Down Expand Up @@ -64,18 +75,6 @@ protocol ZcashRustBackendWelding {
/// - `rustGetCurrentAddressInvalidAddress` if generated unified address isn't valid.
func getCurrentAddress(account: Int32) async throws -> UnifiedAddress

/// Wallets might need to be rewound because of a reorg, or by user request.
/// There are times where the wallet could get out of sync for many reasons and
/// users might be asked to rescan their wallets in order to fix that. This function
/// returns the nearest height where a rewind is possible. Currently pruning gets rid
/// of sapling witnesses older than 100 blocks. So in order to reconstruct the witness
/// tree that allows to spend notes from the given wallet the rewind can't be more than
/// 100 blocks or back to the oldest unspent note that this wallet contains.
/// - parameter height: height you would like to rewind to.
/// - Returns: the blockheight of the nearest rewind height.
/// - Throws: `rustGetNearestRewindHeight`.
func getNearestRewindHeight(height: Int32) async throws -> Int32

/// Returns a newly-generated unified payment address for the specified account, with the next available diversifier.
/// - parameter account: index of the given account
/// - Throws:
Expand Down Expand Up @@ -123,11 +122,11 @@ protocol ZcashRustBackendWelding {
/// Resets the state of the database to only contain block and transaction information up to the given height. clears up all derived data as well
/// - parameter height: height to rewind to.
/// - Throws: `rustRewindToHeight` if rust layer returns error.
func rewindToHeight(height: Int32) async throws
func rewindToHeight(height: BlockHeight) async throws -> RewindResult

/// Resets the state of the FsBlock database to only contain block and transaction information up to the given height.
/// - Note: this does not delete the files. Only rolls back the database.
/// - parameter height: height to rewind to. DON'T PASS ARBITRARY HEIGHT. Use `getNearestRewindHeight` when unsure
/// - parameter height: height to rewind to. This should be the height returned by a successful `rewindToHeight` call.
/// - Throws: `rustRewindCacheToHeight` if rust layer returns error.
func rewindCacheToHeight(height: Int32) async throws

Expand Down

0 comments on commit c11c8b0

Please sign in to comment.