diff --git a/Makefile.am b/Makefile.am
index 221622e5..9e18911c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -100,7 +100,7 @@ test_libbitcoin_database_test_SOURCES = \
test/tables/archives/spend.cpp \
test/tables/archives/transaction.cpp \
test/tables/archives/txs.cpp \
- test/tables/caches/prevouts.cpp \
+ test/tables/caches/prevout.cpp \
test/tables/caches/validated_bk.cpp \
test/tables/caches/validated_tx.cpp \
test/tables/indexes/height.cpp \
@@ -237,7 +237,7 @@ include_bitcoin_database_tables_archives_HEADERS = \
include_bitcoin_database_tables_cachesdir = ${includedir}/bitcoin/database/tables/caches
include_bitcoin_database_tables_caches_HEADERS = \
- include/bitcoin/database/tables/caches/prevouts.hpp \
+ include/bitcoin/database/tables/caches/prevout.hpp \
include/bitcoin/database/tables/caches/validated_bk.hpp \
include/bitcoin/database/tables/caches/validated_tx.hpp
diff --git a/builds/cmake/CMakeLists.txt b/builds/cmake/CMakeLists.txt
index f01d716a..65648399 100644
--- a/builds/cmake/CMakeLists.txt
+++ b/builds/cmake/CMakeLists.txt
@@ -308,7 +308,7 @@ if (with-tests)
"../../test/tables/archives/spend.cpp"
"../../test/tables/archives/transaction.cpp"
"../../test/tables/archives/txs.cpp"
- "../../test/tables/caches/prevouts.cpp"
+ "../../test/tables/caches/prevout.cpp"
"../../test/tables/caches/validated_bk.cpp"
"../../test/tables/caches/validated_tx.cpp"
"../../test/tables/indexes/height.cpp"
diff --git a/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj b/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj
index 54dc5b41..248a8e7f 100644
--- a/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj
+++ b/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj
@@ -111,7 +111,7 @@
-
+
diff --git a/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj.filters
index 8e1d963c..3511be7f 100644
--- a/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj.filters
+++ b/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj.filters
@@ -156,7 +156,7 @@
src\tables\archives
-
+
src\tables\caches
diff --git a/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj b/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj
index 4dfd15a8..7db4fa20 100644
--- a/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj
+++ b/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj
@@ -133,7 +133,7 @@
-
+
diff --git a/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj.filters
index 8da6a2fa..9851ef0f 100644
--- a/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj.filters
+++ b/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj.filters
@@ -242,7 +242,7 @@
include\bitcoin\database\tables\archives
-
+
include\bitcoin\database\tables\caches
diff --git a/include/bitcoin/database.hpp b/include/bitcoin/database.hpp
index 87ad9f6b..cc456e1d 100644
--- a/include/bitcoin/database.hpp
+++ b/include/bitcoin/database.hpp
@@ -64,7 +64,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/include/bitcoin/database/tables/caches/prevout.hpp b/include/bitcoin/database/tables/caches/prevout.hpp
new file mode 100644
index 00000000..b288b35f
--- /dev/null
+++ b/include/bitcoin/database/tables/caches/prevout.hpp
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
+ *
+ * This file is part of libbitcoin.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+#ifndef LIBBITCOIN_DATABASE_TABLES_OPTIONALS_BUFFER_HPP
+#define LIBBITCOIN_DATABASE_TABLES_OPTIONALS_BUFFER_HPP
+
+#include
+#include
+#include
+#include
+
+namespace libbitcoin {
+namespace database {
+namespace table {
+
+/// prevout is an array map index of previous outputs by block.
+struct prevout
+ : public array_map
+{
+ using tx = linkage;
+ using spend = linkage;
+ using array_map::arraymap;
+
+ struct record
+ : public schema::prevout
+ {
+ inline bool from_data(reader& source) NOEXCEPT
+ {
+ coinbase = source.read_byte();
+ spend_fk = source.read_little_endian();
+ output_tx_fk = source.read_little_endian();
+ BC_ASSERT(source.get_read_position() == count());
+ return source;
+ }
+
+ inline bool to_data(finalizer& sink) const NOEXCEPT
+ {
+ sink.write_byte(coinbase);
+ sink.write_little_endian(spend_fk);
+ sink.write_little_endian(output_tx_fk);
+ BC_ASSERT(sink.get_write_position() == count());
+ return sink;
+ }
+
+ inline bool operator==(const record& other) const NOEXCEPT
+ {
+ return coinbase == other.coinbase
+ && spend_fk == other.spend_fk
+ && output_tx_fk == other.output_tx_fk;
+ }
+
+ bool coinbase{};
+ spend::integer spend_fk{};
+ tx::integer output_tx_fk{};
+ };
+};
+
+} // namespace table
+} // namespace database
+} // namespace libbitcoin
+
+#endif
diff --git a/include/bitcoin/database/tables/caches/prevouts.hpp b/include/bitcoin/database/tables/caches/prevouts.hpp
deleted file mode 100644
index 6df2bc14..00000000
--- a/include/bitcoin/database/tables/caches/prevouts.hpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/////**
-//// * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
-//// *
-//// * This file is part of libbitcoin.
-//// *
-//// * This program is free software: you can redistribute it and/or modify
-//// * it under the terms of the GNU Affero General Public License as published by
-//// * the Free Software Foundation, either version 3 of the License, or
-//// * (at your option) any later version.
-//// *
-//// * This program is distributed in the hope that it will be useful,
-//// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-//// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//// * GNU Affero General Public License for more details.
-//// *
-//// * You should have received a copy of the GNU Affero General Public License
-//// * along with this program. If not, see .
-//// */
-////#ifndef LIBBITCOIN_DATABASE_TABLES_OPTIONALS_BUFFER_HPP
-////#define LIBBITCOIN_DATABASE_TABLES_OPTIONALS_BUFFER_HPP
-////
-////#include
-////#include
-////#include
-////#include
-////
-////namespace libbitcoin {
-////namespace database {
-////namespace table {
-////
-/////// buffer is a slab hashmap of txs.
-////struct buffer
-//// : public hash_map
-////{
-//// using hash_map::hashmap;
-////
-//// struct slab
-//// : public schema::buffer
-//// {
-//// link count() const NOEXCEPT
-//// {
-//// return system::possible_narrow_cast(pk + sk +
-//// tx.serialized_size(true));
-//// }
-////
-//// inline bool from_data(reader& source) NOEXCEPT
-//// {
-//// tx = system::chain::transaction{ source, true };
-//// BC_ASSERT(source.get_read_position() == count());
-//// return source;
-//// }
-////
-//// inline bool to_data(finalizer& sink) const NOEXCEPT
-//// {
-//// tx.to_data(sink, true);
-//// BC_ASSERT(sink.get_write_position() == count());
-//// return sink;
-//// }
-////
-//// inline bool operator==(const slab& other) const NOEXCEPT
-//// {
-//// return tx == other.tx;
-//// }
-////
-//// system::chain::transaction tx{};
-//// };
-////
-//// struct slab_ptr
-//// : public schema::buffer
-//// {
-//// link count() const NOEXCEPT
-//// {
-//// return system::possible_narrow_cast(pk + sk +
-//// tx->serialized_size(true));
-//// }
-////
-//// inline bool from_data(reader& source) NOEXCEPT
-//// {
-//// using namespace system;
-//// tx = system::to_shared(source, true);
-//// return source;
-//// }
-////
-//// inline bool to_data(finalizer& sink) const NOEXCEPT
-//// {
-//// BC_ASSERT(tx);
-//// tx->to_data(sink, true);
-//// return sink;
-//// }
-////
-//// system::chain::transaction::cptr tx{};
-//// };
-////
-//// struct put_ref
-//// : public schema::buffer
-//// {
-//// link count() const NOEXCEPT
-//// {
-//// return system::possible_narrow_cast(pk + sk +
-//// tx.serialized_size(true));
-//// }
-////
-//// inline bool to_data(finalizer& sink) const NOEXCEPT
-//// {
-//// tx.to_data(sink, true);
-//// return sink;
-//// }
-////
-//// const system::chain::transaction& tx{};
-//// };
-////};
-////
-////} // namespace table
-////} // namespace database
-////} // namespace libbitcoin
-////
-////#endif
diff --git a/include/bitcoin/database/tables/schema.hpp b/include/bitcoin/database/tables/schema.hpp
index 729bc6c1..864e5aca 100644
--- a/include/bitcoin/database/tables/schema.hpp
+++ b/include/bitcoin/database/tables/schema.hpp
@@ -63,6 +63,7 @@ namespace schema
namespace caches
{
+ constexpr auto prevout = "prevout";
constexpr auto validated_bk = "validated_bk";
constexpr auto validated_tx = "validated_tx";
}
@@ -120,7 +121,6 @@ namespace schema
constexpr size_t bk_slab = 3; // ->validated_bk record.
constexpr size_t tx_slab = 5; // ->validated_tk record.
constexpr size_t neutrino_ = 5; // ->neutrino record.
- ////constexpr size_t buffer_ = 5; // ->buffer record (guestimate).
/// Search keys.
constexpr size_t hash = system::hash_size;
@@ -355,6 +355,22 @@ namespace schema
static_assert(minrow == 23u);
};
+ // record arraymap
+ struct prevout
+ {
+ static constexpr size_t pk = schema::spend_;
+ static constexpr size_t sk = zero;
+ static constexpr size_t minsize =
+ schema::bit + // TODO: merge bit.
+ schema::spend_ +
+ schema::tx;
+ static constexpr size_t minrow = minsize;
+ static constexpr size_t size = minsize;
+ static constexpr linkage count() NOEXCEPT { return 1; }
+ static_assert(minsize == 9u);
+ static_assert(minrow == 9u);
+ };
+
// slab hashmap
struct neutrino
{
diff --git a/test/tables/caches/prevout.cpp b/test/tables/caches/prevout.cpp
new file mode 100644
index 00000000..1d64afd6
--- /dev/null
+++ b/test/tables/caches/prevout.cpp
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
+ *
+ * This file is part of libbitcoin.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+#include "../../test.hpp"
+#include "../../mocks/chunk_storage.hpp"
+
+BOOST_AUTO_TEST_SUITE(prevout_tests)
+
+using namespace system;
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/tables/caches/prevouts.cpp b/test/tables/caches/prevouts.cpp
deleted file mode 100644
index 48ba4c8d..00000000
--- a/test/tables/caches/prevouts.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/////**
-//// * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
-//// *
-//// * This file is part of libbitcoin.
-//// *
-//// * This program is free software: you can redistribute it and/or modify
-//// * it under the terms of the GNU Affero General Public License as published by
-//// * the Free Software Foundation, either version 3 of the License, or
-//// * (at your option) any later version.
-//// *
-//// * This program is distributed in the hope that it will be useful,
-//// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-//// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//// * GNU Affero General Public License for more details.
-//// *
-//// * You should have received a copy of the GNU Affero General Public License
-//// * along with this program. If not, see .
-//// */
-////#include "../../test.hpp"
-////#include "../../mocks/chunk_storage.hpp"
-////
-////BOOST_AUTO_TEST_SUITE(buffer_tests)
-////
-////using namespace system;
-////const chain::transaction empty{};
-////const auto genesis = system::settings{ system::chain::selection::mainnet }.genesis_block;
-////const auto genesis_tx = genesis.transactions_ptr()->front();
-////const table::buffer::key key1{ 0x01, 0x02, 0x03, 0x04 };
-////const table::buffer::key key2{ 0xa1, 0xa2, 0xa3, 0xa4 };
-////const table::buffer::slab slab1{ {}, empty };
-////const table::buffer::slab slab2{ {}, *genesis_tx };
-////const data_chunk expected_head = base16_chunk
-////(
-//// "0000000000"
-//// "1300000000"
-//// "ffffffffff"
-//// "ffffffffff"
-//// "ffffffffff"
-//// "ffffffffff"
-////);
-////const data_chunk closed_head = base16_chunk
-////(
-//// "e800000000"
-//// "1300000000"
-//// "ffffffffff"
-//// "ffffffffff"
-//// "ffffffffff"
-//// "ffffffffff"
-////);
-////const data_chunk expected_body = base16_chunk
-////(
-//// "ffffffffff" // next->end
-//// "01020304" // key1
-//// "00000000000000000000" // tx1 (empty)
-////
-//// "0000000000" // next->
-//// "a1a2a3a4" // key2
-//// "0100000001000000000000000000000000000000000000000"
-//// "0000000000000000000000000ffffffff4d04ffff001d0104"
-//// "455468652054696d65732030332f4a616e2f3230303920436"
-//// "8616e63656c6c6f72206f6e206272696e6b206f6620736563"
-//// "6f6e64206261696c6f757420666f722062616e6b73fffffff"
-//// "f0100f2052a01000000434104678afdb0fe5548271967f1a6"
-//// "7130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4"
-//// "cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6b"
-//// "f11d5fac00000000" // tx2 (genesis[0])
-////);
-////
-////BOOST_AUTO_TEST_CASE(buffer__put__two__expected)
-////{
-//// test::chunk_storage head_store{};
-//// test::chunk_storage body_store{};
-//// table::buffer instance{ head_store, body_store, 5 };
-//// BOOST_REQUIRE(instance.create());
-////
-//// table::buffer::link link1{};
-//// BOOST_REQUIRE(instance.put_link(link1, key1, slab1));
-//// BOOST_REQUIRE_EQUAL(link1, 0u);
-////
-//// table::buffer::link link2{};
-//// BOOST_REQUIRE(instance.put_link(link2, key2, slab2));
-//// BOOST_REQUIRE_EQUAL(link2, 0x13);
-////
-//// BOOST_REQUIRE_EQUAL(head_store.buffer(), expected_head);
-//// BOOST_REQUIRE_EQUAL(body_store.buffer(), expected_body);
-//// BOOST_REQUIRE(instance.close());
-//// BOOST_REQUIRE_EQUAL(head_store.buffer(), closed_head);
-////}
-////
-////BOOST_AUTO_TEST_CASE(buffer__get__two__expected)
-////{
-//// auto head = expected_head;
-//// auto body = expected_body;
-//// test::chunk_storage head_store{ head };
-//// test::chunk_storage body_store{ body };
-//// table::buffer instance{ head_store, body_store, 5 };
-//// BOOST_REQUIRE_EQUAL(head_store.buffer(), expected_head);
-//// BOOST_REQUIRE_EQUAL(body_store.buffer(), expected_body);
-////
-//// table::buffer::slab out{};
-//// BOOST_REQUIRE(instance.get(0u, out));
-//// BOOST_REQUIRE(out == slab1);
-//// BOOST_REQUIRE(instance.get(0x13, out));
-//// BOOST_REQUIRE(out == slab2);
-////}
-////
-////BOOST_AUTO_TEST_CASE(buffer__put__get__expected)
-////{
-//// test::chunk_storage head_store{};
-//// test::chunk_storage body_store{};
-//// table::buffer instance{ head_store, body_store, 5 };
-//// BOOST_REQUIRE(instance.create());
-//// BOOST_REQUIRE(!instance.put_link(key1, table::buffer::slab_ptr
-//// {
-//// {},
-//// to_shared(chain::transaction{})
-//// }).is_terminal());
-//// BOOST_REQUIRE(!instance.put_link(key2, table::buffer::put_ref
-//// {
-//// {},
-//// slab2.tx
-//// }).is_terminal());
-////
-//// table::buffer::slab_ptr out{};
-//// BOOST_REQUIRE(instance.get(0u, out));
-//// BOOST_REQUIRE(*out.tx == slab1.tx);
-//// BOOST_REQUIRE(instance.get(0x13, out));
-//// BOOST_REQUIRE(*out.tx == slab2.tx);
-////}
-////
-////BOOST_AUTO_TEST_SUITE_END()