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 🛡")
|
||||
|
||||
AppDelegate.shared.sharedSynchronizer.shieldFunds(
|
||||
spendingKey: spendingKey,
|
||||
transparentSecretKey: transparentSecretKey,
|
||||
memo: "shielding is fun!",
|
||||
from: 0,
|
||||
resultBlock: { result in
|
||||
DispatchQueue.main.async {
|
||||
KRProgressHUD.dismiss()
|
||||
switch result {
|
||||
case .success(let transaction):
|
||||
self.messageLabel.text = "funds shielded \(transaction)"
|
||||
case .failure(let error):
|
||||
self.messageLabel.text = "Shielding failed: \(error)"
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
Task { @MainActor in
|
||||
let transaction = try await AppDelegate.shared.sharedSynchronizer.shieldFunds(
|
||||
spendingKey: spendingKey,
|
||||
transparentSecretKey: transparentSecretKey,
|
||||
memo: "shielding is fun!",
|
||||
from: 0)
|
||||
KRProgressHUD.dismiss()
|
||||
self.messageLabel.text = "funds shielded \(transaction)"
|
||||
}
|
||||
} 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
|
||||
)
|
||||
|
||||
/// Sends zatoshi.
|
||||
/// Shields zatoshi.
|
||||
/// - Parameter spendingKey: the key that allows spends to occur.
|
||||
/// - Parameter transparentSecretKey: the key that allows to spend transaprent funds
|
||||
/// - Parameter memo: the optional memo to include as part of the transaction.
|
||||
|
@ -151,9 +151,8 @@ public protocol Synchronizer {
|
|||
spendingKey: String,
|
||||
transparentSecretKey: String,
|
||||
memo: String?,
|
||||
from accountIndex: Int,
|
||||
resultBlock: @escaping (_ result: Result<PendingTransactionEntity, Error>) -> Void
|
||||
)
|
||||
from accountIndex: Int
|
||||
) async throws -> PendingTransactionEntity
|
||||
|
||||
/// 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.
|
||||
|
|
|
@ -507,9 +507,8 @@ public class SDKSynchronizer: Synchronizer {
|
|||
spendingKey: String,
|
||||
transparentSecretKey: String,
|
||||
memo: String?,
|
||||
from accountIndex: Int,
|
||||
resultBlock: @escaping (Result<PendingTransactionEntity, Error>) -> Void
|
||||
) {
|
||||
from accountIndex: Int
|
||||
) async throws -> PendingTransactionEntity {
|
||||
// let's see if there are funds to shield
|
||||
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.
|
||||
guard tBalance.verified >= self.network.constants.defaultFee(for: self.latestScannedHeight) else {
|
||||
resultBlock(.failure(ShieldFundsError.insuficientTransparentFunds))
|
||||
return
|
||||
throw ShieldFundsError.insuficientTransparentFunds
|
||||
}
|
||||
let viewingKey = try derivationTool.deriveViewingKey(spendingKey: spendingKey)
|
||||
let zAddr = try derivationTool.deriveShieldedAddress(viewingKey: viewingKey)
|
||||
|
||||
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
|
||||
Task {
|
||||
do {
|
||||
let transaction = try await transactionManager.encodeShieldingTransaction(
|
||||
spendingKey: spendingKey,
|
||||
tsk: transparentSecretKey,
|
||||
pendingTransaction: shieldingSpend
|
||||
)
|
||||
|
||||
let submittedTx = try await transactionManager.submit(pendingTransaction: transaction)
|
||||
resultBlock(.success(submittedTx))
|
||||
} catch {
|
||||
resultBlock(.failure(error))
|
||||
}
|
||||
}
|
||||
let transaction = try await transactionManager.encodeShieldingTransaction(
|
||||
spendingKey: spendingKey,
|
||||
tsk: transparentSecretKey,
|
||||
pendingTransaction: shieldingSpend
|
||||
)
|
||||
|
||||
return try await transactionManager.submit(pendingTransaction: transaction)
|
||||
} catch {
|
||||
resultBlock(.failure(error))
|
||||
return
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import XCTest
|
||||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class ShieldFundsTests: XCTestCase {
|
||||
// TODO: Parameterize this from environment?
|
||||
// swiftlint:disable:next line_length
|
||||
|
@ -82,7 +83,7 @@ class ShieldFundsTests: XCTestCase {
|
|||
/// 15. sync up to the new chain tip
|
||||
/// verify that the shielded transactions are confirmed
|
||||
///
|
||||
func testShieldFunds() throws {
|
||||
func testShieldFunds() async throws {
|
||||
// 1. load the dataset
|
||||
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")
|
||||
|
||||
// 3. sync up to that height
|
||||
try coordinator.sync(
|
||||
completion: { synchro in
|
||||
initialVerifiedBalance = synchro.initializer.getVerifiedBalance()
|
||||
initialTotalBalance = synchro.initializer.getBalance()
|
||||
preTxExpectation.fulfill()
|
||||
shouldContinue = true
|
||||
},
|
||||
error: self.handleError
|
||||
)
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
do {
|
||||
try coordinator.sync(completion: { synchronizer in
|
||||
initialVerifiedBalance = synchronizer.initializer.getVerifiedBalance()
|
||||
initialTotalBalance = synchronizer.initializer.getBalance()
|
||||
preTxExpectation.fulfill()
|
||||
shouldContinue = true
|
||||
continuation.resume()
|
||||
}, error: self.handleError)
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
|
||||
wait(for: [preTxExpectation], timeout: 10)
|
||||
|
||||
|
@ -149,14 +154,17 @@ class ShieldFundsTests: XCTestCase {
|
|||
shouldContinue = false
|
||||
|
||||
// 6. Sync and find the UXTO on chain.
|
||||
try coordinator.sync(
|
||||
completion: { synchro in
|
||||
tFundsDetectionExpectation.fulfill()
|
||||
shouldContinue = true
|
||||
},
|
||||
error: self.handleError
|
||||
)
|
||||
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
do {
|
||||
try coordinator.sync(completion: { synchronizer in
|
||||
shouldContinue = true
|
||||
tFundsDetectionExpectation.fulfill()
|
||||
continuation.resume()
|
||||
}, error: self.handleError)
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
wait(for: [tFundsDetectionExpectation], timeout: 2)
|
||||
|
||||
// at this point the balance should be zero for shielded, then zero verified transparent funds
|
||||
|
@ -176,13 +184,17 @@ class ShieldFundsTests: XCTestCase {
|
|||
sleep(2)
|
||||
|
||||
// 8. sync up to chain tip.
|
||||
try coordinator.sync(
|
||||
completion: { synchro in
|
||||
tFundsConfirmationSyncExpectation.fulfill()
|
||||
shouldContinue = true
|
||||
},
|
||||
error: self.handleError
|
||||
)
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
do {
|
||||
try coordinator.sync(completion: { synchronizer in
|
||||
shouldContinue = true
|
||||
tFundsConfirmationSyncExpectation.fulfill()
|
||||
continuation.resume()
|
||||
}, error: self.handleError)
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
|
||||
wait(for: [tFundsConfirmationSyncExpectation], timeout: 5)
|
||||
|
||||
|
@ -209,22 +221,18 @@ class ShieldFundsTests: XCTestCase {
|
|||
var shieldingPendingTx: PendingTransactionEntity?
|
||||
|
||||
// shield the funds
|
||||
coordinator.synchronizer.shieldFunds(
|
||||
spendingKey: coordinator.spendingKey,
|
||||
transparentSecretKey: transparentSecretKey,
|
||||
memo: "shield funds",
|
||||
from: 0
|
||||
) { result in
|
||||
switch result {
|
||||
case .failure(let error):
|
||||
XCTFail("Failed With error: \(error.localizedDescription)")
|
||||
|
||||
case .success(let pendingTx):
|
||||
shouldContinue = true
|
||||
XCTAssertEqual(pendingTx.value, Zatoshi(10000))
|
||||
shieldingPendingTx = pendingTx
|
||||
}
|
||||
do {
|
||||
let pendingTx = try await coordinator.synchronizer.shieldFunds(
|
||||
spendingKey: coordinator.spendingKey,
|
||||
transparentSecretKey: transparentSecretKey,
|
||||
memo: "shield funds",
|
||||
from: 0)
|
||||
shouldContinue = true
|
||||
XCTAssertEqual(pendingTx.value, Zatoshi(10000))
|
||||
shieldingPendingTx = pendingTx
|
||||
shieldFundsExpectation.fulfill()
|
||||
} catch {
|
||||
XCTFail("Failed With error: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
wait(for: [shieldFundsExpectation], timeout: 30)
|
||||
|
@ -264,14 +272,17 @@ class ShieldFundsTests: XCTestCase {
|
|||
// 13. sync up to chain tip
|
||||
let postShieldSyncExpectation = XCTestExpectation(description: "sync Post shield")
|
||||
shouldContinue = false
|
||||
try coordinator.sync(
|
||||
completion: { synchro in
|
||||
postShieldSyncExpectation.fulfill()
|
||||
shouldContinue = true
|
||||
},
|
||||
error: self.handleError
|
||||
)
|
||||
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
do {
|
||||
try coordinator.sync(completion: { synchronizer in
|
||||
shouldContinue = true
|
||||
postShieldSyncExpectation.fulfill()
|
||||
continuation.resume()
|
||||
}, error: self.handleError)
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
wait(for: [postShieldSyncExpectation], timeout: 3)
|
||||
|
||||
guard shouldContinue else { return }
|
||||
|
@ -294,13 +305,17 @@ class ShieldFundsTests: XCTestCase {
|
|||
shouldContinue = false
|
||||
|
||||
// 15. sync up to the new chain tip
|
||||
try coordinator.sync(
|
||||
completion: { synchro in
|
||||
confirmationExpectation.fulfill()
|
||||
shouldContinue = true
|
||||
},
|
||||
error: self.handleError
|
||||
)
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
do {
|
||||
try coordinator.sync(completion: { synchronizer in
|
||||
shouldContinue = true
|
||||
confirmationExpectation.fulfill()
|
||||
continuation.resume()
|
||||
}, error: self.handleError)
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
|
||||
wait(for: [confirmationExpectation], timeout: 5)
|
||||
|
||||
|
|
Loading…
Reference in New Issue