Skip to content

Commit

Permalink
Update zcash transactions logging
Browse files Browse the repository at this point in the history
  • Loading branch information
ant013 authored and esen committed Apr 24, 2023
1 parent 72a2a95 commit bb12146
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 52 deletions.
4 changes: 2 additions & 2 deletions UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9475,8 +9475,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/zcash/ZcashLightClientKit";
requirement = {
kind = exactVersion;
version = "0.20.1-beta";
kind = revision;
revision = 690b5aa67f67dfa414f1b4aea07a1bf11fa9687e;
};
};
D3993DAA28F42549008720FB /* XCRemoteSwiftPackageReference "WalletConnectSwiftV2" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ZcashAdapter {

private let synchronizer: Synchronizer

private var address: UnifiedAddress?
private var zAddress: String?
private var transactionPool: ZcashTransactionPool?

private let uniqueId: String
Expand All @@ -45,7 +45,7 @@ class ZcashAdapter {

private var waitForStart: Bool = false {
didSet {
if waitForStart && address != nil { // already prepared and has address
if waitForStart && zAddress != nil { // already prepared and has address
syncMain()
}
}
Expand Down Expand Up @@ -173,22 +173,18 @@ class ZcashAdapter {
throw AppError.ZcashError.seedRequired
}
logger?.log(level: .debug, message: "Successful prepared!")
guard let address = await synchronizer.getUnifiedAddress(accountIndex: 0),
let saplingAddress = address.saplingReceiver() else {
guard let address = try? await synchronizer.getUnifiedAddress(accountIndex: 0),
let saplingAddress = try? address.saplingReceiver() else {
throw AppError.ZcashError.noReceiveAddress
}
self.address = address
zAddress = saplingAddress.stringEncoded
logger?.log(level: .debug, message: "Successful get address for 0 account! \(saplingAddress.stringEncoded)")

let transactionPool = ZcashTransactionPool(receiveAddress: saplingAddress, synchronizer: synchronizer)
self.transactionPool = transactionPool

logger?.log(level: .debug, message: "Starting fetch transactions.")
let overviews = await synchronizer.clearedTransactions
let pending = await synchronizer.pendingTransactions
logger?.log(level: .debug, message: "Successful fetch \(overviews.count) txs and \(pending.count) pending txs")

await transactionPool.store(confirmedTransactions: overviews, pendingTransactions: pending)
await transactionPool.initTransactions()
let wrapped = transactionPool.all

if !wrapped.isEmpty {
Expand All @@ -198,8 +194,8 @@ class ZcashAdapter {
})
}

let shielded = synchronizer.getShieldedBalance(accountIndex: 0).decimalValue.decimalValue
let shieldedVerified = synchronizer.getShieldedVerifiedBalance(accountIndex: 0).decimalValue.decimalValue
let shielded = await (try? synchronizer.getShieldedBalance(accountIndex: 0).decimalValue.decimalValue) ?? 0
let shieldedVerified = await (try? synchronizer.getShieldedVerifiedBalance(accountIndex: 0).decimalValue.decimalValue) ?? 0
balanceSubject.onNext(BalanceData(
balance: shieldedVerified,
balanceLocked: shielded - shieldedVerified
Expand Down Expand Up @@ -296,6 +292,9 @@ class ZcashAdapter {
switch event {
case .foundTransactions(let transactions, let inRange):
logger?.log(level: .debug, message: "found \(transactions.count) mined txs in range: \(inRange)")
transactions.forEach { overview in
logger?.log(level: .debug, message: "tx: \(overview.value.decimalValue.decimalString) : \(overview.fee?.decimalString()) : \(overview.raw?.hs.hex)")
}
Task {
let newTxs = await transactionPool?.sync(transactions: transactions) ?? []
transactionRecordsSubject.onNext(newTxs.map {
Expand Down Expand Up @@ -449,6 +448,7 @@ class ZcashAdapter {
switch result {
case .finished:
App.shared.localStorage.zcashAlwaysPendingRewind = true
self?.logger?.log(level: .debug, message: "rewind Successful")
completion?()
case let .failure(error):
self?.state = .notSynced(error: error)
Expand Down Expand Up @@ -553,7 +553,7 @@ extension ZcashAdapter: IAdapter {
return
}

guard address != nil else { // else we need to try prepare library again
guard zAddress != nil else { // else we need to try prepare library again
logger?.log(level: .debug, message: "No address, try to prepare kit again!")
prepare(seedData: seedData, viewingKeys: [viewingKey], walletBirthday: birthday)
return
Expand Down Expand Up @@ -603,15 +603,14 @@ extension ZcashAdapter: IAdapter {
}

var debugInfo: String {
let tAddress = self.address?.transparentReceiver()?.stringEncoded ?? "No Info"
let zAddress = self.address?.saplingReceiver()?.stringEncoded ?? "No Info"
let zAddress = zAddress ?? "No Info"
var balanceState = "No Balance Information yet"

if let status = self.synchronizerState {
balanceState = """
shielded balance
total: \(synchronizer.getShieldedBalance(accountIndex: 0).decimalValue.decimalValue)
verified: \(synchronizer.getShieldedVerifiedBalance(accountIndex: 0).decimalValue.decimalValue)
total: \(balanceData.balanceTotal.description)
verified: \(balanceData.balance)
transparent balance
total: \(String(describing: status.transparentBalance.total))
verified: \(String(describing: status.transparentBalance.verified))
Expand All @@ -620,7 +619,6 @@ extension ZcashAdapter: IAdapter {
return """
ZcashAdapter
z-address: \(String(describing: zAddress))
t-address: \(String(describing: tAddress))
spendingKeys: \(spendingKey.description)
balanceState: \(balanceState)
"""
Expand Down Expand Up @@ -697,7 +695,7 @@ extension ZcashAdapter: IDepositAdapter {

var receiveAddress: String {
// only first account
address?.saplingReceiver()?.stringEncoded ?? "n/a".localized
zAddress ?? "n/a".localized
}

}
Expand All @@ -709,7 +707,7 @@ extension ZcashAdapter: ISendZcashAdapter {
}

var availableBalance: Decimal {
max(0, synchronizer.getShieldedVerifiedBalance(accountIndex: 0).decimalValue.decimalValue - fee)
max(0, balanceData.balance - fee) //TODO: check
}

func validate(address: String) throws -> AddressType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,72 @@ class ZcashTransactionPool {
}

private func zcashTransactions(_ transactions: [PendingTransactionEntity]) -> [ZcashTransactionWrapper] {
transactions.compactMap { ZcashTransactionWrapper(pendingTransaction: $0) }
transactions.compactMap { ZcashTransactionWrapper(tx: $0) }
}

private func zcashTransactions(_ transactions: [ZcashTransaction.Overview]) async -> [ZcashTransactionWrapper] {
var wrapped = [ZcashTransactionWrapper]()
for tx in transactions {
if let tx = try? await transactionWithMemo(confirmedTransaction: tx) {
if let tx = try? await transactionWithAdditional(tx: tx) {
wrapped.append(tx)
}
}
return wrapped
}

private func transactionWithMemo(confirmedTransaction: ZcashTransaction.Overview) async throws -> ZcashTransactionWrapper? {
let memos: [Memo] = (try? await synchronizer.getMemos(for: confirmedTransaction)) ?? []
return ZcashTransactionWrapper(confirmedTransaction: confirmedTransaction, memo: memos.first)
private func zcashTransactions(_ transactions: [ZcashTransaction.Sent]) async -> [ZcashTransactionWrapper] {
var wrapped = [ZcashTransactionWrapper]()
for tx in transactions {
if let tx = try? await transactionWithAdditional(tx: tx) {
wrapped.append(tx)
}
}
return wrapped
}

private func zcashTransactions(_ transactions: [ZcashTransaction.Received]) async -> [ZcashTransactionWrapper] {
var wrapped = [ZcashTransactionWrapper]()
for tx in transactions {
if let tx = try? await transactionWithAdditional(tx: tx) {
wrapped.append(tx)
}
}
return wrapped
}

private func transactionWithAdditional(tx: ZcashTransaction.Overview) async throws -> ZcashTransactionWrapper? {
let memos: [Memo] = (try? await synchronizer.getMemos(for: tx)) ?? []
let recipients = await synchronizer.getRecipients(for: tx)
print("OVERVIEW TX: TXID: \(tx.id) \(tx.value.decimalString())")
memos.forEach { memo in
print("Found Memo: \(memo)")
}
recipients.forEach { recipient in
print("Found Recipient: \(recipient)")
}
return ZcashTransactionWrapper(tx: tx, memo: memos.first, recipient: recipients.first)
}

private func transactionWithAdditional(tx: ZcashTransaction.Sent) async throws -> ZcashTransactionWrapper? {
let memos: [Memo] = (try? await synchronizer.getMemos(for: tx)) ?? []
let recipients = await synchronizer.getRecipients(for: tx)
print("OVERVIEW TX: TXID: \(tx.id) \(tx.value.decimalString())")
memos.forEach { memo in
print("Found Memo: \(memo)")
}
recipients.forEach { recipient in
print("Found Recipient: \(recipient)")
}
return ZcashTransactionWrapper(tx: tx, memo: memos.first, recipient: recipients.first)
}

private func transactionWithAdditional(tx: ZcashTransaction.Received) async throws -> ZcashTransactionWrapper? {
let memos: [Memo] = (try? await synchronizer.getMemos(for: tx)) ?? []
print("OVERVIEW TX: TXID: \(tx.id) \(tx.value.decimalString())")
memos.forEach { memo in
print("Found Memo: \(memo)")
}
return ZcashTransactionWrapper(tx: tx, memo: memos.first, recipient: nil)
}

@discardableResult private func sync(own: inout Set<ZcashTransactionWrapper>, incoming: [ZcashTransactionWrapper]) -> [ZcashTransactionWrapper] {
Expand All @@ -62,9 +112,33 @@ class ZcashTransactionPool {
return newTxs
}

func store(confirmedTransactions: [ZcashTransaction.Overview], pendingTransactions: [PendingTransactionEntity]) async {
self.pendingTransactions = Set(zcashTransactions(pendingTransactions))
self.confirmedTransactions = Set(await zcashTransactions(confirmedTransactions))
func initTransactions() async {
let overviews = await synchronizer.clearedTransactions
let pending = await synchronizer.pendingTransactions
let sent = await synchronizer.sentTransactions
let received = await synchronizer.receivedTransactions
print("Found | overviews: \(overviews.count) | pending: \(pending.count) | sent: \(sent.count) | received: \(received.count)")

pendingTransactions = Set(zcashTransactions(pending))
confirmedTransactions = Set(await zcashTransactions(overviews))

let sentWrapped = await zcashTransactions(sent)
let receivedWrapped = await zcashTransactions(received)

print("===> Overviews:")
confirmedTransactions.forEach { tx in
print("ID: \(tx.id ?? "N/A") | Value: \(tx.value) | Fee: \(tx.fee?.decimalString() ?? "N/A") | Recipient: \(tx.toAddress ?? "N/A")")
}

print("===> Sent:")
sentWrapped.forEach { tx in
print("ID: \(tx.id ?? "N/A") | Value: \(tx.value) | Fee: \(tx.fee?.decimalString() ?? "N/A") | Recipient: \(tx.toAddress ?? "N/A")")
}

print("===> received:")
receivedWrapped.forEach { tx in
print("ID: \(tx.id ?? "N/A") | Value: \(tx.value) | Fee: \(tx.fee?.decimalString() ?? "N/A") | Recipient: \(tx.toAddress ?? "N/A")")
}
}

func sync(transactions: [PendingTransactionEntity]) -> [ZcashTransactionWrapper] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,78 @@ class ZcashTransactionWrapper {
let minedHeight: Int?
let timestamp: TimeInterval
let value: Zatoshi
let fee: Zatoshi?
let memo: String?
let failed: Bool

init?(confirmedTransaction: ZcashTransaction.Overview, memo: Memo?) {
id = confirmedTransaction.id.description
raw = confirmedTransaction.raw
transactionHash = confirmedTransaction.rawID.hs.reversedHex
transactionIndex = confirmedTransaction.index ?? 0
toAddress = nil
isSentTransaction = confirmedTransaction.value < Zatoshi(0)
minedHeight = confirmedTransaction.minedHeight
expiryHeight = confirmedTransaction.expiryHeight
timestamp = confirmedTransaction.blockTime ?? 0
value = confirmedTransaction.value
init?(tx: ZcashTransaction.Overview, memo: Memo?, recipient: TransactionRecipient?) {
id = tx.id.description
raw = tx.raw
transactionHash = tx.rawID.hs.reversedHex
transactionIndex = tx.index ?? 0
toAddress = recipient?.asString
isSentTransaction = tx.value < Zatoshi(0)
minedHeight = tx.minedHeight
expiryHeight = tx.expiryHeight
timestamp = tx.blockTime ?? 0
value = tx.value
fee = tx.fee
self.memo = memo.flatMap { $0.toString() }
failed = false
}

init?(pendingTransaction: PendingTransactionEntity) {
guard let rawTransactionId = pendingTransaction.rawTransactionId else {
init?(tx: ZcashTransaction.Sent, memo: Memo?, recipient: TransactionRecipient?) {
id = tx.id.description
raw = tx.raw
transactionHash = tx.rawID?.hs.reversedHex ?? "n/a".localized
transactionIndex = tx.index ?? 0
toAddress = recipient?.asString
isSentTransaction = tx.value < Zatoshi(0)
minedHeight = tx.minedHeight
expiryHeight = tx.expiryHeight
timestamp = tx.blockTime ?? 0
value = tx.value
fee = nil // ?? todo : how to?
self.memo = memo.flatMap { $0.toString() }
failed = false
}

init?(tx: ZcashTransaction.Received, memo: Memo?, recipient: TransactionRecipient?) {
id = tx.id.description
raw = tx.raw
transactionHash = tx.rawID?.hs.reversedHex ?? "n/a".localized
transactionIndex = tx.index
toAddress = recipient?.asString
isSentTransaction = tx.value < Zatoshi(0)
minedHeight = tx.minedHeight
expiryHeight = tx.expiryHeight
timestamp = tx.blockTime
value = tx.value
fee = nil // ?? todo: how to?
self.memo = memo.flatMap { $0.toString() }
failed = false
}

init?(tx: PendingTransactionEntity) {
guard let rawTransactionId = tx.rawTransactionId else {
return nil
}

id = pendingTransaction.id?.description
raw = pendingTransaction.raw
id = tx.id?.description
raw = tx.raw
transactionHash = rawTransactionId.hs.reversedHex
transactionIndex = -1
toAddress = pendingTransaction.recipient.asString
toAddress = tx.recipient.asString

// if has toAddress - we must mark tx as sent
isSentTransaction = toAddress == nil ? pendingTransaction.value < Zatoshi(0) : true
isSentTransaction = toAddress == nil ? tx.value < Zatoshi(0) : true
minedHeight = nil
expiryHeight = pendingTransaction.expiryHeight
timestamp = pendingTransaction.createTime
value = pendingTransaction.value
memo = pendingTransaction.memo.flatMap { String(bytes: $0, encoding: .utf8) }
failed = pendingTransaction.isFailure
expiryHeight = tx.expiryHeight
timestamp = tx.createTime
value = tx.value
fee = tx.fee
memo = tx.memo.flatMap { String(bytes: $0, encoding: .utf8) }
failed = tx.isFailure
}

}
Expand Down

0 comments on commit bb12146

Please sign in to comment.