Skip to content

Commit

Permalink
Merge pull request #5808 from knst/bp-v21-p6
Browse files Browse the repository at this point in the history
  • Loading branch information
PastaPastaPasta authored Jan 16, 2024
2 parents 08c75ad + 6f02bab commit dd7fac4
Show file tree
Hide file tree
Showing 38 changed files with 326 additions and 329 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ before_install:
install:
- set -o errexit; source ./ci/test/04_install.sh
before_script:
- set -o errexit; source ./ci/test/05_before_script.sh
# Temporary workaround for https://github.com/bitcoin/bitcoin/issues/16368
- for i in {1..4}; do echo "$(sleep 500)" ; done &
- set -o errexit; source ./ci/test/05_before_script.sh &> "/dev/null"
script:
- if [ $SECONDS -gt 1200 ]; then set +o errexit; echo "Travis early exit to cache current state"; false; else set -o errexit; source .travis/test_06_script.sh; fi
after_script:
Expand Down
1 change: 0 additions & 1 deletion ci/dash/test_unittests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export BOOST_TEST_LOG_LEVEL=test_suite

cd build-ci/dashcore-$BUILD_TARGET

bash -c "${CI_WAIT}" & # Print dots in case the unit tests take a long time to run
if [ "$DIRECT_WINE_EXEC_TESTS" = "true" ]; then
# Inside Docker, binfmt isn't working so we can't trust in make invoking windows binaries correctly
wine ./src/test/test_dash.exe
Expand Down
16 changes: 15 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,21 @@ AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
#include <byteswap.h>
#endif])

AC_CHECK_DECLS([__builtin_clz, __builtin_clzl, __builtin_clzll])
AC_MSG_CHECKING(for __builtin_clzl)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[
(void) __builtin_clzl(0);
]])],
[ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_BUILTIN_CLZL, 1, [Define this symbol if you have __builtin_clzl])],
[ AC_MSG_RESULT(no)]
)

AC_MSG_CHECKING(for __builtin_clzll)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[
(void) __builtin_clzll(0);
]])],
[ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_BUILTIN_CLZLL, 1, [Define this symbol if you have __builtin_clzll])],
[ AC_MSG_RESULT(no)]
)

dnl Check for mallopt(M_ARENA_MAX) (to set glibc arenas)
AC_MSG_CHECKING(for mallopt M_ARENA_MAX)
Expand Down
4 changes: 2 additions & 2 deletions src/crypto/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ void static inline WriteBE64(unsigned char* ptr, uint64_t x)
/** Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set. */
uint64_t static inline CountBits(uint64_t x)
{
#if HAVE_DECL___BUILTIN_CLZL
#if HAVE_BUILTIN_CLZL
if (sizeof(unsigned long) >= sizeof(uint64_t)) {
return x ? 8 * sizeof(unsigned long) - __builtin_clzl(x) : 0;
}
#endif
#if HAVE_DECL___BUILTIN_CLZLL
#if HAVE_BUILTIN_CLZLL
if (sizeof(unsigned long long) >= sizeof(uint64_t)) {
return x ? 8 * sizeof(unsigned long long) - __builtin_clzll(x) : 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ template <typename... Args>
static void FatalError(const char* fmt, const Args&... args)
{
std::string strMessage = tfm::format(fmt, args...);
SetMiscWarning(strMessage);
SetMiscWarning(Untranslated(strMessage));
LogPrintf("*** %s\n", strMessage);
AbortError(_("A fatal internal error occurred, see debug.log for details"));
StartShutdown();
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <netaddress.h> // For Network
#include <support/allocators/secure.h> // For SecureString
#include <uint256.h>
#include <util/translation.h>

#include <functional>
#include <memory>
Expand Down Expand Up @@ -171,7 +172,7 @@ class Node
virtual void initParameterInteraction() = 0;

//! Get warnings.
virtual std::string getWarnings() = 0;
virtual bilingual_str getWarnings() = 0;

// Get log flags.
virtual uint64_t getLogCategories() = 0;
Expand Down
26 changes: 14 additions & 12 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2119,7 +2119,7 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
// mempool entries added before this time have likely expired from mapRelay
const std::chrono::seconds longlived_mempool_time = GetTime<std::chrono::seconds>() - RELAY_TX_CACHE_TIME;
// Get last mempool request time
const std::chrono::seconds mempool_req = !pfrom.RelayAddrsWithConn() ? pfrom.m_tx_relay->m_last_mempool_req.load()
const std::chrono::seconds mempool_req = pfrom.RelayAddrsWithConn() ? pfrom.m_tx_relay->m_last_mempool_req.load()
: std::chrono::seconds::min();

// Process as many TX items from the front of the getdata queue as
Expand Down Expand Up @@ -2823,14 +2823,6 @@ void PeerManagerImpl::ProcessMessage(
PeerRef peer = GetPeerRef(pfrom.GetId());
if (peer == nullptr) return;

if (!(pfrom.GetLocalServices() & NODE_BLOOM) &&
(msg_type == NetMsgType::FILTERLOAD ||
msg_type == NetMsgType::FILTERADD))
{
Misbehaving(pfrom.GetId(), 100);
return;
}

if (msg_type == NetMsgType::VERSION) {
// Each connection can only send one version message
if (pfrom.nVersion != 0)
Expand Down Expand Up @@ -4190,6 +4182,10 @@ void PeerManagerImpl::ProcessMessage(
}

if (msg_type == NetMsgType::FILTERLOAD) {
if (!(pfrom.GetLocalServices() & NODE_BLOOM)) {
pfrom.fDisconnect = true;
return;
}
CBloomFilter filter;
vRecv >> filter;

Expand All @@ -4208,6 +4204,10 @@ void PeerManagerImpl::ProcessMessage(
}

if (msg_type == NetMsgType::FILTERADD) {
if (!(pfrom.GetLocalServices() & NODE_BLOOM)) {
pfrom.fDisconnect = true;
return;
}
std::vector<unsigned char> vData;
vRecv >> vData;

Expand All @@ -4231,13 +4231,15 @@ void PeerManagerImpl::ProcessMessage(
}

if (msg_type == NetMsgType::FILTERCLEAR) {
if (!(pfrom.GetLocalServices() & NODE_BLOOM)) {
pfrom.fDisconnect = true;
return;
}
if (!pfrom.RelayAddrsWithConn()) {
return;
}
LOCK(pfrom.m_tx_relay->cs_filter);
if (pfrom.GetLocalServices() & NODE_BLOOM) {
pfrom.m_tx_relay->pfilter = nullptr;
}
pfrom.m_tx_relay->pfilter = nullptr;
pfrom.m_tx_relay->fRelayTxes = true;
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/node/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ class NodeImpl : public Node
std::string getNetwork() override { return Params().NetworkIDString(); }
void initLogging() override { InitLogging(gArgs); }
void initParameterInteraction() override { InitParameterInteraction(gArgs); }
std::string getWarnings() override { return GetWarnings(true); }
bilingual_str getWarnings() override { return GetWarnings(true); }
uint64_t getLogCategories() override { return LogInstance().GetCategoryMask(); }
bool baseInitialize() override
{
Expand Down
4 changes: 2 additions & 2 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ BitcoinCore::BitcoinCore(interfaces::Node& node) :
void BitcoinCore::handleRunawayException(const std::exception_ptr e)
{
PrintExceptionContinue(e, "Runaway exception");
Q_EMIT runawayException(QString::fromStdString(m_node.getWarnings()));
Q_EMIT runawayException(QString::fromStdString(m_node.getWarnings().translated));
}

void BitcoinCore::initialize()
Expand Down Expand Up @@ -747,7 +747,7 @@ int GuiMain(int argc, char* argv[])
}
} catch (...) {
PrintExceptionContinue(std::current_exception(), "Runaway exception");
app.handleRunawayException(QString::fromStdString(node->getWarnings()));
app.handleRunawayException(QString::fromStdString(node->getWarnings().translated));
}
return rv;
}
8 changes: 4 additions & 4 deletions src/qt/bitcoinamountfield.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class AmountLineEdit: public QLineEdit

if (valid) {
val = qBound(m_min_amount, val, m_max_amount);
setText(BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::separatorAlways));
setText(BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::SeparatorStyle::ALWAYS));
}
}

Expand All @@ -103,7 +103,7 @@ class AmountLineEdit: public QLineEdit

void setValue(const CAmount& value)
{
setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways));
setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::SeparatorStyle::ALWAYS));
Q_EMIT valueChanged();
}

Expand All @@ -130,7 +130,7 @@ class AmountLineEdit: public QLineEdit
currentUnit = unit;
amountValidator->updateUnit(unit);

setPlaceholderText(BitcoinUnits::format(currentUnit, m_min_amount, false, BitcoinUnits::separatorAlways));
setPlaceholderText(BitcoinUnits::format(currentUnit, m_min_amount, false, BitcoinUnits::SeparatorStyle::ALWAYS));
if(valid)
setValue(val);
else
Expand All @@ -142,7 +142,7 @@ class AmountLineEdit: public QLineEdit
ensurePolished();
const QFontMetrics fm(fontMetrics());
int h = 0;
int w = GUIUtil::TextWidth(fm, BitcoinUnits::format(BitcoinUnits::DASH, BitcoinUnits::maxMoney(), false, BitcoinUnits::separatorAlways));
int w = GUIUtil::TextWidth(fm, BitcoinUnits::format(BitcoinUnits::DASH, BitcoinUnits::maxMoney(), false, BitcoinUnits::SeparatorStyle::ALWAYS));
w += 2; // cursor blinking space
w += GUIUtil::dashThemeActive() ? 24 : 0; // counteract padding from css
return QSize(w, h);
Expand Down
2 changes: 1 addition & 1 deletion src/qt/bitcoinunits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ QString BitcoinUnits::format(int unit, const CAmount& nIn, bool fPlus, Separator
// confused with the decimal marker.
QChar thin_sp(THIN_SP_CP);
int q_size = quotient_str.size();
if (separators == separatorAlways || (separators == separatorStandard && q_size > 4))
if (separators == SeparatorStyle::ALWAYS || (separators == SeparatorStyle::STANDARD && q_size > 4))
for (int i = 3; i < q_size; i += 3)
quotient_str.insert(q_size - i, thin_sp);

Expand Down
18 changes: 9 additions & 9 deletions src/qt/bitcoinunits.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ class BitcoinUnits: public QAbstractListModel
duffs
};

enum SeparatorStyle
enum class SeparatorStyle
{
separatorNever,
separatorStandard,
separatorAlways
NEVER,
STANDARD,
ALWAYS
};

//! @name Static API
Expand All @@ -71,16 +71,16 @@ class BitcoinUnits: public QAbstractListModel
//! Number of decimals left
static int decimals(int unit);
//! Format as string
static QString format(int unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = separatorStandard, bool justify = false);
static QString simpleFormat(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
static QString format(int unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD, bool justify = false);
static QString simpleFormat(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD);
//! Format as string (with unit)
static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD);
//! Format as HTML string (with unit)
static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD);
//! Format as string (with unit) of fixed length to preserve privacy, if it is set.
static QString formatWithPrivacy(int unit, const CAmount& amount, SeparatorStyle separators, bool privacy);
//! Format as string (with unit) but floor value up to "digits" settings
static QString floorWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
static QString floorWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD);
static QString floorHtmlWithPrivacy(int unit, const CAmount& amount, SeparatorStyle separators, bool privacy);
//! Parse string to coin amount
static bool parse(int unit, const QString &value, CAmount *val_out);
Expand Down
2 changes: 1 addition & 1 deletion src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ enum BlockSource ClientModel::getBlockSource() const

QString ClientModel::getStatusBarWarnings() const
{
return QString::fromStdString(m_node.getWarnings());
return QString::fromStdString(m_node.getWarnings().translated);
}

OptionsModel *ClientModel::getOptionsModel()
Expand Down
6 changes: 0 additions & 6 deletions src/qt/forms/debugwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -929,12 +929,6 @@
<height>426</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnminimumwidth="0,10,0">
<item row="0" column="0">
<widget class="QLabel" name="label_50">
Expand Down
2 changes: 1 addition & 1 deletion src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ QString formatBitcoinURI(const SendCoinsRecipient &info)

if (info.amount)
{
ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::DASH, info.amount, false, BitcoinUnits::separatorNever));
ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::DASH, info.amount, false, BitcoinUnits::SeparatorStyle::NEVER));
paramCount++;
}

Expand Down
32 changes: 16 additions & 16 deletions src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class TxViewDelegate : public QAbstractItemDelegate
colorForeground = qvariant_cast<QColor>(indexAmount.data(Qt::ForegroundRole));
// Note: do NOT use Qt::DisplayRole, have format properly here
qint64 nAmount = index.data(TransactionTableModel::AmountRole).toLongLong();
QString strAmount = BitcoinUnits::floorWithUnit(unit, nAmount, true, BitcoinUnits::separatorAlways);
QString strAmount = BitcoinUnits::floorWithUnit(unit, nAmount, true, BitcoinUnits::SeparatorStyle::ALWAYS);
painter->setPen(colorForeground);
painter->drawText(rectTopHalf, Qt::AlignRight | Qt::AlignVCenter, strAmount);

Expand Down Expand Up @@ -209,20 +209,20 @@ void OverviewPage::setBalance(const interfaces::WalletBalances& balances)
int unit = walletModel->getOptionsModel()->getDisplayUnit();
m_balances = balances;
if (walletModel->wallet().privateKeysDisabled()) {
ui->labelBalance->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_watch_only_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_watch_only_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelBalance->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
} else {
ui->labelBalance->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelAnonymized->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.anonymized_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelWatchAvailable->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelWatchPending->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_watch_only_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelWatchImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_watch_only_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelWatchTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, BitcoinUnits::separatorAlways, m_privacy));
ui->labelBalance->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelAnonymized->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.anonymized_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchAvailable->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchPending->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
}
// only show immature (newly mined) balance if it's non-zero, so as not to complicate things
// for the non-mining users
Expand Down Expand Up @@ -350,7 +350,7 @@ void OverviewPage::updateCoinJoinProgress()
if (!walletModel || !clientModel || clientModel->node().shutdownRequested() || !clientModel->masternodeSync().isBlockchainSynced()) return;

QString strAmountAndRounds;
QString strCoinJoinAmount = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, clientModel->coinJoinOptions().getAmount() * COIN, false, BitcoinUnits::separatorAlways);
QString strCoinJoinAmount = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, clientModel->coinJoinOptions().getAmount() * COIN, false, BitcoinUnits::SeparatorStyle::ALWAYS);

if(m_balances.balance == 0)
{
Expand Down Expand Up @@ -381,7 +381,7 @@ void OverviewPage::updateCoinJoinProgress()
strCoinJoinAmount = strCoinJoinAmount.remove(strCoinJoinAmount.indexOf("."), BitcoinUnits::decimals(nDisplayUnit) + 1);
strAmountAndRounds = strCoinJoinAmount + " / " + tr("%n Rounds", "", clientModel->coinJoinOptions().getRounds());
} else {
QString strMaxToAnonymize = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, nMaxToAnonymize, false, BitcoinUnits::separatorAlways);
QString strMaxToAnonymize = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, nMaxToAnonymize, false, BitcoinUnits::SeparatorStyle::ALWAYS);
ui->labelAmountRounds->setToolTip(tr("Not enough compatible inputs to mix <span style='%1'>%2</span>,<br>"
"will mix <span style='%1'>%3</span> instead")
.arg(GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_ERROR))
Expand Down
Loading

0 comments on commit dd7fac4

Please sign in to comment.