Skip to content

Commit

Permalink
Namecoin / Qt: Use hex encoding in RPC calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy Rand committed Mar 20, 2024
1 parent 45b836e commit 05767a2
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 21 deletions.
47 changes: 42 additions & 5 deletions src/qt/buynamespage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
#include <logging.h>
#include <qt/configurenamedialog.h>
#include <qt/guiutil.h>
#include <qt/nametablemodel.h>
#include <qt/platformstyle.h>
#include <qt/walletmodel.h>
#include <rpc/protocol.h>

#include <names/encoding.h>
#include <univalue.h>

#include <QMessageBox>
Expand Down Expand Up @@ -110,7 +112,20 @@ QString BuyNamesPage::name_available(const QString &name) const
LogPrint(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();

Expand Down Expand Up @@ -143,20 +158,42 @@ QString BuyNamesPage::firstupdate(const QString &name, const std::optional<QStri
LogPrint(BCLog::QT, "wallet attempting name_firstupdate: 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");

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 {
Expand Down
112 changes: 96 additions & 16 deletions src/qt/nametablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <qt/clientmodel.h>
#include <qt/transactiontablemodel.h>
#include <qt/walletmodel.h>

#include <names/encoding.h>
#include <univalue.h>
#include <wallet/wallet.h>

Expand Down Expand Up @@ -70,14 +72,18 @@ class NameTablePriv
std::map<std::string, NameTableEntry> 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
Expand All @@ -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<int>();
const int expiresIn = v.find_value ( "expires_in").getInt<int>();

Expand All @@ -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
Expand All @@ -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();
Expand Down Expand Up @@ -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<QString> &value, const std::optional<QString> &transferTo) const
{
const std::string strName = name.toStdString();
LogPrint(BCLog::QT, "wallet attempting name_update: name=%s\n", strName);
LogPrint(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 {
Expand Down
3 changes: 3 additions & 0 deletions src/qt/nametablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<QString> &value, const std::optional<QString> &transferTo) const;
QString renew(const QString &name) const;

Expand Down

0 comments on commit 05767a2

Please sign in to comment.