Merge pull request #537 from LukasKorba/487_shieldFunds_to_async_await
[#487] shieldFunds to async/await
This commit is contained in:
commit
c834b13f29
|
@ -46,25 +46,17 @@ class GetUTXOsViewController: UIViewController {
|
||||||
|
|
||||||
KRProgressHUD.showMessage("🛡 Shielding 🛡")
|
KRProgressHUD.showMessage("🛡 Shielding 🛡")
|
||||||
|
|
||||||
AppDelegate.shared.sharedSynchronizer.shieldFunds(
|
Task { @MainActor in
|
||||||
spendingKey: spendingKey,
|
let transaction = try await AppDelegate.shared.sharedSynchronizer.shieldFunds(
|
||||||
transparentSecretKey: transparentSecretKey,
|
spendingKey: spendingKey,
|
||||||
memo: "shielding is fun!",
|
transparentSecretKey: transparentSecretKey,
|
||||||
from: 0,
|
memo: "shielding is fun!",
|
||||||
resultBlock: { result in
|
from: 0)
|
||||||
DispatchQueue.main.async {
|
KRProgressHUD.dismiss()
|
||||||
KRProgressHUD.dismiss()
|
self.messageLabel.text = "funds shielded \(transaction)"
|
||||||
switch result {
|
}
|
||||||
case .success(let transaction):
|
|
||||||
self.messageLabel.text = "funds shielded \(transaction)"
|
|
||||||
case .failure(let error):
|
|
||||||
self.messageLabel.text = "Shielding failed: \(error)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} catch {
|
} catch {
|
||||||
self.messageLabel.text = "Error \(error)"
|
self.messageLabel.text = "Shielding failed \(error)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ public protocol Synchronizer {
|
||||||
resultBlock: @escaping (_ result: Result<PendingTransactionEntity, Error>) -> Void
|
resultBlock: @escaping (_ result: Result<PendingTransactionEntity, Error>) -> Void
|
||||||
)
|
)
|
||||||
|
|
||||||
/// Sends zatoshi.
|
/// Shields zatoshi.
|
||||||
/// - Parameter spendingKey: the key that allows spends to occur.
|
/// - Parameter spendingKey: the key that allows spends to occur.
|
||||||
/// - Parameter transparentSecretKey: the key that allows to spend transaprent funds
|
/// - Parameter transparentSecretKey: the key that allows to spend transaprent funds
|
||||||
/// - Parameter memo: the optional memo to include as part of the transaction.
|
/// - Parameter memo: the optional memo to include as part of the transaction.
|
||||||
|
@ -151,9 +151,8 @@ public protocol Synchronizer {
|
||||||
spendingKey: String,
|
spendingKey: String,
|
||||||
transparentSecretKey: String,
|
transparentSecretKey: String,
|
||||||
memo: String?,
|
memo: String?,
|
||||||
from accountIndex: Int,
|
from accountIndex: Int
|
||||||
resultBlock: @escaping (_ result: Result<PendingTransactionEntity, Error>) -> Void
|
) async throws -> PendingTransactionEntity
|
||||||
)
|
|
||||||
|
|
||||||
/// Attempts to cancel a transaction that is about to be sent. Typically, cancellation is only
|
/// Attempts to cancel a transaction that is about to be sent. Typically, cancellation is only
|
||||||
/// an option if the transaction has not yet been submitted to the server.
|
/// an option if the transaction has not yet been submitted to the server.
|
||||||
|
|
|
@ -507,9 +507,8 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
spendingKey: String,
|
spendingKey: String,
|
||||||
transparentSecretKey: String,
|
transparentSecretKey: String,
|
||||||
memo: String?,
|
memo: String?,
|
||||||
from accountIndex: Int,
|
from accountIndex: Int
|
||||||
resultBlock: @escaping (Result<PendingTransactionEntity, Error>) -> Void
|
) async throws -> PendingTransactionEntity {
|
||||||
) {
|
|
||||||
// let's see if there are funds to shield
|
// let's see if there are funds to shield
|
||||||
let derivationTool = DerivationTool(networkType: self.network.networkType)
|
let derivationTool = DerivationTool(networkType: self.network.networkType)
|
||||||
|
|
||||||
|
@ -519,32 +518,22 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
|
|
||||||
// Verify that at least there are funds for the fee. Ideally this logic will be improved by the shielding wallet.
|
// Verify that at least there are funds for the fee. Ideally this logic will be improved by the shielding wallet.
|
||||||
guard tBalance.verified >= self.network.constants.defaultFee(for: self.latestScannedHeight) else {
|
guard tBalance.verified >= self.network.constants.defaultFee(for: self.latestScannedHeight) else {
|
||||||
resultBlock(.failure(ShieldFundsError.insuficientTransparentFunds))
|
throw ShieldFundsError.insuficientTransparentFunds
|
||||||
return
|
|
||||||
}
|
}
|
||||||
let viewingKey = try derivationTool.deriveViewingKey(spendingKey: spendingKey)
|
let viewingKey = try derivationTool.deriveViewingKey(spendingKey: spendingKey)
|
||||||
let zAddr = try derivationTool.deriveShieldedAddress(viewingKey: viewingKey)
|
let zAddr = try derivationTool.deriveShieldedAddress(viewingKey: viewingKey)
|
||||||
|
|
||||||
let shieldingSpend = try transactionManager.initSpend(zatoshi: tBalance.verified, toAddress: zAddr, memo: memo, from: 0)
|
let shieldingSpend = try transactionManager.initSpend(zatoshi: tBalance.verified, toAddress: zAddr, memo: memo, from: 0)
|
||||||
|
|
||||||
// TODO: Task will be removed when this method is changed to async, issue 487, https://github.com/zcash/ZcashLightClientKit/issues/487
|
let transaction = try await transactionManager.encodeShieldingTransaction(
|
||||||
Task {
|
spendingKey: spendingKey,
|
||||||
do {
|
tsk: transparentSecretKey,
|
||||||
let transaction = try await transactionManager.encodeShieldingTransaction(
|
pendingTransaction: shieldingSpend
|
||||||
spendingKey: spendingKey,
|
)
|
||||||
tsk: transparentSecretKey,
|
|
||||||
pendingTransaction: shieldingSpend
|
return try await transactionManager.submit(pendingTransaction: transaction)
|
||||||
)
|
|
||||||
|
|
||||||
let submittedTx = try await transactionManager.submit(pendingTransaction: transaction)
|
|
||||||
resultBlock(.success(submittedTx))
|
|
||||||
} catch {
|
|
||||||
resultBlock(.failure(error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
} catch {
|
||||||
resultBlock(.failure(error))
|
throw error
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class ShieldFundsTests: XCTestCase {
|
class ShieldFundsTests: XCTestCase {
|
||||||
// TODO: Parameterize this from environment?
|
// TODO: Parameterize this from environment?
|
||||||
// swiftlint:disable:next line_length
|
// swiftlint:disable:next line_length
|
||||||
|
@ -82,7 +83,7 @@ class ShieldFundsTests: XCTestCase {
|
||||||
/// 15. sync up to the new chain tip
|
/// 15. sync up to the new chain tip
|
||||||
/// verify that the shielded transactions are confirmed
|
/// verify that the shielded transactions are confirmed
|
||||||
///
|
///
|
||||||
func testShieldFunds() throws {
|
func testShieldFunds() async throws {
|
||||||
// 1. load the dataset
|
// 1. load the dataset
|
||||||
try coordinator.service.useDataset(from: "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/shielding-dataset/shield-funds/1631000.txt")
|
try coordinator.service.useDataset(from: "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/shielding-dataset/shield-funds/1631000.txt")
|
||||||
|
|
||||||
|
@ -110,15 +111,19 @@ class ShieldFundsTests: XCTestCase {
|
||||||
let preTxExpectation = XCTestExpectation(description: "pre receive")
|
let preTxExpectation = XCTestExpectation(description: "pre receive")
|
||||||
|
|
||||||
// 3. sync up to that height
|
// 3. sync up to that height
|
||||||
try coordinator.sync(
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
completion: { synchro in
|
do {
|
||||||
initialVerifiedBalance = synchro.initializer.getVerifiedBalance()
|
try coordinator.sync(completion: { synchronizer in
|
||||||
initialTotalBalance = synchro.initializer.getBalance()
|
initialVerifiedBalance = synchronizer.initializer.getVerifiedBalance()
|
||||||
preTxExpectation.fulfill()
|
initialTotalBalance = synchronizer.initializer.getBalance()
|
||||||
shouldContinue = true
|
preTxExpectation.fulfill()
|
||||||
},
|
shouldContinue = true
|
||||||
error: self.handleError
|
continuation.resume()
|
||||||
)
|
}, error: self.handleError)
|
||||||
|
} catch {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wait(for: [preTxExpectation], timeout: 10)
|
wait(for: [preTxExpectation], timeout: 10)
|
||||||
|
|
||||||
|
@ -149,14 +154,17 @@ class ShieldFundsTests: XCTestCase {
|
||||||
shouldContinue = false
|
shouldContinue = false
|
||||||
|
|
||||||
// 6. Sync and find the UXTO on chain.
|
// 6. Sync and find the UXTO on chain.
|
||||||
try coordinator.sync(
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
completion: { synchro in
|
do {
|
||||||
tFundsDetectionExpectation.fulfill()
|
try coordinator.sync(completion: { synchronizer in
|
||||||
shouldContinue = true
|
shouldContinue = true
|
||||||
},
|
tFundsDetectionExpectation.fulfill()
|
||||||
error: self.handleError
|
continuation.resume()
|
||||||
)
|
}, error: self.handleError)
|
||||||
|
} catch {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
wait(for: [tFundsDetectionExpectation], timeout: 2)
|
wait(for: [tFundsDetectionExpectation], timeout: 2)
|
||||||
|
|
||||||
// at this point the balance should be zero for shielded, then zero verified transparent funds
|
// at this point the balance should be zero for shielded, then zero verified transparent funds
|
||||||
|
@ -176,13 +184,17 @@ class ShieldFundsTests: XCTestCase {
|
||||||
sleep(2)
|
sleep(2)
|
||||||
|
|
||||||
// 8. sync up to chain tip.
|
// 8. sync up to chain tip.
|
||||||
try coordinator.sync(
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
completion: { synchro in
|
do {
|
||||||
tFundsConfirmationSyncExpectation.fulfill()
|
try coordinator.sync(completion: { synchronizer in
|
||||||
shouldContinue = true
|
shouldContinue = true
|
||||||
},
|
tFundsConfirmationSyncExpectation.fulfill()
|
||||||
error: self.handleError
|
continuation.resume()
|
||||||
)
|
}, error: self.handleError)
|
||||||
|
} catch {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wait(for: [tFundsConfirmationSyncExpectation], timeout: 5)
|
wait(for: [tFundsConfirmationSyncExpectation], timeout: 5)
|
||||||
|
|
||||||
|
@ -209,22 +221,18 @@ class ShieldFundsTests: XCTestCase {
|
||||||
var shieldingPendingTx: PendingTransactionEntity?
|
var shieldingPendingTx: PendingTransactionEntity?
|
||||||
|
|
||||||
// shield the funds
|
// shield the funds
|
||||||
coordinator.synchronizer.shieldFunds(
|
do {
|
||||||
spendingKey: coordinator.spendingKey,
|
let pendingTx = try await coordinator.synchronizer.shieldFunds(
|
||||||
transparentSecretKey: transparentSecretKey,
|
spendingKey: coordinator.spendingKey,
|
||||||
memo: "shield funds",
|
transparentSecretKey: transparentSecretKey,
|
||||||
from: 0
|
memo: "shield funds",
|
||||||
) { result in
|
from: 0)
|
||||||
switch result {
|
shouldContinue = true
|
||||||
case .failure(let error):
|
XCTAssertEqual(pendingTx.value, Zatoshi(10000))
|
||||||
XCTFail("Failed With error: \(error.localizedDescription)")
|
shieldingPendingTx = pendingTx
|
||||||
|
|
||||||
case .success(let pendingTx):
|
|
||||||
shouldContinue = true
|
|
||||||
XCTAssertEqual(pendingTx.value, Zatoshi(10000))
|
|
||||||
shieldingPendingTx = pendingTx
|
|
||||||
}
|
|
||||||
shieldFundsExpectation.fulfill()
|
shieldFundsExpectation.fulfill()
|
||||||
|
} catch {
|
||||||
|
XCTFail("Failed With error: \(error.localizedDescription)")
|
||||||
}
|
}
|
||||||
|
|
||||||
wait(for: [shieldFundsExpectation], timeout: 30)
|
wait(for: [shieldFundsExpectation], timeout: 30)
|
||||||
|
@ -264,14 +272,17 @@ class ShieldFundsTests: XCTestCase {
|
||||||
// 13. sync up to chain tip
|
// 13. sync up to chain tip
|
||||||
let postShieldSyncExpectation = XCTestExpectation(description: "sync Post shield")
|
let postShieldSyncExpectation = XCTestExpectation(description: "sync Post shield")
|
||||||
shouldContinue = false
|
shouldContinue = false
|
||||||
try coordinator.sync(
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
completion: { synchro in
|
do {
|
||||||
postShieldSyncExpectation.fulfill()
|
try coordinator.sync(completion: { synchronizer in
|
||||||
shouldContinue = true
|
shouldContinue = true
|
||||||
},
|
postShieldSyncExpectation.fulfill()
|
||||||
error: self.handleError
|
continuation.resume()
|
||||||
)
|
}, error: self.handleError)
|
||||||
|
} catch {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
wait(for: [postShieldSyncExpectation], timeout: 3)
|
wait(for: [postShieldSyncExpectation], timeout: 3)
|
||||||
|
|
||||||
guard shouldContinue else { return }
|
guard shouldContinue else { return }
|
||||||
|
@ -294,13 +305,17 @@ class ShieldFundsTests: XCTestCase {
|
||||||
shouldContinue = false
|
shouldContinue = false
|
||||||
|
|
||||||
// 15. sync up to the new chain tip
|
// 15. sync up to the new chain tip
|
||||||
try coordinator.sync(
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
completion: { synchro in
|
do {
|
||||||
confirmationExpectation.fulfill()
|
try coordinator.sync(completion: { synchronizer in
|
||||||
shouldContinue = true
|
shouldContinue = true
|
||||||
},
|
confirmationExpectation.fulfill()
|
||||||
error: self.handleError
|
continuation.resume()
|
||||||
)
|
}, error: self.handleError)
|
||||||
|
} catch {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wait(for: [confirmationExpectation], timeout: 5)
|
wait(for: [confirmationExpectation], timeout: 5)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue