Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to preview zcash-light-client-ffi release with fix for note commitment tree corruption #1493

Merged
merged 1 commit into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/grpc/grpc-swift.git",
"state" : {
"revision" : "6a90b7e77e29f9bda6c2b3a4165a40d6c02cfda1",
"version" : "1.23.0"
"revision" : "07123ed731671e800ab8d641006613612e954746",
"version" : "1.23.1"
}
},
{
Expand Down Expand Up @@ -77,8 +77,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "ee97538f5b81ae89698fd95938896dec5217b148",
"version" : "1.1.1"
"revision" : "671108c96644956dddcd89dd59c203dcdb36cec7",
"version" : "1.1.4"
}
},
{
Expand All @@ -95,53 +95,53 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-http-types",
"state" : {
"revision" : "9bee2fdb79cc740081abd8ebd80738063d632286",
"version" : "1.1.0"
"revision" : "ae67c8178eb46944fd85e4dc6dd970e1f3ed6ccd",
"version" : "1.3.0"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-log.git",
"state" : {
"revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5",
"version" : "1.5.4"
"revision" : "9cb486020ebf03bfa5b5df985387a14a98744537",
"version" : "1.6.1"
}
},
{
"identity" : "swift-nio",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "9428f62793696d9a0cc1f26a63f63bb31da0516d",
"version" : "2.66.0"
"revision" : "665206000b8307cab5ac51203d29b0f232d7e31b",
"version" : "2.74.0"
}
},
{
"identity" : "swift-nio-extras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
"revision" : "a3b640d7dc567225db7c94386a6e71aded1bfa63",
"version" : "1.22.0"
"revision" : "d1ead62745cc3269e482f1c51f27608057174379",
"version" : "1.24.0"
}
},
{
"identity" : "swift-nio-http2",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "8d8eb609929aee75336a0a3d2417280786265868",
"version" : "1.32.0"
"revision" : "b5f7062b60e4add1e8c343ba4eb8da2e324b3a94",
"version" : "1.34.0"
}
},
{
"identity" : "swift-nio-ssl",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-ssl.git",
"state" : {
"revision" : "2b09805797f21c380f7dc9bedaab3157c5508efb",
"version" : "2.27.0"
"revision" : "7b84abbdcef69cc3be6573ac12440220789dcd69",
"version" : "2.27.2"
}
},
{
Expand All @@ -158,26 +158,26 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "9f0c76544701845ad98716f3f6a774a892152bcb",
"version" : "1.26.0"
"revision" : "ebc7251dd5b37f627c93698e4374084d98409633",
"version" : "1.28.2"
}
},
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "f9266c85189c2751589a50ea5aec72799797e471",
"version" : "1.3.0"
"revision" : "d2ba781702a1d8285419c15ee62fd734a9437ff5",
"version" : "1.3.2"
}
},
{
"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" : "be1575f8d2dce5b7502448ef1f8619e2ca9359d9",
"version" : "0.10.0"
}
}
],
Expand Down
26 changes: 13 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,10 @@
{
"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" : "be1575f8d2dce5b7502448ef1f8619e2ca9359d9",
"version" : "0.10.0"
}
}
],
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", from: "0.10.0")
],
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"))
}
}
Comment on lines +325 to +337
Copy link
Contributor

@daira daira Sep 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the code duplicated between here and RewindAction.swift be factored out? Non-blocking.

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: Int64 = -1;
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
Loading