From c1970e75e57b5045a4b0394a5a5f557901fac0bb Mon Sep 17 00:00:00 2001 From: levoncrypto Date: Thu, 16 Jan 2025 00:55:10 +0400 Subject: [PATCH] RPCs for spark names --- src/rpc/blockchain.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++ src/sparkname.cpp | 42 ++++++++++++++++++++ src/sparkname.h | 4 ++ 3 files changed, 134 insertions(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6578d87eb3..1ce4ee5788 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -25,6 +25,7 @@ #include "evo/providertx.h" #include "evo/deterministicmns.h" #include "evo/cbtx.h" +#include "../sparkname.h" #include "llmq/quorums_chainlocks.h" #include "llmq/quorums_instantsend.h" @@ -176,6 +177,91 @@ UniValue getblockcount(const JSONRPCRequest& request) return chainActive.Height(); } +UniValue getsparknames(const JSONRPCRequest &request) +{ + if (request.fHelp || request.params.size() > 1) { + throw std::runtime_error( + "getsparknames ( height )\n" + "\nReturns a list of all Spark names.\n" + "\nArguments:\n" + "1. height (numeric, optional) The block height to filter Spark names (default is the spark names start block height).\n" + "\nResult:\n" + "[\n" + " \"name1\", (string) The Spark name and address\n" + " \"name2\", (string) Another Spark name and address\n" + " ...\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getsparknames", "1000") + + HelpExampleRpc("getsparknames", "1000") + ); + } + + LOCK(cs_main); + + const Consensus::Params &consensusParams = Params().GetConsensus(); + int nHeight = consensusParams.nSparkNamesStartBlock; + if (request.params.size() == 1) { + nHeight = request.params[0].get_int(); + } + CSparkNameManager *sparkNameManager = CSparkNameManager::GetInstance(); + std::set sparkNames = sparkNameManager->GetSparkNames(nHeight); + UniValue result(UniValue::VARR); + for (const auto &name : sparkNames) { + result.push_back(name); + unsigned char network = spark::GetNetworkType(); + spark::Address SparkAddr; + sparkNameManager->GetSparkAddress(name, chainActive.Tip()->nHeight, SparkAddr); + std::string strAddress = SparkAddr.encode(network); + result.push_back(strAddress); + } + return result; +} + +UniValue getsparknamedata(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 1) { + throw std::runtime_error( + "getsparknamedata ( sparkname )\n" + "\nReturns info about spark name.\n" + "\nArguments:\n" + "Spark name (string)\n" + "\nResult:\n" + "[\n" + "1. Address (string)\n" + "2. Block Height (string)\n" + "3. TxId (string)\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getsparknamedata", "sparkname") + + HelpExampleRpc("getsparknamedata", "sparkname") + ); + } + + LOCK(cs_main); + + std::string sparkName = request.params[0].get_str(); + CSparkNameManager *sparkNameManager = CSparkNameManager::GetInstance(); + + spark::Address SparkAddr; + sparkNameManager->GetSparkAddress(sparkName, chainActive.Tip()->nHeight, SparkAddr); + + UniValue result(UniValue::VARR); + unsigned char network = spark::GetNetworkType(); + + std::string strAddress = SparkAddr.encode(network); + result.push_back(strAddress); + + uint64_t nameBlockHeight = sparkNameManager->GetSparkNameBlockHeight(sparkName); + result.push_back(nameBlockHeight); + + std::string sparkNameTxId = sparkNameManager->GetSparkNameTxID(sparkName); + result.push_back(sparkNameTxId); + + return result; + +} + UniValue getbestblockhash(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) @@ -1658,6 +1744,8 @@ static const CRPCCommand commands[] = { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} }, { "blockchain", "getbestblockhash", &getbestblockhash, true, {} }, { "blockchain", "getblockcount", &getblockcount, true, {} }, + { "blockchain", "getsparknames", &getsparknames, true, {} }, + { "blockchain", "getsparknamedata", &getsparknamedata, true, {} }, { "blockchain", "getblock", &getblock, true, {"blockhash","verbose"} }, { "blockchain", "getblockhash", &getblockhash, true, {"height"} }, { "blockchain", "getblockhashes", &getblockhashes, true, {"high", "low"} }, diff --git a/src/sparkname.cpp b/src/sparkname.cpp index e1cc7d6077..98f85c9753 100644 --- a/src/sparkname.cpp +++ b/src/sparkname.cpp @@ -6,6 +6,7 @@ #include "script/standard.h" #include "base58.h" #include "sparkname.h" +#include "validation.h" CSparkNameManager *CSparkNameManager::sharedSparkNameManager = new CSparkNameManager(); @@ -53,6 +54,47 @@ bool CSparkNameManager::GetSparkAddress(const std::string &name, int nHeight, sp } } +uint64_t CSparkNameManager::GetSparkNameBlockHeight(const std::string &name) const +{ + auto it = sparkNames.find(name); + if (it == sparkNames.end()) + throw std::runtime_error("Spark name not found: " + name); + + size_t height = it->second.second; + return height; +} + +std::string CSparkNameManager::GetSparkNameTxID(const std::string &name) const +{ + auto it = sparkNames.find(name); + if (it == sparkNames.end()) + throw std::runtime_error("Spark name not found: " + name); + + uint32_t blockHeight = it->second.second; + + CBlockIndex* pBlockIndex = chainActive[blockHeight]; + if (!pBlockIndex) + throw std::runtime_error("Block not found at height: " + std::to_string(blockHeight)); + + CBlock block; + if (!ReadBlockFromDisk(block, pBlockIndex, Params().GetConsensus())) + throw std::runtime_error("Failed to read block from disk."); + + CSparkNameManager *sparkNameManager = CSparkNameManager::GetInstance(); + for (const CTransactionRef& tx : block.vtx) + { + CSparkNameTxData sparkNameData; + CValidationState state; + + if (sparkNameManager->CheckSparkNameTx(*tx, blockHeight, state, &sparkNameData)) + { + return (*tx).GetHash().ToString(); + } + } + + throw std::runtime_error("Spark name transaction not found for: " + name); +} + bool CSparkNameManager::ParseSparkNameTxData(const CTransaction &tx, spark::SpendTransaction &sparkTx, CSparkNameTxData &sparkNameData, size_t &sparkNameDataPos) { CDataStream serializedSpark(SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/sparkname.h b/src/sparkname.h index 8a57123878..173980b14b 100644 --- a/src/sparkname.h +++ b/src/sparkname.h @@ -89,6 +89,10 @@ class CSparkNameManager } static CSparkNameManager *GetInstance() { return sharedSparkNameManager; }; + + uint64_t GetSparkNameBlockHeight(const std::string &name) const; + + std::string GetSparkNameTxID(const std::string &name) const; }; #endif // FIRO_SPARKNAME_H \ No newline at end of file