From ec67cd3356049470b4bb7e8d332a2f2a7f182b57 Mon Sep 17 00:00:00 2001 From: Maxnflaxl Date: Sat, 18 Apr 2026 17:11:04 +0200 Subject: [PATCH] #2016: query block by hash --- .gitignore | 5 +++-- explorer/adapter.cpp | 13 +++++++++++++ explorer/adapter.h | 1 + explorer/htm/BeamExplorer.htm | 4 ++-- explorer/server.cpp | 19 ++++++++++++++++++- node/db.cpp | 19 ++++++++++++++++++- node/db.h | 2 ++ 7 files changed, 57 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index b955fe58d6..f2c62a87b6 100644 --- a/.gitignore +++ b/.gitignore @@ -111,5 +111,6 @@ ui/translations.qrc beam_version.gen keykeeper/wasm-key-keeper.* -out/ -wmake.sh +out/ +wmake.sh +.cache \ No newline at end of file diff --git a/explorer/adapter.cpp b/explorer/adapter.cpp index 092222f58d..103951f089 100644 --- a/explorer/adapter.cpp +++ b/explorer/adapter.cpp @@ -2882,6 +2882,19 @@ class Adapter : public Node::IObserver, public IAdapter { return get_block_not_found(h); } + json get_block_by_hash(const Blob& key) override + { + Height h = _nodeBackend.get_DB().FindBlockByHash(key); + if (h) + { + NodeDB::StateID sid; + Block::SystemState::Full s; + if (FindBlockByHeight(sid, s, h)) + return extract_block_from_row(sid, s, h); + } + return get_block_not_found(0); + } + json get_blocks(Height startHeight, uint64_t n) override { json result = json::array(); diff --git a/explorer/adapter.h b/explorer/adapter.h index 55e7a269d3..60882d3b98 100644 --- a/explorer/adapter.h +++ b/explorer/adapter.h @@ -71,6 +71,7 @@ struct IAdapter { virtual json get_status() = 0; virtual json get_block(Height height, int adj) = 0; virtual json get_block_by_kernel(const Blob& key) = 0; + virtual json get_block_by_hash(const Blob& key) = 0; virtual json get_blocks(Height startHeight, uint64_t n) = 0; virtual json get_hdrs(Height hMax, uint64_t nMax, uint64_t dn, const TotalsCol* pCols, uint32_t nCols) = 0; virtual json get_peers() = 0; diff --git a/explorer/htm/BeamExplorer.htm b/explorer/htm/BeamExplorer.htm index fce509e88f..60e80005df 100644 --- a/explorer/htm/BeamExplorer.htm +++ b/explorer/htm/BeamExplorer.htm @@ -3348,8 +3348,8 @@

About

function submitSearch() { // Get search string let query = document.getElementById('SearchField').value; - // Simplistic test to check if search string is rather block height or kernel id - let key = query.length < 10 ? '&height=' : '&kernel='; + // Simplistic test to check if search string is rather block height or hash/kernel id + let key = query.length < 10 ? '&height=' : '&id='; // Load the corresponding URL window.location.href = UrlSelf('block', key + query); } diff --git a/explorer/server.cpp b/explorer/server.cpp index 031033f616..4bb88da5e2 100644 --- a/explorer/server.cpp +++ b/explorer/server.cpp @@ -695,11 +695,28 @@ bool get_UrlHexArg(const HttpUrl& url, const std::string_view& name, uintBig_tsecond; + if (val.find_first_not_of("0123456789") == std::string_view::npos) + return _backend.get_block(static_cast(_currentUrl.get_int_arg("id", 0)), 0); + if (get_UrlHexArg(_currentUrl, "id", hv)) + { + auto res = _backend.get_block_by_kernel(hv); + if (res.value("found", true)) + return res; + return _backend.get_block_by_hash(hv); + } + } + auto height = _currentUrl.get_int_arg("height", 0); auto adj = _currentUrl.get_int_arg("adj", 0); return _backend.get_block(height, static_cast(adj)); diff --git a/node/db.cpp b/node/db.cpp index 9599abd5a6..76a4dadc58 100644 --- a/node/db.cpp +++ b/node/db.cpp @@ -399,7 +399,7 @@ void NodeDB::Open(const char* szPath) bCreate = !rs.Step(); } - const uint64_t nVersionTop = 38; + const uint64_t nVersionTop = 39; Transaction t(*this); @@ -499,6 +499,10 @@ void NodeDB::Open(const char* szPath) CreateTables37(); // no break; + case 38: // block hash index + ExecQuick("CREATE INDEX IF NOT EXISTS [Idx" TblStates "Hash] ON [" TblStates "] ([" TblStates_Hash "]);"); + // no break; + ParamIntSet(ParamID::DbVer, nVersionTop); // no break; @@ -559,6 +563,7 @@ void NodeDB::Create() ExecQuick("CREATE INDEX [Idx" TblStates "Wrk] ON [" TblStates "] ([" TblStates_ChainWork "]);"); ExecQuick("CREATE INDEX [Idx" TblStates TblStates_Txos "] ON [" TblStates "] ([" TblStates_Txos "]);"); + ExecQuick("CREATE INDEX [Idx" TblStates "Hash] ON [" TblStates "] ([" TblStates_Hash "]);"); ExecQuick("CREATE TABLE [" TblTips "] (" "[" TblTips_Number "] INTEGER NOT NULL," @@ -2381,6 +2386,18 @@ Height NodeDB::FindKernel(const Blob& key) return h; } +Height NodeDB::FindBlockByHash(const Blob& hash) +{ + Recordset rs(*this, Query::StateFindByHash, "SELECT " TblStates_Number " FROM " TblStates " WHERE " TblStates_Hash "=? LIMIT 1"); + rs.put(0, hash); + if (!rs.Step()) + return 0; + + Height h; + rs.get(0, h); + return h; +} + void NodeDB::TxoAdd(TxoID id, const Blob& b) { Recordset rs(*this, Query::TxoAdd, "INSERT INTO " TblTxo "(" TblTxo_ID "," TblTxo_Value ") VALUES(?,?)"); diff --git a/node/db.h b/node/db.h index 2583ac4c1e..8d1b25b2a6 100644 --- a/node/db.h +++ b/node/db.h @@ -115,6 +115,7 @@ class NodeDB StateSetRB, StateGetTxos, StateFindByTxos, + StateFindByHash, TipAdd, TipDel, TipReachableAdd, @@ -577,6 +578,7 @@ class NodeDB void InsertKernel(const Blob&, Height h); void DeleteKernel(const Blob&, Height h); Height FindKernel(const Blob&); // in case of duplicates - returning the one with the largest Height + Height FindBlockByHash(const Blob& hash); uint64_t FindStateWorkGreater(const Difficulty::Raw&);