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)
182183namespace
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+
351410RPCArg
352411NameOptionsHelp::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 " \n Looks 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 " \n Looks 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;
0 commit comments