@ -0,0 +1,5 @@ |
|||
# The Hush Developers |
|||
|
|||
Duke Leto https://git.hush.is/duke https://github.com/leto |
|||
Jane Mercer https://git.hush.is/radix42 https://github.com/radix42 |
|||
|
@ -1,6 +0,0 @@ |
|||
<html> |
|||
<head></head> |
|||
<body> |
|||
Hello World |
|||
</body> |
|||
</html> |
@ -1,21 +0,0 @@ |
|||
#!/bin/bash |
|||
# Copyright (c) 2019 Hush developers |
|||
|
|||
# set working directory to the location of this script |
|||
# readlink -f does not always exist |
|||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" |
|||
cd $DIR |
|||
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )" |
|||
cd $DIR |
|||
|
|||
NAME=HUSH3 |
|||
|
|||
CLI=${KOMODOCLI:-./komodo-cli} |
|||
if [ -f $CLI ]; then |
|||
$CLI -ac_name=$NAME "$@" |
|||
else |
|||
# We prefix our binary when installed |
|||
# system wide on Debain system, to prevent clashes |
|||
CLI=hush-komodo-cli |
|||
$CLI -ac_name=$NAME "$@" |
|||
fi |
After Width: | Height: | Size: 499 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 416 KiB |
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 33 KiB |
@ -1,13 +0,0 @@ |
|||
This directory contains the hashes and signatures for SilentDargon |
|||
|
|||
Verify the hashes by running: |
|||
sha256sum -c sha256sum-vX.Y.Z.txt |
|||
|
|||
Verify signatures: |
|||
1. First, import the public key (Available on GitHub |
|||
at https://github.com/ZcashFoundation/zecwallet/blob/master/public_key.asc) |
|||
gpg --import public_key.asc |
|||
|
|||
2. Verify signature |
|||
gpg --verify <filename.sig> <downloaded-filename-to-verify> |
|||
|
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 74 KiB |
@ -1,4 +1,4 @@ |
|||
#!/bin/bash |
|||
# Copyright 2019-2020 The Hush Developers |
|||
# Copyright 2019-2021 The Hush Developers |
|||
|
|||
./build.sh && ./silentdragon |
|||
|
Before Width: | Height: | Size: 62 KiB |
@ -0,0 +1,128 @@ |
|||
// Copyright 2019-2021 The Hush developers
|
|||
// Released under the GPLv3
|
|||
#include "settings.h" |
|||
#include "rpc.h" |
|||
|
|||
BannedPeersTableModel::BannedPeersTableModel(QObject *parent) |
|||
: QAbstractTableModel(parent) { |
|||
headers << QObject::tr("Address") << QObject::tr("Subnet") << QObject::tr("Banned Until"); |
|||
} |
|||
|
|||
BannedPeersTableModel::~BannedPeersTableModel() { |
|||
delete modeldata; |
|||
} |
|||
|
|||
void BannedPeersTableModel::addData(const QList<BannedPeerItem>& data) { |
|||
bannedPeers = new QList<BannedPeerItem>(); |
|||
std::copy(data.begin(), data.end(), std::back_inserter(*bannedPeers)); |
|||
|
|||
updateAllData(); |
|||
} |
|||
|
|||
void BannedPeersTableModel::updateAllData() { |
|||
auto newmodeldata = new QList<BannedPeerItem>(); |
|||
|
|||
// Copy peer data so GUI can use it
|
|||
if (bannedPeers != nullptr) std::copy( bannedPeers->begin(), bannedPeers->end(), std::back_inserter(*newmodeldata)); |
|||
|
|||
// Sort by banned_until
|
|||
std::sort(newmodeldata->begin(), newmodeldata->end(), [=] (auto a, auto b) { |
|||
return a.banned_until > b.banned_until; // reverse sort
|
|||
}); |
|||
|
|||
// And then swap out the modeldata with the new one.
|
|||
delete modeldata; |
|||
modeldata = newmodeldata; |
|||
|
|||
// do magic
|
|||
dataChanged(index(0, 0), index(modeldata->size()-1, columnCount(index(0,0))-1)); |
|||
layoutChanged(); |
|||
} |
|||
|
|||
int BannedPeersTableModel::rowCount(const QModelIndex&) const |
|||
{ |
|||
if (modeldata == nullptr) return 0; |
|||
return modeldata->size(); |
|||
} |
|||
|
|||
int BannedPeersTableModel::columnCount(const QModelIndex&) const |
|||
{ |
|||
return headers.size(); |
|||
} |
|||
|
|||
|
|||
QVariant BannedPeersTableModel::data(const QModelIndex &index, int role) const |
|||
{ |
|||
auto dat = modeldata->at(index.row()); |
|||
if (role == Qt::DisplayRole) { |
|||
switch (index.column()) { |
|||
case 0: return dat.address; |
|||
case 1: return dat.subnet; |
|||
case 2: return QDateTime::fromSecsSinceEpoch(dat.banned_until).toLocalTime().toString(); |
|||
} |
|||
} |
|||
|
|||
// we show mask because it's possible to ban ranges of addresses
|
|||
if (role == Qt::ToolTipRole) { |
|||
switch (index.column()) { |
|||
case 0: return "Network Address"; |
|||
case 1: return "Subnet Mask"; |
|||
case 2: return "Banned Until " + QDateTime::fromSecsSinceEpoch(dat.banned_until).toUTC().toString(); |
|||
} |
|||
} |
|||
|
|||
//TODO: show different icons for IP vs Tor vs other kinds of connections
|
|||
/*
|
|||
if (role == Qt::DecorationRole && index.column() == 0) { |
|||
if (!dat.memo.isEmpty()) { |
|||
// If the memo is a Payment URI, then show a payment request icon
|
|||
if (dat.memo.startsWith("hush:")) { |
|||
QIcon icon(":/icons/res/paymentreq.gif"); |
|||
return QVariant(icon.pixmap(16, 16)); |
|||
} else { |
|||
// Return the info pixmap to indicate memo
|
|||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); |
|||
return QVariant(icon.pixmap(16, 16)); |
|||
} |
|||
} else { |
|||
// Empty pixmap to make it align
|
|||
QPixmap p(16, 16); |
|||
p.fill(Qt::white); |
|||
return QVariant(p); |
|||
} |
|||
} |
|||
*/ |
|||
|
|||
return QVariant(); |
|||
} |
|||
|
|||
|
|||
QVariant BannedPeersTableModel::headerData(int section, Qt::Orientation orientation, int role) const |
|||
{ |
|||
//if (role == Qt::TextAlignmentRole && section == 3) return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
|||
if (role == Qt::TextAlignmentRole) return QVariant(Qt::AlignCenter | Qt::AlignVCenter); |
|||
|
|||
if (role == Qt::FontRole) { |
|||
QFont f; |
|||
f.setBold(true); |
|||
return f; |
|||
} |
|||
|
|||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { |
|||
return headers.at(section); |
|||
} |
|||
|
|||
return QVariant(); |
|||
} |
|||
|
|||
QString BannedPeersTableModel::getAddress(int row) const { |
|||
return modeldata->at(row).address.trimmed(); |
|||
} |
|||
|
|||
QString BannedPeersTableModel::getSubnet(int row) const { |
|||
return modeldata->at(row).subnet; |
|||
} |
|||
|
|||
qint64 BannedPeersTableModel::getBannedUntil(int row) const { |
|||
return modeldata->at(row).banned_until; |
|||
} |
@ -0,0 +1,36 @@ |
|||
// Copyright 2019-2021 The Hush developers
|
|||
// Released under the GPLv3
|
|||
#ifndef BANNEDPEERSTABLEMODEL_H |
|||
#define BANNEDPEERSTABLEMODEL_H |
|||
|
|||
#include "precompiled.h" |
|||
|
|||
struct BannedPeerItem; |
|||
|
|||
class BannedPeersTableModel: public QAbstractTableModel |
|||
{ |
|||
public: |
|||
BannedPeersTableModel(QObject* parent); |
|||
~BannedPeersTableModel(); |
|||
|
|||
QString getSubnet(int row) const; |
|||
QString getAddress(int row) const; |
|||
qint64 getBannedUntil(int row) const; |
|||
|
|||
int rowCount(const QModelIndex &parent) const; |
|||
int columnCount(const QModelIndex &parent) const; |
|||
QVariant data(const QModelIndex &index, int role) const; |
|||
QVariant headerData(int section, Qt::Orientation orientation, int role) const; |
|||
|
|||
void addData (const QList<BannedPeerItem>& data); |
|||
|
|||
private: |
|||
void updateAllData(); |
|||
QList<BannedPeerItem>* bannedPeers = nullptr; |
|||
QList<BannedPeerItem>* modeldata = nullptr; |
|||
|
|||
QList<QString> headers; |
|||
}; |
|||
|
|||
|
|||
#endif // BANNEDPEERSTABLEMODEL_H
|
@ -0,0 +1,178 @@ |
|||
// Copyright 2019-2021 The Hush developers
|
|||
// Released under the GPLv3
|
|||
#include "txtablemodel.h" |
|||
#include "settings.h" |
|||
#include "rpc.h" |
|||
|
|||
PeersTableModel::PeersTableModel(QObject *parent) |
|||
: QAbstractTableModel(parent) { |
|||
headers << QObject::tr("PeerID") << QObject::tr("Address") << QObject::tr("ASN") << QObject::tr("TLS Cipher") << QObject::tr("TLS Verfied") << QObject::tr("Version") << QObject::tr("Protocol Version") << QObject::tr("Ping Time") << QObject::tr("Banscore") << QObject::tr("Bytes received") << QObject::tr("Bytes sent"); |
|||
} |
|||
|
|||
PeersTableModel::~PeersTableModel() { |
|||
delete modeldata; |
|||
} |
|||
|
|||
void PeersTableModel::addData(const QList<PeerItem>& data) { |
|||
peers = new QList<PeerItem>(); |
|||
std::copy(data.begin(), data.end(), std::back_inserter(*peers)); |
|||
|
|||
updateAllData(); |
|||
} |
|||
|
|||
void PeersTableModel::updateAllData() { |
|||
auto newmodeldata = new QList<PeerItem>(); |
|||
|
|||
// Copy peer data so GUI can use it
|
|||
if (peers != nullptr) std::copy( peers->begin(), peers->end(), std::back_inserter(*newmodeldata)); |
|||
|
|||
// Sort by connection time
|
|||
std::sort(newmodeldata->begin(), newmodeldata->end(), [=] (auto a, auto b) { |
|||
return a.conntime > b.conntime; // reverse sort
|
|||
}); |
|||
|
|||
// And then swap out the modeldata with the new one.
|
|||
delete modeldata; |
|||
modeldata = newmodeldata; |
|||
|
|||
// do magic
|
|||
dataChanged(index(0, 0), index(modeldata->size()-1, columnCount(index(0,0))-1)); |
|||
layoutChanged(); |
|||
} |
|||
|
|||
int PeersTableModel::rowCount(const QModelIndex&) const |
|||
{ |
|||
if (modeldata == nullptr) return 0; |
|||
return modeldata->size(); |
|||
} |
|||
|
|||
int PeersTableModel::columnCount(const QModelIndex&) const |
|||
{ |
|||
return headers.size(); |
|||
} |
|||
|
|||
|
|||
QVariant PeersTableModel::data(const QModelIndex &index, int role) const |
|||
{ |
|||
// Align column 4 (amount) right
|
|||
//if (role == Qt::TextAlignmentRole && index.column() == 3) return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
|||
|
|||
if (role == Qt::ForegroundRole) { |
|||
// peers with banscore >=50 will likely be banned soon, color them red
|
|||
if (modeldata->at(index.row()).banscore >= 50) { |
|||
QBrush b; |
|||
b.setColor(Qt::red); |
|||
return b; |
|||
} |
|||
|
|||
// Else, just return the default brush
|
|||
QBrush b; |
|||
b.setColor(Qt::black); |
|||
return b; |
|||
} |
|||
|
|||
auto dat = modeldata->at(index.row()); |
|||
if (role == Qt::DisplayRole) { |
|||
switch (index.column()) { |
|||
case 0: return dat.peerid; |
|||
case 1: return dat.address; |
|||
case 2: return "AS" + QString::number(dat.asn); |
|||
case 3: return dat.tls_cipher; |
|||
case 4: return dat.tls_verified; |
|||
case 5: return dat.subver; |
|||
case 6: return dat.protocolversion; |
|||
case 7: return dat.pingtime; |
|||
case 8: return dat.banscore; |
|||
case 9: return dat.bytes_received; |
|||
case 10: return dat.bytes_sent; |
|||
} |
|||
} |
|||
|
|||
if (role == Qt::ToolTipRole) { |
|||
switch (index.column()) { |
|||
case 0: return "Unique Peer ID"; |
|||
case 1: return "Network Address"; |
|||
case 2: return "Autonomous System Number"; |
|||
case 3: return "TLS Ciphersuite"; |
|||
case 4: return "TLS Certificate verified"; |
|||
case 5: return "Full Node Version"; |
|||
case 6: return "P2P Protocol Version"; |
|||
case 7: return "Ping Time (seconds)"; |
|||
case 8: return "Banscore"; |
|||
case 9: return "Bytes received"; |
|||
case 10: return "Bytes sent"; |
|||
} |
|||
} |
|||
|
|||
|
|||
//TODO: show different icons for IP vs Tor vs other kinds of connections
|
|||
/*
|
|||
if (role == Qt::DecorationRole && index.column() == 0) { |
|||
if (!dat.memo.isEmpty()) { |
|||
// If the memo is a Payment URI, then show a payment request icon
|
|||
if (dat.memo.startsWith("hush:")) { |
|||
QIcon icon(":/icons/res/paymentreq.gif"); |
|||
return QVariant(icon.pixmap(16, 16)); |
|||
} else { |
|||
// Return the info pixmap to indicate memo
|
|||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); |
|||
return QVariant(icon.pixmap(16, 16)); |
|||
} |
|||
} else { |
|||
// Empty pixmap to make it align
|
|||
QPixmap p(16, 16); |
|||
p.fill(Qt::white); |
|||
return QVariant(p); |
|||
} |
|||
} |
|||
*/ |
|||
|
|||
return QVariant(); |
|||
} |
|||
|
|||
|
|||
QVariant PeersTableModel::headerData(int section, Qt::Orientation orientation, int role) const |
|||
{ |
|||
//if (role == Qt::TextAlignmentRole && section == 3) return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
|||
if (role == Qt::TextAlignmentRole) return QVariant(Qt::AlignCenter | Qt::AlignVCenter); |
|||
|
|||
if (role == Qt::FontRole) { |
|||
QFont f; |
|||
f.setBold(true); |
|||
return f; |
|||
} |
|||
|
|||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { |
|||
return headers.at(section); |
|||
} |
|||
|
|||
return QVariant(); |
|||
} |
|||
|
|||
QString PeersTableModel::getPeerId(int row) const { |
|||
return QString::number(modeldata->at(row).peerid); |
|||
} |
|||
|
|||
QString PeersTableModel::getAddress(int row) const { |
|||
return modeldata->at(row).address.trimmed(); |
|||
} |
|||
|
|||
QString PeersTableModel::getTLSCipher(int row) const { |
|||
return modeldata->at(row).tls_cipher; |
|||
} |
|||
|
|||
qint64 PeersTableModel::getASN(int row) const { |
|||
return modeldata->at(row).asn; |
|||
} |
|||
|
|||
qint64 PeersTableModel::getConntime(int row) const { |
|||
return modeldata->at(row).conntime; |
|||
} |
|||
|
|||
QString PeersTableModel::getType(int row) const { |
|||
return modeldata->at(row).type; |
|||
} |
|||
|
|||
QString PeersTableModel::getPingtime(int row) const { |
|||
return Settings::getDecimalString(modeldata->at(row).pingtime); |
|||
} |
@ -0,0 +1,44 @@ |
|||
// Copyright 2019-2021 The Hush developers
|
|||
// Released under the GPLv3
|
|||
#ifndef PEERSTABLEMODEL_H |
|||
#define PEERSTABLEMODEL_H |
|||
|
|||
#include "precompiled.h" |
|||
|
|||
struct PeerItem; |
|||
|
|||
class PeersTableModel: public QAbstractTableModel |
|||
{ |
|||
public: |
|||
PeersTableModel(QObject* parent); |
|||
~PeersTableModel(); |
|||
|
|||
QString getPeerId(int row) const; |
|||
QString getAddress(int row) const; |
|||
QString getType(int row) const; |
|||
qint64 getConntime(int row) const; |
|||
qint64 getASN(int row) const; |
|||
QString getSubver(int row) const; |
|||
QString getTLSCipher(int row) const; |
|||
bool getTLSVerified(int row) const; |
|||
QString getPingtime(int row) const; |
|||
unsigned int getBanscore(int row) const; |
|||
unsigned int getProtocolVersion(int row) const; |
|||
|
|||
int rowCount(const QModelIndex &parent) const; |
|||
int columnCount(const QModelIndex &parent) const; |
|||
QVariant data(const QModelIndex &index, int role) const; |
|||
QVariant headerData(int section, Qt::Orientation orientation, int role) const; |
|||
|
|||
void addData (const QList<PeerItem>& data); |
|||
|
|||
private: |
|||
void updateAllData(); |
|||
QList<PeerItem>* peers = nullptr; |
|||
QList<PeerItem>* modeldata = nullptr; |
|||
|
|||
QList<QString> headers; |
|||
}; |
|||
|
|||
|
|||
#endif // PEERSTABLEMODEL_H
|
@ -1 +1 @@ |
|||
#define APP_VERSION "1.0.0" |
|||
#define APP_VERSION "1.3.0" |
|||
|
@ -0,0 +1,9 @@ |
|||
[Desktop Entry] |
|||
Version=1.0 |
|||
Name=Silent Dragon |
|||
Comment=Full-node wallet for HUSH cryptocurrency |
|||
Exec=/usr/bin/silentdragon |
|||
Icon=/opt/silentdragon/silentdragon.png |
|||
Terminal=false |
|||
Type=Application |
|||
Categories=Network; |