[#1526] Failed Transaction TImestamps
- BlockDAO reintroduced - When a minedHeight is missing, the block time is trying to be fetched and used
This commit is contained in:
parent
ed89ed7f0b
commit
ac590f2d53
|
@ -0,0 +1,65 @@
|
|||
// BlockDao.swift
|
||||
// ZcashLightClientKit
|
||||
//
|
||||
// Created by Lukas Korba on 2025-01-25.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SQLite
|
||||
|
||||
protocol BlockDao {
|
||||
func block(at height: BlockHeight) throws -> Block?
|
||||
}
|
||||
|
||||
struct Block: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case height
|
||||
case time
|
||||
}
|
||||
|
||||
enum TableStructure {
|
||||
static let height = SQLite.Expression<Int>(Block.CodingKeys.height.rawValue)
|
||||
static let time = SQLite.Expression<Int>(Block.CodingKeys.time.rawValue)
|
||||
}
|
||||
|
||||
let height: BlockHeight
|
||||
let time: Int
|
||||
|
||||
static let table = Table("blocks")
|
||||
}
|
||||
|
||||
class BlockSQLDAO: BlockDao {
|
||||
let dbProvider: ConnectionProvider
|
||||
let table: Table
|
||||
let height = SQLite.Expression<Int>("height")
|
||||
|
||||
init(dbProvider: ConnectionProvider) {
|
||||
self.dbProvider = dbProvider
|
||||
self.table = Table("Blocks")
|
||||
}
|
||||
|
||||
/// - Throws:
|
||||
/// - `blockDAOCantDecode` if block data loaded from DB can't be decoded to `Block` object.
|
||||
/// - `blockDAOBlock` if sqlite query to load block metadata failed.
|
||||
func block(at height: BlockHeight) throws -> Block? {
|
||||
do {
|
||||
return try dbProvider
|
||||
.connection()
|
||||
.prepare(Block.table.filter(Block.TableStructure.height == height).limit(1))
|
||||
.map {
|
||||
do {
|
||||
return try $0.decode()
|
||||
} catch {
|
||||
throw ZcashError.blockDAOCantDecode(error)
|
||||
}
|
||||
}
|
||||
.first
|
||||
} catch {
|
||||
if let error = error as? ZcashError {
|
||||
throw error
|
||||
} else {
|
||||
throw ZcashError.blockDAOBlock(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,12 +16,14 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
|
||||
let dbProvider: ConnectionProvider
|
||||
|
||||
private let blockDao: BlockSQLDAO
|
||||
private let transactionsView = View("v_transactions")
|
||||
private let txOutputsView = View("v_tx_outputs")
|
||||
private let traceClosure: ((String) -> Void)?
|
||||
|
||||
init(dbProvider: ConnectionProvider, traceClosure: ((String) -> Void)? = nil) {
|
||||
self.dbProvider = dbProvider
|
||||
self.blockDao = BlockSQLDAO(dbProvider: dbProvider)
|
||||
self.traceClosure = traceClosure
|
||||
}
|
||||
|
||||
|
@ -39,6 +41,11 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
true
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func blockForHeight(_ height: BlockHeight) async throws -> Block? {
|
||||
try blockDao.block(at: height)
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func countAll() async throws -> Int {
|
||||
do {
|
||||
|
@ -71,7 +78,22 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
.filterQueryFor(kind: kind)
|
||||
.limit(limit, offset: offset)
|
||||
|
||||
return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
var transactions: [ZcashTransaction.Overview] = try await execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
|
||||
// Enhance the timestamp for unmined & expired transactions
|
||||
for i in 0..<transactions.count {
|
||||
let transaction = transactions[i]
|
||||
|
||||
if transaction.minedHeight == nil {
|
||||
if let expiryHeight = transaction.expiryHeight {
|
||||
if let block = try await blockForHeight(expiryHeight) {
|
||||
transactions[i].blockTime = TimeInterval(block.time)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return transactions
|
||||
}
|
||||
|
||||
func find(in range: CompactBlockRange, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
|
||||
|
|
|
@ -45,7 +45,7 @@ public enum ZcashTransaction {
|
|||
}
|
||||
|
||||
public let accountUUID: AccountUUID
|
||||
public let blockTime: TimeInterval?
|
||||
public var blockTime: TimeInterval?
|
||||
public let expiryHeight: BlockHeight?
|
||||
public let fee: Zatoshi?
|
||||
public let index: Int?
|
||||
|
|
Loading…
Reference in New Issue