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

Check coinbase confirms #1026

Merged
merged 2 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions lib/models/isar/models/blockchain_data/utxo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,14 @@ class UTXO {
return max(0, currentChainHeight - (blockHeight! - 1));
}

bool isConfirmed(int currentChainHeight, int minimumConfirms) {
bool isConfirmed(
int currentChainHeight,
int minimumConfirms,
int minimumCoinbaseConfirms,
) {
final confirmations = getConfirmations(currentChainHeight);
return confirmations >= minimumConfirms;
return confirmations >=
(isCoinbase ? minimumCoinbaseConfirms : minimumConfirms);
}

@ignore
Expand Down
32 changes: 22 additions & 10 deletions lib/models/isar/models/blockchain_data/v2/transaction_v2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,14 @@ class TransactionV2 {
return max(0, currentChainHeight - (height! - 1));
}

bool isConfirmed(int currentChainHeight, int minimumConfirms) {
bool isConfirmed(
int currentChainHeight,
int minimumConfirms,
int minimumCoinbaseConfirms,
) {
final confirmations = getConfirmations(currentChainHeight);
return confirmations >= minimumConfirms;
return confirmations >=
(isCoinbase() ? minimumCoinbaseConfirms : minimumConfirms);
}

Amount getFee({required int fractionDigits}) {
Expand Down Expand Up @@ -225,15 +230,19 @@ class TransactionV2 {
String statusLabel({
required int currentChainHeight,
required int minConfirms,
required int minCoinbaseConfirms,
}) {
String prettyConfirms() =>
"(${getConfirmations(currentChainHeight)}/$minConfirms)";
String prettyConfirms() => "("
"${getConfirmations(currentChainHeight)}"
"/"
"${(isCoinbase() ? minCoinbaseConfirms : minConfirms)}"
")";

if (subType == TransactionSubType.cashFusion ||
subType == TransactionSubType.mint ||
(subType == TransactionSubType.sparkMint &&
type == TransactionType.sentToSelf)) {
if (isConfirmed(currentChainHeight, minConfirms)) {
if (isConfirmed(currentChainHeight, minConfirms, minCoinbaseConfirms)) {
return "Anonymized";
} else {
return "Anonymizing ${prettyConfirms()}";
Expand All @@ -248,7 +257,7 @@ class TransactionV2 {
if (isCancelled) {
return "Cancelled";
} else if (type == TransactionType.incoming) {
if (isConfirmed(currentChainHeight, minConfirms)) {
if (isConfirmed(currentChainHeight, minConfirms, minCoinbaseConfirms)) {
return "Received";
} else {
if (numberOfMessages == 1) {
Expand All @@ -260,7 +269,7 @@ class TransactionV2 {
}
}
} else if (type == TransactionType.outgoing) {
if (isConfirmed(currentChainHeight, minConfirms)) {
if (isConfirmed(currentChainHeight, minConfirms, minCoinbaseConfirms)) {
return "Sent (confirmed)";
} else {
if (numberOfMessages == 1) {
Expand All @@ -278,19 +287,19 @@ class TransactionV2 {
// if (_transaction.isMinting) {
// return "Minting";
// } else
if (isConfirmed(currentChainHeight, minConfirms)) {
if (isConfirmed(currentChainHeight, minConfirms, minCoinbaseConfirms)) {
return "Received";
} else {
return "Receiving ${prettyConfirms()}";
}
} else if (type == TransactionType.outgoing) {
if (isConfirmed(currentChainHeight, minConfirms)) {
if (isConfirmed(currentChainHeight, minConfirms, minCoinbaseConfirms)) {
return "Sent";
} else {
return "Sending ${prettyConfirms()}";
}
} else if (type == TransactionType.sentToSelf) {
if (isConfirmed(currentChainHeight, minConfirms)) {
if (isConfirmed(currentChainHeight, minConfirms, minCoinbaseConfirms)) {
return "Sent to self";
} else {
return "Sent to self ${prettyConfirms()}";
Expand All @@ -308,6 +317,9 @@ class TransactionV2 {
return map[key];
}

bool isCoinbase() =>
type == TransactionType.incoming && inputs.any((e) => e.coinbase != null);

@override
String toString() {
return 'TransactionV2(\n'
Expand Down
3 changes: 3 additions & 0 deletions lib/pages/coin_control/coin_control_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
utxo.isConfirmed(
currentHeight,
minConfirms,
coin.minCoinbaseConfirms,
)),
initialSelectedState: isSelected,
onSelectedChanged: (value) {
Expand Down Expand Up @@ -414,6 +415,7 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
utxo.isConfirmed(
currentHeight,
minConfirms,
coin.minCoinbaseConfirms,
)),
initialSelectedState: isSelected,
onSelectedChanged: (value) {
Expand Down Expand Up @@ -558,6 +560,7 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
utxo.isConfirmed(
currentHeight,
minConfirms,
coin.minCoinbaseConfirms,
)),
initialSelectedState: isSelected,
onSelectedChanged: (value) {
Expand Down
5 changes: 5 additions & 0 deletions lib/pages/coin_control/utxo_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ class _UtxoCardState extends ConsumerState<UtxoCard> {
.getWallet(widget.walletId)
.cryptoCurrency
.minConfirms,
ref
.watch(pWallets)
.getWallet(widget.walletId)
.cryptoCurrency
.minCoinbaseConfirms,
)
? UTXOStatusIconStatus.confirmed
: UTXOStatusIconStatus.unconfirmed,
Expand Down
5 changes: 5 additions & 0 deletions lib/pages/coin_control/utxo_details_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ class _UtxoDetailsViewState extends ConsumerState<UtxoDetailsView> {
final confirmed = utxo!.isConfirmed(
currentHeight,
ref.watch(pWallets).getWallet(widget.walletId).cryptoCurrency.minConfirms,
ref
.watch(pWallets)
.getWallet(widget.walletId)
.cryptoCurrency
.minCoinbaseConfirms,
);

return ConditionalParent(
Expand Down
6 changes: 6 additions & 0 deletions lib/pages/wallet_view/sub_widgets/tx_icon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';

import '../../../models/isar/models/blockchain_data/v2/transaction_v2.dart';
import '../../../models/isar/models/isar_models.dart';
import '../../../models/isar/stack_theme.dart';
Expand Down Expand Up @@ -106,6 +107,11 @@ class TxIcon extends ConsumerWidget {
!tx.isConfirmed(
currentHeight,
ref.watch(pWallets).getWallet(tx.walletId).cryptoCurrency.minConfirms,
ref
.watch(pWallets)
.getWallet(tx.walletId)
.cryptoCurrency
.minCoinbaseConfirms,
),
tx.subType,
tx.type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:isar/isar.dart';

import '../../../../models/isar/models/blockchain_data/v2/transaction_v2.dart';
import '../../../../models/isar/models/contact_entry.dart';
import '../../../../models/isar/models/isar_models.dart';
import '../../../../models/transaction_filter.dart';
import '../../sub_widgets/tx_icon.dart';
import '../transaction_search_filter_view.dart';
import 'transaction_v2_card.dart';
import 'transaction_v2_details_view.dart';
import '../../../../providers/db/main_db_provider.dart';
import '../../../../providers/global/address_book_service_provider.dart';
import '../../../../providers/providers.dart';
Expand All @@ -49,6 +46,10 @@ import '../../../../widgets/loading_indicator.dart';
import '../../../../widgets/rounded_white_container.dart';
import '../../../../widgets/stack_text_field.dart';
import '../../../../widgets/textfield_icon_button.dart';
import '../../sub_widgets/tx_icon.dart';
import '../transaction_search_filter_view.dart';
import 'transaction_v2_card.dart';
import 'transaction_v2_details_view.dart';

typedef _GroupedTransactions = ({
String label,
Expand Down Expand Up @@ -866,6 +867,11 @@ class _DesktopTransactionCardRowState
String whatIsIt(TransactionV2 tx, int height) => tx.statusLabel(
currentChainHeight: height,
minConfirms: minConfirms,
minCoinbaseConfirms: ref
.read(pWallets)
.getWallet(widget.walletId)
.cryptoCurrency
.minCoinbaseConfirms,
);

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> {
.getWallet(walletId)
.cryptoCurrency
.minConfirms,
minCoinbaseConfirms: ref
.read(pWallets)
.getWallet(walletId)
.cryptoCurrency
.minCoinbaseConfirms,
);

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,11 @@ class _TransactionV2DetailsViewState
String whatIsIt(TransactionV2 tx, int height) => tx.statusLabel(
currentChainHeight: height,
minConfirms: minConfirms,
minCoinbaseConfirms: ref
.read(pWallets)
.getWallet(walletId)
.cryptoCurrency
.minCoinbaseConfirms,
);

Future<String> fetchContactNameFor(String address) async {
Expand Down Expand Up @@ -567,6 +572,7 @@ class _TransactionV2DetailsViewState
final confirmedTxn = _transaction.isConfirmed(
currentHeight,
coin.minConfirms,
coin.minCoinbaseConfirms,
);

return ConditionalParent(
Expand Down Expand Up @@ -1367,6 +1373,7 @@ class _TransactionV2DetailsViewState
? _transaction.isConfirmed(
currentHeight,
minConfirms,
coin.minCoinbaseConfirms,
)
? ref
.watch(pAmountFormatter(coin))
Expand Down Expand Up @@ -1484,9 +1491,9 @@ class _TransactionV2DetailsViewState
height = "Unknown";
} else {
final confirmed = _transaction.isConfirmed(
currentHeight,
minConfirms,
);
currentHeight,
minConfirms,
coin.minCoinbaseConfirms);
if (widget.coin is! Epiccash && confirmed) {
height =
"${_transaction.height == 0 ? "Unknown" : _transaction.height}";
Expand Down
6 changes: 6 additions & 0 deletions lib/pages_desktop_specific/coin_control/utxo_row.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';

import '../../db/isar/main_db.dart';
import '../../models/isar/models/isar_models.dart';
import '../../pages/coin_control/utxo_details_view.dart';
Expand Down Expand Up @@ -141,6 +142,11 @@ class _UtxoRowState extends ConsumerState<UtxoRow> {
.getWallet(widget.walletId)
.cryptoCurrency
.minConfirms,
ref
.watch(pWallets)
.getWallet(widget.walletId)
.cryptoCurrency
.minCoinbaseConfirms,
)
? UTXOStatusIconStatus.confirmed
: UTXOStatusIconStatus.unconfirmed,
Expand Down
3 changes: 3 additions & 0 deletions lib/wallets/crypto_currency/coins/firo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ class Firo extends Bip39HDCurrency with ElectrumXCurrencyInterface {
@override
int get minConfirms => 1;

@override
int get minCoinbaseConfirms => 100;

@override
bool get torSupport => true;

Expand Down
1 change: 1 addition & 0 deletions lib/wallets/crypto_currency/crypto_currency.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ abstract class CryptoCurrency {
bool get torSupport => false;

int get minConfirms;
int get minCoinbaseConfirms => minConfirms;

// TODO: [prio=low] could be handled differently as (at least) epiccash does not use this
String get genesisHash;
Expand Down
14 changes: 12 additions & 2 deletions lib/wallets/wallet/impl/bitcoin_frost_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class BitcoinFrostWallet<T extends FrostCurrency> extends Wallet<T>
(e) => !e.isConfirmed(
currentHeight,
cryptoCurrency.minConfirms,
cryptoCurrency.minCoinbaseConfirms,
),
);
if (utxos.isEmpty) {
Expand Down Expand Up @@ -330,7 +331,11 @@ class BitcoinFrostWallet<T extends FrostCurrency> extends Wallet<T>
final height = await chainHeight;
for (final output in (await mainDB.getUTXOs(walletId).findAll())) {
if (!output.isBlocked &&
output.isConfirmed(height, cryptoCurrency.minConfirms)) {
output.isConfirmed(
height,
cryptoCurrency.minConfirms,
cryptoCurrency.minCoinbaseConfirms,
)) {
available += output.value;
inputCount++;
}
Expand Down Expand Up @@ -448,7 +453,11 @@ class BitcoinFrostWallet<T extends FrostCurrency> extends Wallet<T>
.findFirst();

if (storedTx == null ||
!storedTx.isConfirmed(currentHeight, cryptoCurrency.minConfirms)) {
!storedTx.isConfirmed(
currentHeight,
cryptoCurrency.minConfirms,
cryptoCurrency.minCoinbaseConfirms,
)) {
final tx = await electrumXCachedClient.getTransaction(
txHash: txHash["tx_hash"] as String,
verbose: true,
Expand Down Expand Up @@ -1060,6 +1069,7 @@ class BitcoinFrostWallet<T extends FrostCurrency> extends Wallet<T>
if (utxo.isConfirmed(
currentChainHeight,
cryptoCurrency.minConfirms,
cryptoCurrency.minCoinbaseConfirms,
)) {
satoshiBalanceSpendable += utxoAmount;
} else {
Expand Down
6 changes: 5 additions & 1 deletion lib/wallets/wallet/impl/firo_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,11 @@ class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
);

if (_unconfirmedTxids.contains(tx.txid)) {
if (tx.isConfirmed(await chainHeight, cryptoCurrency.minConfirms)) {
if (tx.isConfirmed(
await chainHeight,
cryptoCurrency.minConfirms,
cryptoCurrency.minCoinbaseConfirms,
)) {
txns.add(tx);
_unconfirmedTxids.removeWhere((e) => e == tx.txid);
} else {
Expand Down
1 change: 1 addition & 0 deletions lib/wallets/wallet/intermediate/bip39_hd_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ abstract class Bip39HDWallet<T extends Bip39HDCurrency> extends Bip39Wallet<T>
if (utxo.isConfirmed(
currentChainHeight,
cryptoCurrency.minConfirms,
cryptoCurrency.minCoinbaseConfirms,
)) {
satoshiBalanceSpendable += utxoAmount;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ mixin ElectrumXInterface<T extends ElectrumXCurrencyInterface>
e.isConfirmed(
currentChainHeight,
cryptoCurrency.minConfirms,
cryptoCurrency.minCoinbaseConfirms,
)),
)
.toList();
Expand Down Expand Up @@ -1920,6 +1921,7 @@ mixin ElectrumXInterface<T extends ElectrumXCurrencyInterface>
e.isConfirmed(
info.cachedChainHeight,
cryptoCurrency.minConfirms,
cryptoCurrency.minCoinbaseConfirms,
),
)
.toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,7 @@ mixin LelantusInterface<T extends ElectrumXCurrencyInterface>
if (availableOutputs[i].isConfirmed(
currentChainHeight,
cryptoCurrency.minConfirms,
cryptoCurrency.minCoinbaseConfirms,
) ==
true &&
!(availableOutputs[i].isCoinbase &&
Expand Down
Loading
Loading