Repository: bitcoin/bitcoin
File: src/qt/transactionview.cpp (C++)

Code before:
    // check if transaction can be abandoned, disable context menu action in case it doesn't
    uint256 hash;
    hash.SetHexDeprecated(selection.at(0).data(TransactionTableModel::TxHashRole).toString().toStdString());
    abandonAction->setEnabled(model->wallet().transactionCanBeAbandoned(hash));
    bumpFeeAction->setEnabled(model->wallet().transactionCanBeBumped(hash));
    copyAddressAction->setEnabled(GUIUtil::hasEntryData(transactionView, 0, TransactionTableModel::AddressRole));
    copyLabelAction->setEnabled(GUIUtil::hasEntryData(transactionView, 0, TransactionTableModel::LabelRole));

    if (index.isValid()) {
        GUIUtil::PopupMenu(contextMenu, transactionView->viewport()->mapToGlobal(point));
    }
}

void TransactionView::abandonTx()
{
    if(!transactionView || !transactionView->selectionModel())
        return;
    QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);

    // get the hash from the TxHashRole (QVariant / QString)
    uint256 hash;
    QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
    hash.SetHexDeprecated(hashQStr.toStdString());

    // Abandon the wallet transaction over the walletModel
    model->wallet().abandonTransaction(hash);
}

void TransactionView::bumpFee([[maybe_unused]] bool checked)
{
    if(!transactionView || !transactionView->selectionModel())
        return;
    QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);

    // get the hash from the TxHashRole (QVariant / QString)
    uint256 hash;
    QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
    hash.SetHexDeprecated(hashQStr.toStdString());

    // Bump tx fee over the walletModel
    uint256 newHash;
    if (model->bumpFee(hash, newHash)) {
        // Update the table
        transactionView->selectionModel()->clearSelection();
        model->getTransactionTableModel()->updateTransaction(hashQStr, CT_UPDATED, true);

        qApp->processEvents();
        Q_EMIT bumpedFee(newHash);
    }
}


Review comment (suggestion):
Seems fine, same reasoning about `.data()` as before. Plus if we get here, the context menu was enabled.

Code after:
    // If the hash from the TxHashRole (QVariant / QString) is invalid, exit
    QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
    std::optional<Txid> maybeHash = Txid::FromHex(hashQStr.toStdString());
    if (!maybeHash)
        return;

    Txid hash = *maybeHash;
    abandonAction->setEnabled(model->wallet().transactionCanBeAbandoned(hash));
    bumpFeeAction->setEnabled(model->wallet().transactionCanBeBumped(hash));
    copyAddressAction->setEnabled(GUIUtil::hasEntryData(transactionView, 0, TransactionTableModel::AddressRole));
    copyLabelAction->setEnabled(GUIUtil::hasEntryData(transactionView, 0, TransactionTableModel::LabelRole));

    if (index.isValid()) {
        GUIUtil::PopupMenu(contextMenu, transactionView->viewport()->mapToGlobal(point));
    }
}

void TransactionView::abandonTx()
{
    if(!transactionView || !transactionView->selectionModel())
        return;
    QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);

    // get the hash from the TxHashRole (QVariant / QString)
    QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
    Txid hash = Txid::FromHex(hashQStr.toStdString()).value();

    // Abandon the wallet transaction over the walletModel
    model->wallet().abandonTransaction(hash);
}

void TransactionView::bumpFee([[maybe_unused]] bool checked)
{
    if(!transactionView || !transactionView->selectionModel())
        return;
    QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);

    // get the hash from the TxHashRole (QVariant / QString)
    QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
    Txid hash = Txid::FromHex(hashQStr.toStdString()).value();

    // Bump tx fee over the walletModel
    uint256 newHash;
    if (model->bumpFee(hash, newHash)) {
        // Update the table
        transactionView->selectionModel()->clearSelection();
        model->getTransactionTableModel()->updateTransaction(hashQStr, CT_UPDATED, true);

        qApp->processEvents();
        Q_EMIT bumpedFee(newHash);
    }