diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index 353e344c6..dd6cd0c0c 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -1,167 +1,169 @@ // Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include // For banmap_t -#include #include -#include +#include #include +#include +#include +#include bool BannedNodeLessThan::operator()(const CCombinedBan &left, const CCombinedBan &right) const { const CCombinedBan *pLeft = &left; const CCombinedBan *pRight = &right; if (order == Qt::DescendingOrder) { std::swap(pLeft, pRight); } switch (column) { case BanTableModel::Address: return pLeft->subnet.ToString().compare(pRight->subnet.ToString()) < 0; case BanTableModel::Bantime: return pLeft->banEntry.nBanUntil < pRight->banEntry.nBanUntil; } return false; } // private implementation class BanTablePriv { public: /** Local cache of peer information */ QList cachedBanlist; /** Column to sort nodes by (default to unsorted) */ int sortColumn{-1}; /** Order (ascending or descending) to sort nodes by */ Qt::SortOrder sortOrder; /** Pull a full list of banned nodes from CNode into our cache */ void refreshBanlist(interfaces::Node &node) { banmap_t banMap; node.getBanned(banMap); cachedBanlist.clear(); cachedBanlist.reserve(banMap.size()); for (const auto &entry : banMap) { CCombinedBan banEntry; banEntry.subnet = entry.first; banEntry.banEntry = entry.second; cachedBanlist.append(banEntry); } if (sortColumn >= 0) { // sort cachedBanlist (use stable sort to prevent rows jumping // around unnecessarily) std::stable_sort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); } } int size() const { return cachedBanlist.size(); } CCombinedBan *index(int idx) { if (idx >= 0 && idx < cachedBanlist.size()) { return &cachedBanlist[idx]; } return nullptr; } }; -BanTableModel::BanTableModel(interfaces::Node &node, ClientModel *parent) - : QAbstractTableModel(parent), m_node(node), clientModel(parent) { +BanTableModel::BanTableModel(interfaces::Node &node, QObject *parent) + : QAbstractTableModel(parent), m_node(node) { columns << tr("IP/Netmask") << tr("Banned Until"); priv.reset(new BanTablePriv()); // load initial data refresh(); } BanTableModel::~BanTableModel() { // Intentionally left empty } int BanTableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return priv->size(); } int BanTableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return columns.length(); } QVariant BanTableModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } CCombinedBan *rec = static_cast(index.internalPointer()); if (role == Qt::DisplayRole) { switch (index.column()) { case Address: return QString::fromStdString(rec->subnet.ToString()); case Bantime: QDateTime date = QDateTime::fromMSecsSinceEpoch(0); date = date.addSecs(rec->banEntry.nBanUntil); return date.toString(QLocale().dateTimeFormat()); } } return QVariant(); } QVariant BanTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole && section < columns.size()) { return columns[section]; } } return QVariant(); } Qt::ItemFlags BanTableModel::flags(const QModelIndex &index) const { if (!index.isValid()) { return Qt::NoItemFlags; } Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; return retval; } QModelIndex BanTableModel::index(int row, int column, const QModelIndex &parent) const { Q_UNUSED(parent); CCombinedBan *data = priv->index(row); if (data) { return createIndex(row, column, data); } return QModelIndex(); } void BanTableModel::refresh() { Q_EMIT layoutAboutToBeChanged(); priv->refreshBanlist(m_node); Q_EMIT layoutChanged(); } void BanTableModel::sort(int column, Qt::SortOrder order) { priv->sortColumn = column; priv->sortOrder = order; refresh(); } bool BanTableModel::shouldShow() { return priv->size() > 0; } diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h index bcad2ab5c..f6663b641 100644 --- a/src/qt/bantablemodel.h +++ b/src/qt/bantablemodel.h @@ -1,78 +1,75 @@ // Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_BANTABLEMODEL_H #define BITCOIN_QT_BANTABLEMODEL_H #include #include #include #include -class ClientModel; class BanTablePriv; namespace interfaces { class Node; } struct CCombinedBan { CSubNet subnet; CBanEntry banEntry; }; class BannedNodeLessThan { public: BannedNodeLessThan(int nColumn, Qt::SortOrder fOrder) : column(nColumn), order(fOrder) {} bool operator()(const CCombinedBan &left, const CCombinedBan &right) const; private: int column; Qt::SortOrder order; }; /** Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call. Used by the rpc console UI. */ class BanTableModel : public QAbstractTableModel { Q_OBJECT public: - explicit BanTableModel(interfaces::Node &node, - ClientModel *parent = nullptr); + explicit BanTableModel(interfaces::Node &node, QObject *parent); ~BanTableModel(); void startAutoRefresh(); void stopAutoRefresh(); enum ColumnIndex { Address = 0, Bantime = 1 }; /** @name Methods overridden from QAbstractTableModel @{*/ int rowCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QModelIndex index(int row, int column, const QModelIndex &parent) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; void sort(int column, Qt::SortOrder order) override; bool shouldShow(); /*@}*/ public Q_SLOTS: void refresh(); private: interfaces::Node &m_node; - ClientModel *clientModel; QStringList columns; std::unique_ptr priv; }; #endif // BITCOIN_QT_BANTABLEMODEL_H diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh index d57a0fb65..f551eb520 100755 --- a/test/lint/lint-circular-dependencies.sh +++ b/test/lint/lint-circular-dependencies.sh @@ -1,84 +1,83 @@ #!/usr/bin/env bash # # Copyright (c) 2018 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # # Check for circular dependencies export LC_ALL=C set -euo pipefail : "${TOPLEVEL:=$(git rev-parse --show-toplevel)}" EXPECTED_CIRCULAR_DEPENDENCIES=( "index/txindex -> validation -> index/txindex" "qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel" - "qt/bantablemodel -> qt/clientmodel -> qt/bantablemodel" "qt/bitcoingui -> qt/utilitydialog -> qt/bitcoingui" "qt/bitcoingui -> qt/walletframe -> qt/bitcoingui" "qt/bitcoingui -> qt/walletview -> qt/bitcoingui" "qt/clientmodel -> qt/peertablemodel -> qt/clientmodel" "qt/recentrequeststablemodel -> qt/walletmodel -> qt/recentrequeststablemodel" "qt/transactiontablemodel -> qt/walletmodel -> qt/transactiontablemodel" "txmempool -> validation -> txmempool" "wallet/fees -> wallet/wallet -> wallet/fees" "wallet/rpcwallet -> wallet/wallet -> wallet/rpcwallet" "wallet/wallet -> wallet/walletdb -> wallet/wallet" "avalanche/processor -> validation -> avalanche/processor" "avalanche/processor -> net_processing -> avalanche/processor" "chainparams -> protocol -> chainparams" "chainparamsbase -> util/system -> chainparamsbase" "minerfund -> validation -> minerfund" "script/scriptcache -> validation -> script/scriptcache" "seeder/bitcoin -> seeder/db -> seeder/bitcoin" "chainparams -> protocol -> config -> chainparams" "checkpoints -> validation -> checkpoints" "pow/aserti32d -> validation -> pow/aserti32d" "pow/aserti32d -> validation -> pow/pow -> pow/aserti32d" ) EXIT_CODE=0 CIRCULAR_DEPENDENCIES=() pushd "${TOPLEVEL}" IFS=$'\n' for CIRC in $(cd src && ../contrib/devtools/circular-dependencies.py {*,*/*,*/*/*}.{h,cpp} | sed -e 's/^Circular dependency: //'); do CIRCULAR_DEPENDENCIES+=("$CIRC") IS_EXPECTED_CIRC=0 for EXPECTED_CIRC in "${EXPECTED_CIRCULAR_DEPENDENCIES[@]}"; do if [[ "${CIRC}" == "${EXPECTED_CIRC}" ]]; then IS_EXPECTED_CIRC=1 break fi done if [[ ${IS_EXPECTED_CIRC} == 0 ]]; then echo "A new circular dependency in the form of \"${CIRC}\" appears to have been introduced." echo EXIT_CODE=1 fi done for EXPECTED_CIRC in "${EXPECTED_CIRCULAR_DEPENDENCIES[@]}"; do IS_PRESENT_EXPECTED_CIRC=0 for CIRC in "${CIRCULAR_DEPENDENCIES[@]}"; do if [[ "${CIRC}" == "${EXPECTED_CIRC}" ]]; then IS_PRESENT_EXPECTED_CIRC=1 break fi done if [[ ${IS_PRESENT_EXPECTED_CIRC} == 0 ]]; then echo "Good job! The circular dependency \"${EXPECTED_CIRC}\" is no longer present." echo "Please remove it from EXPECTED_CIRCULAR_DEPENDENCIES in $0" echo "to make sure this circular dependency is not accidentally reintroduced." echo EXIT_CODE=1 fi done popd exit ${EXIT_CODE}