Bitcoin Core 28.99.0
P2P Digital Currency
bantablemodel.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2022 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <qt/bantablemodel.h>
6
7#include <interfaces/node.h>
8#include <net_types.h> // For banmap_t
9
10#include <utility>
11
12#include <QDateTime>
13#include <QList>
14#include <QLocale>
15#include <QModelIndex>
16#include <QVariant>
17
18bool BannedNodeLessThan::operator()(const CCombinedBan& left, const CCombinedBan& right) const
19{
20 const CCombinedBan* pLeft = &left;
21 const CCombinedBan* pRight = &right;
22
23 if (order == Qt::DescendingOrder)
24 std::swap(pLeft, pRight);
25
26 switch (static_cast<BanTableModel::ColumnIndex>(column)) {
28 return pLeft->subnet.ToString().compare(pRight->subnet.ToString()) < 0;
30 return pLeft->banEntry.nBanUntil < pRight->banEntry.nBanUntil;
31 } // no default case, so the compiler can warn about missing cases
32 assert(false);
33}
34
35// private implementation
37{
38public:
40 QList<CCombinedBan> cachedBanlist;
42 int sortColumn{-1};
44 Qt::SortOrder sortOrder;
45
48 {
49 banmap_t banMap;
50 node.getBanned(banMap);
51
52 cachedBanlist.clear();
53 cachedBanlist.reserve(banMap.size());
54 for (const auto& entry : banMap)
55 {
56 CCombinedBan banEntry;
57 banEntry.subnet = entry.first;
58 banEntry.banEntry = entry.second;
59 cachedBanlist.append(banEntry);
60 }
61
62 if (sortColumn >= 0)
63 // sort cachedBanlist (use stable sort to prevent rows jumping around unnecessarily)
64 std::stable_sort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder));
65 }
66
67 int size() const
68 {
69 return cachedBanlist.size();
70 }
71
73 {
74 if (idx >= 0 && idx < cachedBanlist.size())
75 return &cachedBanlist[idx];
76
77 return nullptr;
78 }
79};
80
82 QAbstractTableModel(parent),
84{
85 columns << tr("IP/Netmask") << tr("Banned Until");
86 priv.reset(new BanTablePriv());
87
88 // load initial data
89 refresh();
90}
91
93
94int BanTableModel::rowCount(const QModelIndex &parent) const
95{
96 if (parent.isValid()) {
97 return 0;
98 }
99 return priv->size();
100}
101
102int BanTableModel::columnCount(const QModelIndex &parent) const
103{
104 if (parent.isValid()) {
105 return 0;
106 }
107 return columns.length();
108}
109
110QVariant BanTableModel::data(const QModelIndex &index, int role) const
111{
112 if(!index.isValid())
113 return QVariant();
114
115 CCombinedBan *rec = static_cast<CCombinedBan*>(index.internalPointer());
116
117 const auto column = static_cast<ColumnIndex>(index.column());
118 if (role == Qt::DisplayRole) {
119 switch (column) {
120 case Address:
121 return QString::fromStdString(rec->subnet.ToString());
122 case Bantime:
123 QDateTime date = QDateTime::fromMSecsSinceEpoch(0);
124 date = date.addSecs(rec->banEntry.nBanUntil);
125 return QLocale::system().toString(date, QLocale::LongFormat);
126 } // no default case, so the compiler can warn about missing cases
127 assert(false);
128 }
129
130 return QVariant();
131}
132
133QVariant BanTableModel::headerData(int section, Qt::Orientation orientation, int role) const
134{
135 if(orientation == Qt::Horizontal)
136 {
137 if(role == Qt::DisplayRole && section < columns.size())
138 {
139 return columns[section];
140 }
141 }
142 return QVariant();
143}
144
145Qt::ItemFlags BanTableModel::flags(const QModelIndex &index) const
146{
147 if (!index.isValid()) return Qt::NoItemFlags;
148
149 Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
150 return retval;
151}
152
153QModelIndex BanTableModel::index(int row, int column, const QModelIndex &parent) const
154{
155 Q_UNUSED(parent);
156 CCombinedBan *data = priv->index(row);
157
158 if (data)
159 return createIndex(row, column, data);
160 return QModelIndex();
161}
162
164{
165 Q_EMIT layoutAboutToBeChanged();
166 priv->refreshBanlist(m_node);
167 Q_EMIT layoutChanged();
168}
169
170void BanTableModel::sort(int column, Qt::SortOrder order)
171{
172 priv->sortColumn = column;
173 priv->sortOrder = order;
174 refresh();
175}
176
178{
179 return priv->size() > 0;
180}
181
182bool BanTableModel::unban(const QModelIndex& index)
183{
184 CCombinedBan* ban{static_cast<CCombinedBan*>(index.internalPointer())};
185 return ban != nullptr && m_node.unban(ban->subnet);
186}
node::NodeContext m_node
Definition: bitcoin-gui.cpp:42
std::unique_ptr< BanTablePriv > priv
Definition: bantablemodel.h:79
QVariant data(const QModelIndex &index, int role) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
interfaces::Node & m_node
Definition: bantablemodel.h:77
int columnCount(const QModelIndex &parent) const override
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
void sort(int column, Qt::SortOrder order) override
int rowCount(const QModelIndex &parent) const override
bool unban(const QModelIndex &index)
QStringList columns
Definition: bantablemodel.h:78
QModelIndex index(int row, int column, const QModelIndex &parent) const override
BanTableModel(interfaces::Node &node, QObject *parent)
int sortColumn
Column to sort nodes by (default to unsorted)
void refreshBanlist(interfaces::Node &node)
Pull a full list of banned nodes from interfaces::Node into our cache.
Qt::SortOrder sortOrder
Order (ascending or descending) to sort nodes by.
QList< CCombinedBan > cachedBanlist
Local cache of peer information.
CCombinedBan * index(int idx)
int size() const
Qt::SortOrder order
Definition: bantablemodel.h:36
bool operator()(const CCombinedBan &left, const CCombinedBan &right) const
int64_t nBanUntil
Definition: net_types.h:20
std::string ToString() const
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:71
virtual bool unban(const CSubNet &ip)=0
Unban node.
Definition: messages.h:20
std::map< CSubNet, CBanEntry > banmap_t
Definition: net_types.h:41
CBanEntry banEntry
Definition: bantablemodel.h:24
CSubNet subnet
Definition: bantablemodel.h:23
assert(!tx.IsCoinBase())