Skip to content

Commit

Permalink
Merge #484: Explicitly use hex encoding in GUI to RPC API
Browse files Browse the repository at this point in the history
922da75 Namecoin / Qt: Use hex encoding in RPC calls (Jeremy Rand)

Pull request description:

  Prevents corruption issues that were happening when default encoding wasn't ASCII.  Also a prereq to supporting binary data in the GUI.

ACKs for top commit:
  domob1812:
    All looks good, thanks!  ACK 922da75.

Tree-SHA512: 0bea61f471c68166106bd1649c4c23b2304573234bb7742b71fcc26e3afa969d3dafde47e984c6aee8e664db262614b3c88f218c6f817accb68e06a8b1fd567a
  • Loading branch information
domob1812 committed Oct 15, 2024
2 parents 763e0f5 + 922da75 commit 4479e5c
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
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();

Expand Down Expand Up @@ -143,20 +158,42 @@ QString BuyNamesPage::firstupdate(const QString &name, const std::optional<QStri
LogDebug(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();
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 {
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 4479e5c

Please sign in to comment.