Skip to content

Commit 9d9c75a

Browse files
committed
Allow lookups of names by hash.
If -namehashindex is enabled and the index caught up, allow name_show and name_history to look up names by hash instead of by the preimage itself. This can be enabled through the new "byHash" option.
1 parent bdc1eae commit 9d9c75a

File tree

2 files changed

+66
-6
lines changed

2 files changed

+66
-6
lines changed

src/rpc/names.cpp

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <chainparams.h>
77
#include <core_io.h>
88
#include <init.h>
9+
#include <index/namehash.h>
910
#include <key_io.h>
1011
#include <names/common.h>
1112
#include <names/main.h>
@@ -182,6 +183,56 @@ DecodeValueFromRPCOrThrow (const UniValue& val, const UniValue& opt)
182183
namespace
183184
{
184185

186+
/**
187+
* Decodes the identifier for a name lookup according to the nameEncoding,
188+
* and also looks up the preimage if we look up by hash.
189+
*/
190+
valtype
191+
GetNameForLookup (const UniValue& val, const UniValue& opt)
192+
{
193+
const valtype identifier = DecodeNameFromRPCOrThrow (val, opt);
194+
195+
RPCTypeCheckObj (opt,
196+
{
197+
{"byHash", UniValueType (UniValue::VSTR)},
198+
},
199+
true, false);
200+
201+
if (!opt.exists ("byHash"))
202+
return identifier;
203+
204+
const std::string byHashType = opt["byHash"].get_str ();
205+
if (byHashType == "direct")
206+
return identifier;
207+
208+
if (g_name_hash_index == nullptr)
209+
throw std::runtime_error ("-namehashindex is not enabled");
210+
if (!g_name_hash_index->BlockUntilSyncedToCurrentChain ())
211+
throw std::runtime_error ("The name-hash index is not caught up yet");
212+
213+
if (byHashType != "sha256d")
214+
{
215+
std::ostringstream msg;
216+
msg << "Invalid value for byHash: " << byHashType;
217+
throw JSONRPCError (RPC_INVALID_PARAMETER, msg.str ());
218+
}
219+
220+
if (identifier.size () != 32)
221+
throw JSONRPCError (RPC_INVALID_PARAMETER,
222+
"SHA-256d hash must be 32 bytes long");
223+
224+
const uint256 hash(identifier);
225+
valtype name;
226+
if (!g_name_hash_index->FindNamePreimage (hash, name))
227+
{
228+
std::ostringstream msg;
229+
msg << "name hash not found: " << hash.GetHex ();
230+
throw JSONRPCError (RPC_WALLET_ERROR, msg.str ());
231+
}
232+
233+
return name;
234+
}
235+
185236
/**
186237
* Helper class that extracts the wallet for the current RPC request, if any.
187238
* It handles the case of disabled wallet support or no wallet being present,
@@ -348,6 +399,14 @@ NameOptionsHelp::withValueEncoding ()
348399
return *this;
349400
}
350401

402+
NameOptionsHelp&
403+
NameOptionsHelp::withByHash ()
404+
{
405+
withArg ("byHash", RPCArg::Type::STR,
406+
"Interpret \"name\" as hash (\"direct\" or \"sha256d\")");
407+
return *this;
408+
}
409+
351410
RPCArg
352411
NameOptionsHelp::buildRpcArg () const
353412
{
@@ -367,7 +426,8 @@ name_show (const JSONRPCRequest& request)
367426
NameOptionsHelp optHelp;
368427
optHelp
369428
.withNameEncoding ()
370-
.withValueEncoding ();
429+
.withValueEncoding ()
430+
.withByHash ();
371431

372432
RPCHelpMan ("name_show",
373433
"\nLooks up the current data for the given name. Fails if the name doesn't exist.\n",
@@ -394,8 +454,7 @@ name_show (const JSONRPCRequest& request)
394454
if (request.params.size () >= 2)
395455
options = request.params[1].get_obj ();
396456

397-
const valtype name
398-
= DecodeNameFromRPCOrThrow (request.params[0], options);
457+
const valtype name = GetNameForLookup (request.params[0], options);
399458

400459
CNameData data;
401460
{
@@ -421,7 +480,8 @@ name_history (const JSONRPCRequest& request)
421480
NameOptionsHelp optHelp;
422481
optHelp
423482
.withNameEncoding ()
424-
.withValueEncoding ();
483+
.withValueEncoding ()
484+
.withByHash ();
425485

426486
RPCHelpMan ("name_history",
427487
"\nLooks up the current and all past data for the given name. -namehistory must be enabled.\n",
@@ -455,8 +515,7 @@ name_history (const JSONRPCRequest& request)
455515
if (request.params.size () >= 2)
456516
options = request.params[1].get_obj ();
457517

458-
const valtype name
459-
= DecodeNameFromRPCOrThrow (request.params[0], options);
518+
const valtype name = GetNameForLookup (request.params[0], options);
460519

461520
CNameData data;
462521
CNameHistory history;

src/rpc/names.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class NameOptionsHelp
112112

113113
NameOptionsHelp& withNameEncoding ();
114114
NameOptionsHelp& withValueEncoding ();
115+
NameOptionsHelp& withByHash ();
115116

116117
/**
117118
* Variant of withField that also adds the innerArgs field correctly.

0 commit comments

Comments
 (0)