From 922da75795fed146462184468447d8bc2167f19d Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Tue, 15 Oct 2024 13:59:02 +0000 Subject: [PATCH] Namecoin / Qt: Use hex encoding in RPC calls --- src/qt/buynamespage.cpp | 47 ++++++++++++++-- src/qt/nametablemodel.cpp | 112 ++++++++++++++++++++++++++++++++------ src/qt/nametablemodel.h | 3 + 3 files changed, 141 insertions(+), 21 deletions(-) diff --git a/src/qt/buynamespage.cpp b/src/qt/buynamespage.cpp index 06648861d8..e1cff8fb41 100644 --- a/src/qt/buynamespage.cpp +++ b/src/qt/buynamespage.cpp @@ -5,10 +5,12 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -110,7 +112,20 @@ QString BuyNamesPage::name_available(const QString &name) const LogDebug(BCLog::QT, "wallet attempting name_show: name=%s\n", strName); UniValue params(UniValue::VOBJ); - params.pushKV ("name", strName); + + try + { + const QString hexName = NameTableModel::asciiToHex(name); + params.pushKV ("name", hexName.toStdString()); + } + catch (const InvalidNameString& exc) + { + return tr ("Name was invalid ASCII."); + } + + UniValue options(UniValue::VOBJ); + options.pushKV ("nameEncoding", "hex"); + params.pushKV ("options", options); const std::string walletURI = "/wallet/" + walletModel->getWalletName().toStdString(); @@ -143,20 +158,42 @@ QString BuyNamesPage::firstupdate(const QString &name, const std::optionalgetWalletName().toStdString(); try { diff --git a/src/qt/nametablemodel.cpp b/src/qt/nametablemodel.cpp index 9b1a854f78..02fba0939c 100644 --- a/src/qt/nametablemodel.cpp +++ b/src/qt/nametablemodel.cpp @@ -4,6 +4,8 @@ #include #include #include + +#include #include #include @@ -70,14 +72,18 @@ class NameTablePriv std::map vNamesO; // confirmed names (name_list) - // TODO: Set name and value encoding to hex, so that nonstandard - // encodings don't cause errors. + + UniValue params(UniValue::VOBJ); + UniValue options(UniValue::VOBJ); + options.pushKV ("nameEncoding", "hex"); + options.pushKV ("valueEncoding", "hex"); + params.pushKV ("options", options); const std::string walletURI = "/wallet/" + parent.walletModel->getWalletName().toStdString(); UniValue confirmedNames; try { - confirmedNames = parent.walletModel->node().executeRpc("name_list", NullUniValue, walletURI); + confirmedNames = parent.walletModel->node().executeRpc("name_list", params, walletURI); } catch (const UniValue& e) { // although we shouldn't typically encounter error here, we // should continue and try to add confirmed names and @@ -99,8 +105,24 @@ class NameTablePriv continue; } - const std::string name = maybeName.get_str(); - const std::string data = maybeData.get_str(); + // TODO: Properly handle non-ASCII names/data. + + const std::string hexName = maybeName.get_str(); + std::string name; + + const std::string hexData = maybeData.get_str(); + std::string data; + + try + { + name = NameTableModel::hexToAscii(QString::fromStdString(hexName)).toStdString(); + data = NameTableModel::hexToAscii(QString::fromStdString(hexData)).toStdString(); + } + catch (const InvalidNameString& exc) + { + continue; + } + const int height = v.find_value ( "height").getInt(); const int expiresIn = v.find_value ( "expires_in").getInt(); @@ -123,12 +145,10 @@ class NameTablePriv } // unconfirmed names (name_pending) - // TODO: Set name and value encoding to hex, so that nonstandard - // encodings don't cause errors. UniValue pendingNames; try { - pendingNames = parent.walletModel->node().executeRpc("name_pending", NullUniValue, walletURI); + pendingNames = parent.walletModel->node().executeRpc("name_pending", params, walletURI); } catch (const UniValue& e) { // although we shouldn't typically encounter error here, we // should continue and try to add confirmed names and @@ -150,8 +170,23 @@ class NameTablePriv continue; } - const std::string name = maybeName.get_str(); - const std::string data = maybeData.get_str(); + // TODO: Properly handle non-ASCII names/data. + + const std::string hexName = maybeName.get_str(); + std::string name; + + const std::string hexData = maybeData.get_str(); + std::string data; + + try + { + name = NameTableModel::hexToAscii(QString::fromStdString(hexName)).toStdString(); + data = NameTableModel::hexToAscii(QString::fromStdString(hexData)).toStdString(); + } + catch (const InvalidNameString& exc) + { + continue; + } const bool isMine = v.find_value ( "ismine").get_bool(); const std::string op = v.find_value ( "op").get_str(); @@ -487,26 +522,71 @@ NameTableModel::emitDataChanged(int idx) dataChanged(index(idx, 0), index(idx, columns.length()-1)); } +QString NameTableModel::asciiToHex(const QString &ascii) +{ + const std::string strAscii = ascii.toStdString(); + const valtype vt = DecodeName (strAscii, NameEncoding::ASCII); + + const std::string strHex = EncodeName (vt, NameEncoding::HEX); + const QString hex = QString::fromStdString(strHex); + + return hex; +} + +QString NameTableModel::hexToAscii(const QString &hex) +{ + const std::string strHex = hex.toStdString(); + const valtype vt = DecodeName (strHex, NameEncoding::HEX); + + const std::string strAscii = EncodeName (vt, NameEncoding::ASCII); + const QString ascii = QString::fromStdString(strAscii); + + return ascii; +} + QString NameTableModel::update(const QString &name, const std::optional &value, const std::optional &transferTo) const { - const std::string strName = name.toStdString(); - LogDebug(BCLog::QT, "wallet attempting name_update: name=%s\n", strName); + LogDebug(BCLog::QT, "wallet attempting name_update: name=%s\n", name.toStdString()); UniValue params(UniValue::VOBJ); - params.pushKV ("name", strName); + + // TODO: Properly handle non-ASCII names/data. + + try + { + const QString hexName = NameTableModel::asciiToHex(name); + params.pushKV ("name", hexName.toStdString()); + } + catch (const InvalidNameString& exc) + { + return tr ("Name was invalid ASCII."); + } + + UniValue options(UniValue::VOBJ); + options.pushKV ("nameEncoding", "hex"); if (value) { - params.pushKV ("value", value.value().toStdString()); + try + { + const QString hexValue = NameTableModel::asciiToHex(value.value()); + params.pushKV ("value", hexValue.toStdString()); + } + catch (const InvalidNameString& exc) + { + return tr ("Value was invalid ASCII."); + } + + options.pushKV ("valueEncoding", "hex"); } if (transferTo) { - UniValue options(UniValue::VOBJ); options.pushKV ("destAddress", transferTo.value().toStdString()); - params.pushKV ("options", options); } + params.pushKV ("options", options); + const std::string walletURI = "/wallet/" + walletModel->getWalletName().toStdString(); try { diff --git a/src/qt/nametablemodel.h b/src/qt/nametablemodel.h index 0c20faf4a3..6588eb046b 100644 --- a/src/qt/nametablemodel.h +++ b/src/qt/nametablemodel.h @@ -51,6 +51,9 @@ class NameTableModel : public QAbstractTableModel Qt::ItemFlags flags(const QModelIndex &index) const; /*@}*/ + static QString asciiToHex(const QString &ascii); + static QString hexToAscii(const QString &hex); + QString update(const QString &name, const std::optional &value, const std::optional &transferTo) const; QString renew(const QString &name) const;