diff --git a/silkworm/db/kv/api/local_transaction.cpp b/silkworm/db/kv/api/local_transaction.cpp index f7c60b782d..78f13fd94a 100644 --- a/silkworm/db/kv/api/local_transaction.cpp +++ b/silkworm/db/kv/api/local_transaction.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,17 @@ using CodeDomainGetAsOfQuery = RawDomainGetAsOfQuery; using ReceiptsDomainGetAsOfQuery = RawDomainGetAsOfQuery; +template +using RawHistoryGetQuery = HistoryGetQuery< + kvdb::RawEncoder, snapshots::RawEncoder, + kvdb::RawDecoder, snapshots::RawDecoder, + history_segment_names>; +using AccountsHistoryGetQuery = RawHistoryGetQuery; +using StorageHistoryGetQuery = RawHistoryGetQuery; +using CodeHistoryGetQuery = RawHistoryGetQuery; +using CommitmentHistoryGetQuery = RawHistoryGetQuery; +using ReceiptsHistoryGetQuery = RawHistoryGetQuery; + using RawInvertedIndexRangeByKeyQuery = InvertedIndexRangeByKeyQuery< kvdb::RawEncoder, snapshots::RawEncoder>; // TODO(canepat) try ByteView @@ -180,9 +192,35 @@ Task LocalTransaction::get_as_of(GetAsOfQuery query) { co_return GetAsOfResult{.success = true, .value = std::move(*value)}; } -Task LocalTransaction::history_seek(HistoryPointQuery /*query*/) { - // TODO(canepat) implement using E3-like aggregator abstraction [tx_id_ must be changed] - co_return HistoryPointResult{}; +Task LocalTransaction::history_seek(HistoryPointQuery query) { + if (!kTable2EntityNames.contains(query.table)) { + co_return HistoryPointResult{}; + } + + const auto domain_name = kTable2EntityNames.at(query.table); + const auto domain = data_store_.chaindata.domain(domain_name); + if (!domain.history) { + co_return HistoryPointResult{}; + } + + const auto timestamp = static_cast(query.timestamp); + + std::optional value; + if (domain_name == state::kDomainNameAccounts) { + value = query_history_get(*domain.history, query.key, timestamp); + } else if (domain_name == state::kDomainNameStorage) { + value = query_history_get(*domain.history, query.key, timestamp); + } else if (domain_name == state::kDomainNameCode) { + value = query_history_get(*domain.history, query.key, timestamp); + } else if (domain_name == state::kDomainNameCommitment) { + value = query_history_get(*domain.history, query.key, timestamp); + } else if (domain_name == state::kDomainNameReceipts) { + value = query_history_get(*domain.history, query.key, timestamp); + } + if (!value) { + co_return HistoryPointResult{}; + } + co_return HistoryPointResult{.success = true, .value = std::move(*value)}; } Task LocalTransaction::index_range(IndexRangeQuery query) { diff --git a/silkworm/db/kv/api/local_transaction.hpp b/silkworm/db/kv/api/local_transaction.hpp index ad013d0010..acfb93513d 100644 --- a/silkworm/db/kv/api/local_transaction.hpp +++ b/silkworm/db/kv/api/local_transaction.hpp @@ -81,22 +81,21 @@ class LocalTransaction : public BaseTransaction { Task range_as_of(DomainRangeQuery query) override; private: - template - auto query_domain_latest(const datastore::EntityName domain_name, ByteView key) { - DomainGetLatest query( + template + auto query_domain_as_of(const datastore::EntityName domain_name, ByteView key, Timestamp ts) { + DomainGetAsOfQuery query( data_store_.chaindata.domain(domain_name), tx_, data_store_.state_repository_latest, data_store_.state_repository_historical); - return query.exec(key); + return query.exec(key, ts); } - template - auto query_domain_as_of(const datastore::EntityName domain_name, ByteView key, Timestamp ts) { - DomainGetAsOfQuery query( - data_store_.chaindata.domain(domain_name), + template + auto query_history_get(datastore::kvdb::History kvdb_entity, ByteView key, datastore::Timestamp ts) { + HistoryGetQuery query( + kvdb_entity, tx_, - data_store_.state_repository_latest, data_store_.state_repository_historical); return query.exec(key, ts); }