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

Fixed NSInternalInconsistencyException & Swift runtime failure: arithmetic overflow #267

Merged
merged 6 commits into from
Dec 27, 2024
Prev Previous commit
Next Next commit
Reformat code using Xcode's indentation
- Applied consistent indentation using Xcode's Ctrl + I shortcut to improve code readability.
- No functional changes were made.
azisramdhan committed Dec 27, 2024

Verified

This commit was signed with the committer’s verified signature. The key has expired.
azisramdhan Azis R
commit f3a701fa60644be928f3a6ef8717496e087a695a
128 changes: 64 additions & 64 deletions litewallet/ViewModels/Transaction.swift
Original file line number Diff line number Diff line change
@@ -14,72 +14,72 @@ class Transaction {

private let opsAddressSet: Set<String> = Partner.litewalletOpsSet()
/// Hassan
init?(_ tx: BRTxRef, walletManager: WalletManager, kvStore: BRReplicatedKVStore?, rate: Rate?) {
guard let wallet = walletManager.wallet else { return nil }
guard let peerManager = walletManager.peerManager else { return nil }

self.tx = tx
self.wallet = wallet
self.kvStore = kvStore
let fee = wallet.feeForTx(tx) ?? 0

var outputAddresses = Set<String>()
var opsAmount = UInt64(0)

for (_, output) in tx.outputs.enumerated() {
outputAddresses.insert(output.updatedSwiftAddress)
}

let outputAddress = opsAddressSet.intersection(outputAddresses).first
if let targetAddress = outputAddress,
let opsOutput = tx.outputs.filter({ $0.updatedSwiftAddress == targetAddress }).first
{
opsAmount = opsOutput.amount
}
init?(_ tx: BRTxRef, walletManager: WalletManager, kvStore: BRReplicatedKVStore?, rate: Rate?) {
guard let wallet = walletManager.wallet else { return nil }
guard let peerManager = walletManager.peerManager else { return nil }
self.tx = tx
self.wallet = wallet
self.kvStore = kvStore
let fee = wallet.feeForTx(tx) ?? 0
var outputAddresses = Set<String>()
var opsAmount = UInt64(0)
for (_, output) in tx.outputs.enumerated() {
outputAddresses.insert(output.updatedSwiftAddress)
}
let outputAddress = opsAddressSet.intersection(outputAddresses).first
if let targetAddress = outputAddress,
let opsOutput = tx.outputs.filter({ $0.updatedSwiftAddress == targetAddress }).first
{
opsAmount = opsOutput.amount
}

// Safely calculate fee = fee + opsAmount
Copy link
Contributor

Choose a reason for hiding this comment

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

While comments like // Safely calculate fee = fee + opsAmount provide context, they are overly verbose and repeat what the code already expresses.
For example; // Ensure the new fee calculation doesn't overflow

guard let safeFee = fee.safeAddition(opsAmount) else { return nil }
self.fee = safeFee

let amountReceived = wallet.amountReceivedFromTx(tx)

// Safely calculate amountSent = wallet.amountSentByTx(tx) - opsAmount
guard let safeAmountSent = wallet.amountSentByTx(tx).safeSubtraction(opsAmount) else { return nil }

// Safely calculate (amountReceived + fee)
guard let safeSum = amountReceived.safeAddition(fee) else { return nil }

if safeAmountSent > 0, safeAmountSent == safeSum {
direction = .moved
satoshis = safeAmountSent
} else if safeAmountSent > 0 {
// Safely calculate (safeAmountSent - amountReceived - fee)
guard let safeSatoshis = safeAmountSent
.safeSubtraction(amountReceived)?
.safeSubtraction(fee) else { return nil }
direction = .sent
satoshis = safeSatoshis
} else {
direction = .received
satoshis = amountReceived
}
timestamp = Int(tx.pointee.timestamp)

isValid = wallet.transactionIsValid(tx)
let transactionBlockHeight = tx.pointee.blockHeight
self.blockHeight = tx.pointee.blockHeight == UInt32(INT32_MAX) ? S.TransactionDetails.notConfirmedBlockHeightLabel.localize() : "\(tx.pointee.blockHeight)"

let blockHeight = peerManager.lastBlockHeight
confirms = transactionBlockHeight > blockHeight ? 0 : Int(blockHeight - transactionBlockHeight) + 1
status = makeStatus(tx, wallet: wallet, peerManager: peerManager, confirms: confirms, direction: direction)

hash = tx.pointee.txHash.description
metaDataKey = tx.pointee.txHash.txKey

if let rate = rate, confirms < 6, direction == .received {
attemptCreateMetaData(tx: tx, rate: rate)
}
}
guard let safeFee = fee.safeAddition(opsAmount) else { return nil }
self.fee = safeFee
let amountReceived = wallet.amountReceivedFromTx(tx)
// Safely calculate amountSent = wallet.amountSentByTx(tx) - opsAmount
guard let safeAmountSent = wallet.amountSentByTx(tx).safeSubtraction(opsAmount) else { return nil }
// Safely calculate (amountReceived + fee)
guard let safeSum = amountReceived.safeAddition(fee) else { return nil }
if safeAmountSent > 0, safeAmountSent == safeSum {
direction = .moved
satoshis = safeAmountSent
} else if safeAmountSent > 0 {
// Safely calculate (safeAmountSent - amountReceived - fee)
guard let safeSatoshis = safeAmountSent
.safeSubtraction(amountReceived)?
.safeSubtraction(fee) else { return nil }
direction = .sent
satoshis = safeSatoshis
} else {
direction = .received
satoshis = amountReceived
}
timestamp = Int(tx.pointee.timestamp)
isValid = wallet.transactionIsValid(tx)
let transactionBlockHeight = tx.pointee.blockHeight
self.blockHeight = tx.pointee.blockHeight == UInt32(INT32_MAX) ? S.TransactionDetails.notConfirmedBlockHeightLabel.localize() : "\(tx.pointee.blockHeight)"
let blockHeight = peerManager.lastBlockHeight
confirms = transactionBlockHeight > blockHeight ? 0 : Int(blockHeight - transactionBlockHeight) + 1
status = makeStatus(tx, wallet: wallet, peerManager: peerManager, confirms: confirms, direction: direction)
hash = tx.pointee.txHash.description
metaDataKey = tx.pointee.txHash.txKey
if let rate = rate, confirms < 6, direction == .received {
attemptCreateMetaData(tx: tx, rate: rate)
}
}

func amountDescription(isLtcSwapped: Bool, rate: Rate, maxDigits: Int) -> String {
let amount = Amount(amount: satoshis, rate: rate, maxDigits: maxDigits)