From e49a924767a083e0340c9aa43271c50c60f64c7b Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Sat, 30 Jan 2021 13:14:52 +0000 Subject: [PATCH 1/2] Namecoin / Qt: Show expired/transferred status from name_list --- src/qt/nametablemodel.cpp | 31 ++++++++++++++++++++++++------- src/qt/nametablemodel.h | 4 ++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/qt/nametablemodel.cpp b/src/qt/nametablemodel.cpp index a96bc046f2..fdae74d714 100644 --- a/src/qt/nametablemodel.cpp +++ b/src/qt/nametablemodel.cpp @@ -19,6 +19,10 @@ namespace { }; } +const std::string NameTableEntry::NAME_STATUS_CONFIRMED = "Confirmed"; +const std::string NameTableEntry::NAME_STATUS_EXPIRED = "Expired"; +const std::string NameTableEntry::NAME_STATUS_TRANSFERRED_OUT = "Transferred out"; + // Returns true if new height is better bool NameTableEntry::CompareHeight(int nOldHeight, int nNewHeight) { @@ -63,8 +67,6 @@ class NameTablePriv // confirmed names (name_list) // TODO: Add unconfirmed names once support for this is added to // name_list. - // TODO: Filter out expired=true and ismine=false once support for this - // is added to name_list. // TODO: Set name and value encoding to hex, so that nonstandard // encodings don't cause errors. @@ -94,11 +96,26 @@ class NameTablePriv continue; } - std::string name = maybeName.get_str(); - std::string data = maybeData.get_str(); - int height = find_value ( v, "height").get_int(); - int expiresIn = find_value ( v, "expires_in").get_int(); - vNamesO[name] = NameTableEntry(name, data, height, expiresIn, "confirmed"); + const std::string name = maybeName.get_str(); + const std::string data = maybeData.get_str(); + const int height = find_value ( v, "height").get_int(); + const int expiresIn = find_value ( v, "expires_in").get_int(); + + const bool isMine = find_value ( v, "ismine").get_bool(); + const bool isExpired = find_value ( v, "expired").get_bool(); + // TODO: Check "op" field + + std::string status = NameTableEntry::NAME_STATUS_CONFIRMED; + if (isExpired) + { + status = NameTableEntry::NAME_STATUS_EXPIRED; + } + if (!isMine) + { + status = NameTableEntry::NAME_STATUS_TRANSFERRED_OUT; + } + + vNamesO[name] = NameTableEntry(name, data, height, expiresIn, status); } } diff --git a/src/qt/nametablemodel.h b/src/qt/nametablemodel.h index 36ed68fa44..b70e71b0e4 100644 --- a/src/qt/nametablemodel.h +++ b/src/qt/nametablemodel.h @@ -83,6 +83,10 @@ struct NameTableEntry static const int NAME_NON_EXISTING = -2; // Dummy nHeight value for unitinialized entries static const int NAME_UNCONFIRMED = -3; // Dummy nHeight value for unconfirmed name transactions + static const std::string NAME_STATUS_CONFIRMED; + static const std::string NAME_STATUS_EXPIRED; + static const std::string NAME_STATUS_TRANSFERRED_OUT; + // NOTE: making this const throws warning indicating it will not be const bool HeightValid() { return nHeight >= 0; } static bool CompareHeight(int nOldHeight, int nNewHeight); // Returns true if new height is better From 142c109960344a7cf2fedae7254c45cede406907 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Sat, 30 Jan 2021 13:55:49 +0000 Subject: [PATCH 2/2] Namecoin: Add name_pending Qt GUI --- src/qt/nametablemodel.cpp | 143 +++++++++++++++++++++++++++++++++++++- src/qt/nametablemodel.h | 5 ++ 2 files changed, 146 insertions(+), 2 deletions(-) diff --git a/src/qt/nametablemodel.cpp b/src/qt/nametablemodel.cpp index fdae74d714..451bf93d77 100644 --- a/src/qt/nametablemodel.cpp +++ b/src/qt/nametablemodel.cpp @@ -22,6 +22,11 @@ namespace { const std::string NameTableEntry::NAME_STATUS_CONFIRMED = "Confirmed"; const std::string NameTableEntry::NAME_STATUS_EXPIRED = "Expired"; const std::string NameTableEntry::NAME_STATUS_TRANSFERRED_OUT = "Transferred out"; +const std::string NameTableEntry::NAME_STATUS_REGISTRATION_PENDING = "Registration pending"; +const std::string NameTableEntry::NAME_STATUS_INCOMING_TRANSFER_PENDING = "Incoming transfer pending"; +const std::string NameTableEntry::NAME_STATUS_OUTGOING_TRANSFER_PENDING = "Outgoing transfer pending"; +const std::string NameTableEntry::NAME_STATUS_RENEWAL_PENDING = "Renewal pending"; +const std::string NameTableEntry::NAME_STATUS_UPDATE_PENDING = "Update pending"; // Returns true if new height is better bool NameTableEntry::CompareHeight(int nOldHeight, int nNewHeight) @@ -65,8 +70,6 @@ class NameTablePriv std::map vNamesO; // confirmed names (name_list) - // TODO: Add unconfirmed names once support for this is added to - // name_list. // TODO: Set name and value encoding to hex, so that nonstandard // encodings don't cause errors. @@ -119,6 +122,142 @@ 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); + } catch (const UniValue& e) { + // although we shouldn't typically encounter error here, we + // should continue and try to add confirmed names and + // pending names. show error to user in case something + // actually went wrong so they can potentially recover + UniValue message = find_value( e, "message"); + LogPrintf ("name_pending lookup error: %s\n", message.get_str()); + } + + // will be an object if name_pending command isn't available/other error + if(pendingNames.isArray()) + { + for (const auto& v : pendingNames.getValues()) + { + UniValue maybeName = find_value ( v, "name"); + UniValue maybeData = find_value ( v, "value"); + if (!maybeName.isStr() || !maybeData.isStr()) + { + continue; + } + + const std::string name = maybeName.get_str(); + const std::string data = maybeData.get_str(); + + const bool isMine = find_value ( v, "ismine").get_bool(); + const std::string op = find_value ( v, "op").get_str(); + + const bool confirmedEntryExists = vNamesO.count(name); + + int height = 0; + int expiresIn = 0; + std::string status; + + if (confirmedEntryExists) + { + // A confirmed entry exists. + auto confirmedEntry = vNamesO[name]; + std::string confirmedData = confirmedEntry.value.toStdString(); + std::string confirmedStatus = confirmedEntry.nameStatus.toStdString(); + height = confirmedEntry.nHeight; + expiresIn = confirmedEntry.expiresIn; + + if (confirmedStatus == NameTableEntry::NAME_STATUS_EXPIRED || confirmedStatus == NameTableEntry::NAME_STATUS_TRANSFERRED_OUT) + { + if (!isMine) + { + // This name isn't ours, it's just some random name + // that another user has pending. + continue; + } + + // The name will be ours when it confirms, but it + // wasn't ours before. + + if (op == "name_firstupdate") + { + // This is a registration, so the reason it wasn't + // ours before is that we hadn't registered it yet. + status = NameTableEntry::NAME_STATUS_REGISTRATION_PENDING; + } + else if (op == "name_update") + { + // This is an update, so we weren't the one to + // register it. (If we were, there would be a + // confirmed entry.) So this is an incoming + // transfer. + status = NameTableEntry::NAME_STATUS_INCOMING_TRANSFER_PENDING; + } + } + else if (confirmedStatus == NameTableEntry::NAME_STATUS_CONFIRMED) + { + if (!isMine) + { + // This name was ours, but won't be after this + // transaction confirms. So this is an outgoing + // transfer. + status = NameTableEntry::NAME_STATUS_OUTGOING_TRANSFER_PENDING; + } + else + { + // This name was ours, and still will be. So this + // is a pending update. + + if (data == confirmedData) + { + // Data is unchanged, so this is a renewal. + status = NameTableEntry::NAME_STATUS_RENEWAL_PENDING; + } + else + { + // Data is changed. + status = NameTableEntry::NAME_STATUS_UPDATE_PENDING; + } + } + } + } + else + { + // A confirmed entry doesn't exist. + + if (!isMine) + { + // This name isn't ours, it's just some random name + // that another user has pending. + continue; + } + + // The name will be ours when it confirms, but it wasn't + // ours before. + + if (op == "name_firstupdate") + { + // This is a registration, so the reason it wasn't ours + // before is that we hadn't registered it yet. + status = NameTableEntry::NAME_STATUS_REGISTRATION_PENDING; + } + else if (op == "name_update") + { + // This is an update, so we weren't the one to register + // it. (If we were, there would be a confirmed entry.) + // So this is an incoming transfer. + status = NameTableEntry::NAME_STATUS_INCOMING_TRANSFER_PENDING; + } + } + + vNamesO[name] = NameTableEntry(name, data, height, expiresIn, status); + } + } + for (const auto& item : vNamesO) { if (cachedNameMap.count(item.first)) diff --git a/src/qt/nametablemodel.h b/src/qt/nametablemodel.h index b70e71b0e4..8326ec6d35 100644 --- a/src/qt/nametablemodel.h +++ b/src/qt/nametablemodel.h @@ -86,6 +86,11 @@ struct NameTableEntry static const std::string NAME_STATUS_CONFIRMED; static const std::string NAME_STATUS_EXPIRED; static const std::string NAME_STATUS_TRANSFERRED_OUT; + static const std::string NAME_STATUS_REGISTRATION_PENDING; + static const std::string NAME_STATUS_INCOMING_TRANSFER_PENDING; + static const std::string NAME_STATUS_OUTGOING_TRANSFER_PENDING; + static const std::string NAME_STATUS_RENEWAL_PENDING; + static const std::string NAME_STATUS_UPDATE_PENDING; // NOTE: making this const throws warning indicating it will not be const bool HeightValid() { return nHeight >= 0; }