diff --git a/Makefile.am b/Makefile.am index c732f81d..d6a4bd98 100644 --- a/Makefile.am +++ b/Makefile.am @@ -101,6 +101,7 @@ test_libbitcoin_database_test_SOURCES = \ test/query/optional.cpp \ test/query/translate.cpp \ test/query/validate.cpp \ + test/query/wire.cpp \ test/tables/archives/header.cpp \ test/tables/archives/input.cpp \ test/tables/archives/output.cpp \ @@ -192,7 +193,8 @@ include_bitcoin_database_impl_query_HEADERS = \ include/bitcoin/database/impl/query/optional.ipp \ include/bitcoin/database/impl/query/query.ipp \ include/bitcoin/database/impl/query/translate.ipp \ - include/bitcoin/database/impl/query/validate.ipp + include/bitcoin/database/impl/query/validate.ipp \ + include/bitcoin/database/impl/query/wire.ipp include_bitcoin_database_locksdir = ${includedir}/bitcoin/database/locks include_bitcoin_database_locks_HEADERS = \ 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 10e05d91..f1f1c41a 100644 --- a/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-database-test/libbitcoin-database-test.vcxproj @@ -164,6 +164,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 b7bb295d..175e235e 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 @@ -153,6 +153,9 @@ src\query + + src\query + src diff --git a/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj b/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj index 89a91e7c..971bb10c 100644 --- a/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj @@ -230,6 +230,7 @@ + diff --git a/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj.filters index afcaa58c..e40f6fad 100644 --- a/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-database/libbitcoin-database.vcxproj.filters @@ -379,6 +379,9 @@ include\bitcoin\database\impl\query + + include\bitcoin\database\impl\query + include\bitcoin\database\impl diff --git a/include/bitcoin/database/impl/query/wire.ipp b/include/bitcoin/database/impl/query/wire.ipp new file mode 100644 index 00000000..a348e6d2 --- /dev/null +++ b/include/bitcoin/database/impl/query/wire.ipp @@ -0,0 +1,253 @@ +/** + * Copyright (c) 2011-2026 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_QUERY_WIRE_IPP +#define LIBBITCOIN_DATABASE_QUERY_WIRE_IPP + +#include +#include +#include + +namespace libbitcoin { +namespace database { + +// Wire serialized objects. +// ---------------------------------------------------------------------------- +// Due to the idiotic segwit serialization of witness after output there is are +// duplicated navigations to store_.ins and store_.input by the witness reader. +// This normalized approach is also the most efficient. + +TEMPLATE +bool CLASS::get_wire_header(byteflipper& flipper, + const header_link& link) const NOEXCEPT +{ + const auto start = flipper.get_write_position(); + table::header::wire_header header{ {}, flipper }; + if (!store_.header.get(link, header)) + { + flipper.invalidate(); + return false; + } + + // Genesis header parent is defaulted. + if (header.parent_fk == schema::header::link::terminal) + return true; + + flipper.set_position(start); + table::header::wire_key key{ {}, flipper }; + if (!store_.header.get(header.parent_fk, key)) + { + flipper.invalidate(); + return false; + } + + return true; +} + +TEMPLATE +bool CLASS::get_wire_input(byteflipper& flipper, + const point_link& link) const NOEXCEPT +{ + // [point] + table::point::wire_point point{ {}, flipper }; + if (!store_.point.get(link, point)) + { + flipper.invalidate(); + return false; + } + + // [[size]script] + table::ins::get_input ins{}; + table::input::wire_script script{ {}, flipper }; + if (!store_.ins.get(link, ins) || + !store_.input.get(ins.input_fk, script)) + { + flipper.invalidate(); + return false; + } + + // [sequence] + flipper.write_4_bytes_little_endian(ins.sequence); + return true; +} + +TEMPLATE +bool CLASS::get_wire_output(byteflipper& flipper, + const output_link& link) const NOEXCEPT +{ + // [value][[[size]script]] + table::output::wire_script out{ {}, flipper }; + if (!store_.output.get(link, out)) + { + flipper.invalidate(); + return false; + } + + return true; +} + +TEMPLATE +bool CLASS::get_wire_witness(byteflipper& flipper, + const point_link& link) const NOEXCEPT +{ + // [count][[[size]element]] + table::ins::get_input ins{}; + table::input::wire_witness wire{ {}, flipper }; + if (!store_.ins.get(link, ins) || + !store_.input.get(ins.input_fk, wire)) + { + flipper.invalidate(); + return false; + } + + return true; +} + +TEMPLATE +bool CLASS::get_wire_tx(byteflipper& flipper, const tx_link& link, + bool witness) const NOEXCEPT +{ + table::transaction::record tx{}; + if (!store_.tx.get(link, tx)) + { + flipper.invalidate(); + return false; + } + + table::outs::record outs{}; + outs.out_fks.resize(tx.outs_count); + if (!store_.outs.get(tx.outs_fk, outs)) + { + flipper.invalidate(); + return false; + } + + // Point links are contiguous (computed). + const auto ins_begin = tx.point_fk; + const auto ins_count = tx.ins_count; + const auto ins_final = ins_begin + ins_count; + const auto witnessed = witness && (tx.heavy != tx.light); + + flipper.write_4_bytes_little_endian(tx.version); + + if (witnessed) + { + flipper.write_byte(system::chain::witness_marker); + flipper.write_byte(system::chain::witness_enabled); + } + + flipper.write_variable(ins_count); + for (auto fk = ins_begin; fk < ins_final; ++fk) + if (!get_wire_input(flipper, fk)) + return false; + + flipper.write_variable(outs.out_fks.size()); + for (const auto& fk: outs.out_fks) + if (!get_wire_output(flipper, fk)) + return false; + + if (witnessed) + { + for (auto fk = ins_begin; fk < ins_final; ++fk) + if (!get_wire_witness(flipper, fk)) + return false; + } + + flipper.write_4_bytes_little_endian(tx.locktime); + return true; +} + +TEMPLATE +bool CLASS::get_wire_block(byteflipper& flipper, const header_link& link, + bool witness) const NOEXCEPT +{ + if (!get_wire_header(flipper, link)) + return false; + + const auto txs = to_transactions(link); + if (txs.empty()) + { + flipper.invalidate(); + return false; + } + + flipper.write_variable(txs.size()); + for (const auto& tx_link: txs) + if (!get_wire_tx(flipper, tx_link, witness)) + return false; + + return true; +} + +// These convenience wrappers are made practical by size caching for block and +// tx for both nominal and witness wire encodings (and fixed size headers). +// Intermediate objects (input, output, witness) have a size prefix + +TEMPLATE +data_chunk CLASS::get_wire_header(const header_link& link) const NOEXCEPT +{ + using namespace system; + data_chunk data(chain::header::serialized_size()); + + stream::flip::fast ostream(data); + flip::bytes::fast out(ostream); + if (!get_wire_header(out, link) || !out) + return {}; + + return data; +} + +TEMPLATE +data_chunk CLASS::get_wire_tx(const tx_link& link, bool witness) const NOEXCEPT +{ + using namespace system; + size_t size{}; + if (!get_tx_size(size, link, witness)) + return {}; + + data_chunk data(size); + stream::flip::fast ostream(data); + flip::bytes::fast out(ostream); + if (!get_wire_tx(out, link, witness) || !out) + return {}; + + return data; +} + +TEMPLATE +data_chunk CLASS::get_wire_block(const header_link& link, + bool witness) const NOEXCEPT +{ + using namespace system; + size_t size{}; + if (!get_block_size(size, link, witness)) + return {}; + + data_chunk data(size); + stream::flip::fast ostream(data); + flip::bytes::fast out(ostream); + if (!get_wire_block(out, link, witness) || !out) + return {}; + + return data; +} + +} // namespace database +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/database/query.hpp b/include/bitcoin/database/query.hpp index ea8cf0da..4c9864a0 100644 --- a/include/bitcoin/database/query.hpp +++ b/include/bitcoin/database/query.hpp @@ -350,14 +350,10 @@ class query size_t position) const NOEXCEPT; /// Sizes. - bool get_tx_size(size_t& out, const tx_link& link, - bool witness) const NOEXCEPT; - bool get_block_size(size_t& out, const header_link& link, - bool witness) const NOEXCEPT; - bool get_block_sizes(size_t& light, size_t& heavy, - const header_link& link) const NOEXCEPT; - bool get_tx_sizes(size_t& light, size_t& heavy, - const tx_link& link) const NOEXCEPT; + bool get_tx_size(size_t& out, const tx_link& link, bool witness) const NOEXCEPT; + bool get_block_size(size_t& out, const header_link& link, bool witness) const NOEXCEPT; + bool get_block_sizes(size_t& light, size_t& heavy, const header_link& link) const NOEXCEPT; + bool get_tx_sizes(size_t& light, size_t& heavy, const tx_link& link) const NOEXCEPT; /// Heights. height_link get_height(const hash_digest& key) const NOEXCEPT; @@ -374,6 +370,21 @@ class query bool get_block_spend(uint64_t& out, const header_link& link) const NOEXCEPT; bool get_block_fee(uint64_t& out, const header_link& link) const NOEXCEPT; + /// Wire. + /// ----------------------------------------------------------------------- + + bool get_wire_input(byteflipper& flipper, const point_link& link) const NOEXCEPT; + bool get_wire_output(byteflipper& flipper, const output_link& link) const NOEXCEPT; + bool get_wire_witness(byteflipper& flipper, const point_link& link) const NOEXCEPT; + bool get_wire_header(byteflipper& flipper, const header_link& link) const NOEXCEPT; + bool get_wire_tx(byteflipper& flipper, const tx_link& link, bool witness) const NOEXCEPT; + bool get_wire_block(byteflipper& flipper, const header_link& link, + bool witness) const NOEXCEPT; + + data_chunk get_wire_header(const header_link& link) const NOEXCEPT; + data_chunk get_wire_tx(const tx_link& link, bool witness) const NOEXCEPT; + data_chunk get_wire_block(const header_link& link, bool witness) const NOEXCEPT; + /// Objects. /// ----------------------------------------------------------------------- @@ -836,6 +847,7 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) #include #include #include +#include BC_POP_WARNING() diff --git a/include/bitcoin/database/tables/archives/header.hpp b/include/bitcoin/database/tables/archives/header.hpp index afe23fef..4b5818da 100644 --- a/include/bitcoin/database/tables/archives/header.hpp +++ b/include/bitcoin/database/tables/archives/header.hpp @@ -321,6 +321,45 @@ struct header context ctx{}; uint32_t timestamp{}; }; + + struct wire_key + : public schema::header + { + inline bool from_data(reader& source) NOEXCEPT + { + const auto time_bits_nonce_size = 3u * sizeof(uint32_t); + const auto version_size = sizeof(uint32_t); + source.rewind_bytes(sk); + flipper.skip_bytes(version_size); + flipper.write_bytes(source.read_hash()); + flipper.skip_bytes(schema::hash + time_bits_nonce_size); + return source; + } + + system::byteflipper& flipper; + }; + + struct wire_header + : public schema::header + { + inline bool from_data(reader& source) NOEXCEPT + { + const auto time_bits_nonce_size = 3u * sizeof(uint32_t); + const auto version_size = sizeof(uint32_t); + source.skip_bytes(skip_to_parent); + parent_fk = to_parent(source.read_little_endian()); + flipper.write_bytes(source.read_bytes(version_size)); + flipper.write_bytes(system::null_hash); + source.skip_bytes(time_bits_nonce_size); + flipper.write_bytes(source.read_hash()); + source.rewind_bytes(time_bits_nonce_size + schema::hash); + flipper.write_bytes(source.read_bytes(time_bits_nonce_size)); + return source; + } + + system::byteflipper& flipper; + link::integer parent_fk{}; + }; }; } // namespace table diff --git a/include/bitcoin/database/tables/archives/input.hpp b/include/bitcoin/database/tables/archives/input.hpp index d2eb144c..f9130411 100644 --- a/include/bitcoin/database/tables/archives/input.hpp +++ b/include/bitcoin/database/tables/archives/input.hpp @@ -175,6 +175,47 @@ struct input const system::chain::transaction& tx_{}; }; + + struct wire_script + : public schema::input + { + inline bool from_data(reader& source) NOEXCEPT + { + // script (prefixed) + const auto length = source.read_size(); + flipper.write_variable(length); + flipper.write_bytes(source.read_bytes(length)); + return source; + } + + system::byteflipper& flipper; + }; + + struct wire_witness + : public schema::input + { + inline bool from_data(reader& source) NOEXCEPT + { + // script (skip) + source.skip_bytes(source.read_size()); + + // witness (count) + const auto count = source.read_size(); + flipper.write_variable(count); + + // witness (prefixed) + for (size_t element{}; element < count; ++element) + { + const auto length = source.read_size(); + flipper.write_variable(length); + flipper.write_bytes(source.read_bytes(length)); + } + + return source; + } + + system::byteflipper& flipper; + }; }; BC_POP_WARNING() diff --git a/include/bitcoin/database/tables/archives/ins.hpp b/include/bitcoin/database/tables/archives/ins.hpp index 45620a02..2f48e527 100644 --- a/include/bitcoin/database/tables/archives/ins.hpp +++ b/include/bitcoin/database/tables/archives/ins.hpp @@ -132,6 +132,19 @@ struct ins const tx::integer parent_fk{}; const system::chain::transaction& tx_{}; }; + + struct wire_sequence + : public schema::ins + { + inline bool from_data(reader& source) NOEXCEPT + { + const auto sequence_size = sizeof(uint32_t); + flipper.write_bytes(source.read_bytes(sequence_size)); + return source; + } + + system::byteflipper& flipper; + }; }; } // namespace table diff --git a/include/bitcoin/database/tables/archives/output.hpp b/include/bitcoin/database/tables/archives/output.hpp index 6b54e2f6..595fd860 100644 --- a/include/bitcoin/database/tables/archives/output.hpp +++ b/include/bitcoin/database/tables/archives/output.hpp @@ -46,8 +46,7 @@ struct output inline link count() const NOEXCEPT { return system::possible_narrow_cast( - tx::size + - variable_size(value) + + tx::size + variable_size(value) + script.serialized_size(true)); } @@ -231,6 +230,27 @@ struct output const tx::integer parent_fk{}; const system::chain::transaction& tx_{}; }; + + struct wire_script + : public schema::output + { + inline bool from_data(reader& source) NOEXCEPT + { + // skip: parent_fk + source.skip_bytes(tx::size); + + // value (translates from variable to fixed width) + flipper.write_8_bytes_little_endian(source.read_variable()); + + // script (prefixed) + const auto length = source.read_size(); + flipper.write_variable(length); + flipper.write_bytes(source.read_bytes(length)); + return source; + } + + system::byteflipper& flipper; + }; }; BC_POP_WARNING() diff --git a/include/bitcoin/database/tables/archives/point.hpp b/include/bitcoin/database/tables/archives/point.hpp index 0a5517c1..aef19780 100644 --- a/include/bitcoin/database/tables/archives/point.hpp +++ b/include/bitcoin/database/tables/archives/point.hpp @@ -29,12 +29,19 @@ namespace libbitcoin { namespace database { namespace table { +// There is no value in this table, just search keys. struct point : public hash_map { using hash_map::hashmap; using ix = linkage; + static uint32_t to_index(ix::integer value) NOEXCEPT + { + using namespace system; + return value == ix::terminal ? chain::point::null_index : value; + } + struct record : public schema::point { @@ -42,11 +49,7 @@ struct point { source.rewind_bytes(schema::point::sk); hash = source.read_hash(); - index = source.read_little_endian(); - - if (index == ix::terminal) - index = system::chain::point::null_index; - + index = to_index(source.read_little_endian()); BC_ASSERT(!source || source.get_read_position() == minrow); return source; } @@ -81,7 +84,7 @@ struct point key = { source.read_hash(), - source.read_little_endian() + to_index(source.read_little_endian()) }; BC_ASSERT(!source || source.get_read_position() == minrow); return source; @@ -89,6 +92,21 @@ struct point system::chain::point key{}; }; + + struct wire_point + : public schema::point + { + inline bool from_data(reader& source) NOEXCEPT + { + source.rewind_bytes(schema::point::sk); + flipper.write_bytes(source.read_hash()); + const auto value = source.read_little_endian(); + flipper.write_4_bytes_little_endian(to_index(value)); + return source; + } + + system::byteflipper& flipper; + }; }; } // namespace table diff --git a/include/bitcoin/database/types.hpp b/include/bitcoin/database/types.hpp index 00eb1383..e5fa4bae 100644 --- a/include/bitcoin/database/types.hpp +++ b/include/bitcoin/database/types.hpp @@ -51,6 +51,11 @@ using inpoints = std::set; using outpoint = system::chain::outpoint; using outpoints = std::set; +using data_chunk = system::data_chunk; +using bytereader = system::bytereader; +using bytewriter = system::bytewriter; +using byteflipper = system::byteflipper; + struct header_state { header_link link; code ec; }; using header_states = std::vector; diff --git a/test/mocks/blocks.cpp b/test/mocks/blocks.cpp index 12cfd49c..7ba6ca7a 100644 --- a/test/mocks/blocks.cpp +++ b/test/mocks/blocks.cpp @@ -21,117 +21,751 @@ namespace test { +using namespace system; +constexpr hash_digest two_hash = from_uintx(uint256_t(two)); +constexpr database::context context{ 0x01020304, 0x11121314, 0x21222324 }; + +constexpr hash_digest block0_hash = base16_hash("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); +constexpr hash_digest block1_hash = base16_hash("00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"); +constexpr hash_digest block2_hash = base16_hash("000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd"); +constexpr hash_digest block3_hash = base16_hash("0000000082b5015589a3fdf2d4baff403e6f0be035a5d9742c1cae6295464449"); +constexpr hash_digest block4_hash = base16_hash("000000004ebadb55ee9096c9a2f8880e09da59c0d68b1c228da88e48844a1485"); +constexpr hash_digest block5_hash = base16_hash("000000009b7262315dbf071787ad3656097b892abffd1f95a1a022f896f533fc"); +constexpr hash_digest block6_hash = base16_hash("000000003031a0e73735690c5a1ff2a4be82553b2a12b776fbd3a215dc8f778d"); +constexpr hash_digest block7_hash = base16_hash("0000000071966c2b1d065fd446b1e485b2c9d9594acd2007ccbd5441cfc89444"); +constexpr hash_digest block8_hash = base16_hash("00000000408c48f847aa786c2268fc3e6ec2af68e8468a34a28c61b7f1de0dc6"); +constexpr hash_digest block9_hash = base16_hash("000000008d9dc510f23c2657fc4f67bea30078cc05a90eb89e84cc475c080805"); + +constexpr hash_digest root01 = sha256::double_hash(block0_hash, block1_hash); +constexpr hash_digest root23 = sha256::double_hash(block2_hash, block3_hash); +constexpr hash_digest root03 = sha256::double_hash(root01, root23); +constexpr hash_digest root45 = sha256::double_hash(block4_hash, block5_hash); +constexpr hash_digest root67 = sha256::double_hash(block6_hash, block7_hash); +constexpr hash_digest root47 = sha256::double_hash(root45, root67); +constexpr hash_digest root07 = sha256::double_hash(root03, root47); +constexpr hash_digest root82 = sha256::double_hash(block8_hash, block8_hash); +constexpr hash_digest root84 = sha256::double_hash(root82, root82); +constexpr hash_digest root88 = sha256::double_hash(root84, root84); +constexpr hash_digest root08 = sha256::double_hash(root07, root88); + +constexpr header_data header0_data = base16_array("0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c"); +constexpr header_data header1_data = base16_array("010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e36299"); +constexpr header_data header2_data = base16_array("010000004860eb18bf1b1620e37e9490fc8a427514416fd75159ab86688e9a8300000000d5fdcc541e25de1c7a5addedf24858b8bb665c9f36ef744ee42c316022c90f9bb0bc6649ffff001d08d2bd61"); +constexpr header_data header3_data = base16_array("01000000bddd99ccfda39da1b108ce1a5d70038d0a967bacb68b6b63065f626a0000000044f672226090d85db9a9f2fbfe5f0f9609b387af7be5b7fbb7a1767c831c9e995dbe6649ffff001d05e0ed6d"); +constexpr header_data header4_data = base16_array("010000004944469562ae1c2c74d9a535e00b6f3e40ffbad4f2fda3895501b582000000007a06ea98cd40ba2e3288262b28638cec5337c1456aaf5eedc8e9e5a20f062bdf8cc16649ffff001d2bfee0a9"); +constexpr header_data header5_data = base16_array("0100000085144a84488ea88d221c8bd6c059da090e88f8a2c99690ee55dbba4e00000000e11c48fecdd9e72510ca84f023370c9a38bf91ac5cae88019bee94d24528526344c36649ffff001d1d03e477"); +constexpr header_data header6_data = base16_array("01000000fc33f596f822a0a1951ffdbf2a897b095636ad871707bf5d3162729b00000000379dfb96a5ea8c81700ea4ac6b97ae9a9312b2d4301a29580e924ee6761a2520adc46649ffff001d189c4c97"); +constexpr header_data header7_data = base16_array("010000008d778fdc15a2d3fb76b7122a3b5582bea4f21f5a0c693537e7a03130000000003f674005103b42f984169c7d008370967e91920a6a5d64fd51282f75bc73a68af1c66649ffff001d39a59c86"); +constexpr header_data header8_data = base16_array("010000004494c8cf4154bdcc0720cd4a59d9c9b285e4b146d45f061d2b6c967100000000e3855ed886605b6d4a99d5fa2ef2e9b0b164e63df3c4136bebf2d0dac0f1f7a667c86649ffff001d1c4b5666"); +constexpr header_data header9_data = base16_array("01000000c60ddef1b7618ca2348a46e868afc26e3efc68226c78aa47f8488c4000000000c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd37047fca6649ffff001d28404f53"); + +constexpr block_data block1_data = base16_array("010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e362990101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000"); +constexpr block_data block2_data = base16_array("010000004860eb18bf1b1620e37e9490fc8a427514416fd75159ab86688e9a8300000000d5fdcc541e25de1c7a5addedf24858b8bb665c9f36ef744ee42c316022c90f9bb0bc6649ffff001d08d2bd610101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d010bffffffff0100f2052a010000004341047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77ac00000000"); +constexpr block_data block3_data = base16_array("01000000bddd99ccfda39da1b108ce1a5d70038d0a967bacb68b6b63065f626a0000000044f672226090d85db9a9f2fbfe5f0f9609b387af7be5b7fbb7a1767c831c9e995dbe6649ffff001d05e0ed6d0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d010effffffff0100f2052a0100000043410494b9d3e76c5b1629ecf97fff95d7a4bbdac87cc26099ada28066c6ff1eb9191223cd897194a08d0c2726c5747f1db49e8cf90e75dc3e3550ae9b30086f3cd5aaac00000000"); +constexpr block_data block4_data = base16_array("010000004944469562ae1c2c74d9a535e00b6f3e40ffbad4f2fda3895501b582000000007a06ea98cd40ba2e3288262b28638cec5337c1456aaf5eedc8e9e5a20f062bdf8cc16649ffff001d2bfee0a90101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d011affffffff0100f2052a01000000434104184f32b212815c6e522e66686324030ff7e5bf08efb21f8b00614fb7690e19131dd31304c54f37baa40db231c918106bb9fd43373e37ae31a0befc6ecaefb867ac00000000"); +constexpr block_data block5_data = base16_array("0100000085144a84488ea88d221c8bd6c059da090e88f8a2c99690ee55dbba4e00000000e11c48fecdd9e72510ca84f023370c9a38bf91ac5cae88019bee94d24528526344c36649ffff001d1d03e4770101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0120ffffffff0100f2052a0100000043410456579536d150fbce94ee62b47db2ca43af0a730a0467ba55c79e2a7ec9ce4ad297e35cdbb8e42a4643a60eef7c9abee2f5822f86b1da242d9c2301c431facfd8ac00000000"); +constexpr block_data block6_data = base16_array("01000000fc33f596f822a0a1951ffdbf2a897b095636ad871707bf5d3162729b00000000379dfb96a5ea8c81700ea4ac6b97ae9a9312b2d4301a29580e924ee6761a2520adc46649ffff001d189c4c970101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0123ffffffff0100f2052a0100000043410408ce279174b34c077c7b2043e3f3d45a588b85ef4ca466740f848ead7fb498f0a795c982552fdfa41616a7c0333a269d62108588e260fd5a48ac8e4dbf49e2bcac00000000"); +constexpr block_data block7_data = base16_array("010000008d778fdc15a2d3fb76b7122a3b5582bea4f21f5a0c693537e7a03130000000003f674005103b42f984169c7d008370967e91920a6a5d64fd51282f75bc73a68af1c66649ffff001d39a59c860101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d012bffffffff0100f2052a01000000434104a59e64c774923d003fae7491b2a7f75d6b7aa3f35606a8ff1cf06cd3317d16a41aa16928b1df1f631f31f28c7da35d4edad3603adb2338c4d4dd268f31530555ac00000000"); +constexpr block_data block8_data = base16_array("010000004494c8cf4154bdcc0720cd4a59d9c9b285e4b146d45f061d2b6c967100000000e3855ed886605b6d4a99d5fa2ef2e9b0b164e63df3c4136bebf2d0dac0f1f7a667c86649ffff001d1c4b56660101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d012cffffffff0100f2052a01000000434104cc8d85f5e7933cb18f13b97d165e1189c1fb3e9c98b0dd5446b2a1989883ff9e740a8a75da99cc59a21016caf7a7afd3e4e9e7952983e18d1ff70529d62e0ba1ac00000000"); +constexpr block_data block9_data = base16_array("01000000c60ddef1b7618ca2348a46e868afc26e3efc68226c78aa47f8488c4000000000c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd37047fca6649ffff001d28404f530101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0134ffffffff0100f2052a0100000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000"); + +using namespace system::chain; +const block genesis = system::settings{ selection::mainnet }.genesis_block; +const block block1{ block1_data, true }; +const block block2{ block2_data, true }; +const block block3{ block3_data, true }; +const block block4{ block4_data, true }; +const block block5{ block5_data, true }; +const block block6{ block6_data, true }; +const block block7{ block7_data, true }; +const block block8{ block8_data, true }; +const block block9{ block9_data, true }; + +bool setup_three_block_store(query_t& query) NOEXCEPT +{ + return query.initialize(genesis) && + query.set(block1, database::context{ 0, 1, 0 }, false, false) && + query.set(block2, database::context{ 0, 2, 0 }, false, false) && + query.push_confirmed(query.to_header(block1_hash), false) && + query.push_confirmed(query.to_header(block2_hash), false); +} + +bool setup_three_block_witness_store(query_t& query) NOEXCEPT +{ + return query.initialize(genesis) && + query.set(block1a, database::context{ 0, 1, 0 }, false, false) && + query.set(block2a, database::context{ 0, 2, 0 }, false, false) && + query.push_confirmed(query.to_header(block1a.hash()), false) && + query.push_confirmed(query.to_header(block2a.hash()), false); +} + // Setting block metadata on a shared instance creates test side effects. // Chain objects such as blocks cannot be copied for side-effect-free metadata // tests, since block copy takes shared pointer references. So create new test // blocks for each metadata test. -block get_bogus_block() +const block bogus_block { - return block + header { - header + 0x31323334, + null_hash, + one_hash, + 0x41424344, + 0x51525354, + 0x61626364 + }, + transactions + { + transaction + { + 0x01, + inputs + { + input + { + point{}, + script{}, + witness{}, + 0x02 + }, + input + { + point{}, + script{}, + witness{}, + 0x03 + } + }, + outputs + { + output + { + 0x04, + script{} + } + }, + 0x05 + }, + transaction { - 0x31323334, - system::null_hash, - system::one_hash, - 0x41424344, - 0x51525354, - 0x61626364 + 0x06, + inputs + { + input + { + point{}, + script{}, + witness{}, + 0x07 + }, + input + { + point{}, + script{}, + witness{}, + 0x08 + } + }, + outputs + { + output + { + 0x09, + script{} + } + }, + 0x0a }, - transactions - { - transaction - { - 0x01, - inputs - { - input - { - point{}, - script{}, - witness{}, - 0x02 - }, - input - { - point{}, - script{}, - witness{}, - 0x03 - } + transaction + { + 0x0b, + inputs + { + input + { + point{}, + script{}, + witness{}, + 0x0c + }, + input + { + point{}, + script{}, + witness{}, + 0x0d + } + }, + outputs + { + output + { + 0x0e, + script{} + } + }, + 0x0f + } + } +}; +const block block1a +{ + header + { + 0x31323334, // version + block0_hash, // previous_block_hash + null_hash, // merkle_root + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + // This first transaction is *not* a coinbase. + transaction // tx#1 + { + 0x2a, // version + inputs + { + input + { + point{ one_hash, 0x18 }, // missing prevout + script{ { { opcode::op_return }, { opcode::pick } } }, + witness{ "[242424]" }, + 0x2a // sequence + }, + input + { + point{ one_hash, 0x2a }, // missing prevout + script{ { { opcode::op_return }, { opcode::roll } } }, + witness{ "[313131]" }, + 0x18 // sequence + }, + input + { + point{ two_hash, 0x2b }, // missing prevout + script{ { { opcode::op_return }, { opcode::roll } } }, + witness{ "[424242]" }, + 0x19 // sequence + } + }, + outputs + { + output + { + 0x18, // value + script{ { { opcode::pick } } } }, - outputs + output + { + 0x2a, // value + script{ { { opcode::roll } } } + } + }, + 0x18 // locktime + } + } +}; +const block block2a +{ + header + { + 0x31323334, // version + block1a.hash(), // previous_block_hash + one_hash, // merkle_root + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + // This first transaction is *not* a coinbase. + transaction // tx#2 + { + 0xa2, // version + inputs + { + input { - output - { - 0x04, - script{} - } + // existing prevout + point{ block1a.transactions_ptr()->front()->hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::pick } } }, + witness{ "[242424]" }, + 0xa2 // sequence }, - 0x05 - }, - transaction - { - 0x06, - inputs - { - input - { - point{}, - script{}, - witness{}, - 0x07 - }, - input - { - point{}, - script{}, - witness{}, - 0x08 - } + input + { + // existing prevout + point{ block1a.transactions_ptr()->front()->hash(false), 0x01 }, + script{ { { opcode::checkmultisig }, { opcode::roll } } }, + witness{ "[313131]" }, + 0x81 // sequence + } + }, + outputs + { + output + { + 0x81, // value + script{ { { opcode::pick } } } + } + }, + 0x81 // locktime + }, + transaction // tx#3 + { + 0xa2, // version + inputs + { + input + { + point{ one_hash, 0x20 }, // missing prevout + script{ { { opcode::checkmultisig }, { opcode::pick } } }, + witness{ "[242424]" }, + 0xa2 // sequence }, - outputs + input + { + point{ one_hash, 0x21 }, // missing prevout + script{ { { opcode::checkmultisig }, { opcode::roll } } }, + witness{ "[313131]" }, + 0x81 // sequence + } + }, + outputs + { + output + { + 0x81, // value + script{ { { opcode::pick } } } + } + }, + 0x81 // locktime + } + } +}; +const transaction tx4 +{ + 0xa5, // version + inputs + { + input + { + point{ block1a.transactions_ptr()->front()->hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::pick } } }, + witness{ "[252525]" }, + 0xa5 // sequence + }, + input + { + point{ block1a.transactions_ptr()->front()->hash(false), 0x01 }, + script{ { { opcode::checkmultisig }, { opcode::roll } } }, + witness{ "[353535]" }, + 0x85 // sequence + } + }, + outputs + { + output + { + 0x85, // value + script{ { { opcode::pick } } } + } + }, + 0x85 // locktime +}; +const transaction tx5 +{ + 0xa5, // version + inputs + { + input + { + point{ block1a.transactions_ptr()->front()->hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::pick } } }, + witness{ "[252525]" }, + 0xa5 // sequence + } + }, + outputs + { + output + { + 0x85, // value + script{ { { opcode::pick } } } + } + }, + 0x85 // locktime +}; +const block block_spend_1a +{ + header + { + 0x31323334, // version + block1a.hash(), // previous_block_hash + two_hash, // merkle_root (two_hash allows double spend) + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + tx4 + } +}; +const transaction tx_spend_genesis +{ + 0xa6, + inputs + { + input + { + // Spend genesis. + point{ genesis.transactions_ptr()->front()->hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::pick } } }, + witness{ "[262626]" }, + 0xa6 + } + }, + outputs + { + output + { + 0x86, + script{ { { opcode::pick } } } + } + }, + 0x86 +}; +const block block_spend_genesis +{ + header + { + 0x31323334, // version + block0_hash, // previous_block_hash + null_hash, // merkle_root + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + tx_spend_genesis + } +}; +const block block3a +{ + header + { + 0x31323334, // version + block2a.hash(), // previous_block_hash + two_hash, // merkle_root + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + // This first transaction is *not* a coinbase. + transaction + { + 0xa3, // version + inputs + { + input { - output - { - 0x09, - script{} - } + // existing prevout + point{ block1a.transactions_ptr()->front()->hash(false), 0x01 }, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{ "[949494]" }, + 0xa3 // sequence }, - 0x0a - }, - transaction - { - 0x0b, - inputs - { - input - { - point{}, - script{}, - witness{}, - 0x0c - }, - input - { - point{}, - script{}, - witness{}, - 0x0d - } + input + { + // existing prevout + point{ block1a.transactions_ptr()->front()->hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{ "[919191]" }, + 0x83 // sequence + } + }, + outputs + { + output + { + 0x83, // value + script{ { { opcode::pick } } } + } + }, + 0x83 // locktime + } + } +}; +const block block1b +{ + header + { + 0x31323334, // version + block0_hash, // previous_block_hash + null_hash, // merkle_root + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + // This first transaction is a coinbase. + transaction // tx#1 + { + 0xb1, + inputs + { + input + { + point{}, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{}, + 0xb1 + } + }, + outputs + { + output + { + 0xb1, + script{ { { opcode::pick } } } }, - outputs + output + { + 0xb1, + script{ { { opcode::pick } } } + } + }, + 0xb1 + } + } +}; +const block block2b +{ + header + { + 0x31323334, // version + block1b.hash(), // previous_block_hash + one_hash, // merkle_root + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + // This first transaction is a coinbase. + transaction // tx#2 + { + 0xb2, + inputs + { + input { - output - { - 0x0e, - script{} - } + point{ block1b.transactions_ptr()->front()->hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{}, + 0xb2 }, - 0x0f + input + { + point{ block1b.transactions_ptr()->front()->hash(false), 0x01 }, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{}, + 0xb2 + } + }, + outputs + { + output + { + 0xb2, + script{ { { opcode::pick } } } + } + }, + 0xb2 + } + } +}; +const transaction tx2b +{ + transaction + { + 0xb1, + inputs + { + input + { + // Spends block1b coinbase. + point{ block1b.transactions_ptr()->front()->hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{}, + 0xb1 } + }, + outputs + { + output + { + 0xb1, + script{ { { opcode::pick } } } + } + }, + 0xb1 + } +}; +const block block_spend_internal_2b +{ + header + { + 0x31323334, // version + block1b.hash(), // previous_block_hash + one_hash, // merkle_root + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + tx2b, // tx#2 + transaction // tx#3 + { + 0xb2, + inputs + { + input + { + // Spends tx2b:0. + point{ tx2b.hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{}, + 0xb2 + } + }, + outputs + { + output + { + 0xb2, + script{ { { opcode::pick } } } + } + }, + 0xb2 } - }; -} + } +}; +const block block_missing_prevout_2b +{ + header + { + 0x31323334, // version + block1b.hash(), // previous_block_hash + one_hash, // merkle_root + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + tx2b, // tx#2 + transaction // tx#3 + { + 0xb2, + inputs + { + input + { + // missing prevout index. + point{ tx2b.hash(false), 0x01 }, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{}, + 0xb2 + } + }, + outputs + { + output + { + 0xb0, // fee will be 0x01 + script{ { { opcode::pick } } } + } + }, + 0xb2 + } + } +}; +const block block_valid_spend_internal_2b +{ + header + { + 0x31323334, // version + block1b.hash(), // previous_block_hash + one_hash, // merkle_root + 0x41424344, // timestamp + 0x51525354, // bits + 0x61626364 // nonce + }, + transactions + { + tx2b, // tx#2 + transaction // tx#3 + { + 0xb2, + inputs + { + input + { + point{ tx2b.hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{}, + 0xb2 + } + }, + outputs + { + output + { + 0xb0, // fee will be 0x01 + script{ { { opcode::pick } } } + } + }, + 0xb2 + }, + transaction // tx#4 + { + 0xb2, + inputs + { + input + { + point{ block1b.transactions_ptr()->front()->hash(false), 0x00 }, + script{ { { opcode::checkmultisig }, { opcode::size } } }, + witness{}, + 0xb2 + }, + input + { + point{ block1b.transactions_ptr()->front()->hash(false), 0x01 }, + script{ { { opcode::checkmultisig } } }, + witness{}, + 0xb2 + } + }, + outputs + { + output + { + 0xb2, // fee will be 0xb1 + 0xb1 - 0xb2 = 0xb0 + script{ { { opcode::pick }, { opcode::roll }, { opcode::pick } } } + } + }, + 0xb2 + } + } +}; } // namespace test diff --git a/test/mocks/blocks.hpp b/test/mocks/blocks.hpp index c30c483b..82bc02ce 100644 --- a/test/mocks/blocks.hpp +++ b/test/mocks/blocks.hpp @@ -23,608 +23,86 @@ namespace test { -constexpr auto block0_hash = system::base16_hash("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); -constexpr auto block1_hash = system::base16_hash("00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"); -constexpr auto block2_hash = system::base16_hash("000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd"); -constexpr auto block3_hash = system::base16_hash("0000000082b5015589a3fdf2d4baff403e6f0be035a5d9742c1cae6295464449"); -constexpr auto block4_hash = system::base16_hash("000000004ebadb55ee9096c9a2f8880e09da59c0d68b1c228da88e48844a1485"); -constexpr auto block5_hash = system::base16_hash("000000009b7262315dbf071787ad3656097b892abffd1f95a1a022f896f533fc"); -constexpr auto block6_hash = system::base16_hash("000000003031a0e73735690c5a1ff2a4be82553b2a12b776fbd3a215dc8f778d"); -constexpr auto block7_hash = system::base16_hash("0000000071966c2b1d065fd446b1e485b2c9d9594acd2007ccbd5441cfc89444"); -constexpr auto block8_hash = system::base16_hash("00000000408c48f847aa786c2268fc3e6ec2af68e8468a34a28c61b7f1de0dc6"); +using block_data = system::data_array<215>; +using header_data = system::data_array<80>; +using store_t = database::store; +using query_t = database::query>; +const auto events_handler = [](auto, auto) {}; +extern const database::context context; -// blockchain.info/rawblock/[block-hash]?format=hex -constexpr auto block1_data = system::base16_array("010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e362990101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000"); -constexpr auto block2_data = system::base16_array("010000004860eb18bf1b1620e37e9490fc8a427514416fd75159ab86688e9a8300000000d5fdcc541e25de1c7a5addedf24858b8bb665c9f36ef744ee42c316022c90f9bb0bc6649ffff001d08d2bd610101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d010bffffffff0100f2052a010000004341047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77ac00000000"); -constexpr auto block3_data = system::base16_array("01000000bddd99ccfda39da1b108ce1a5d70038d0a967bacb68b6b63065f626a0000000044f672226090d85db9a9f2fbfe5f0f9609b387af7be5b7fbb7a1767c831c9e995dbe6649ffff001d05e0ed6d0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d010effffffff0100f2052a0100000043410494b9d3e76c5b1629ecf97fff95d7a4bbdac87cc26099ada28066c6ff1eb9191223cd897194a08d0c2726c5747f1db49e8cf90e75dc3e3550ae9b30086f3cd5aaac00000000"); -constexpr auto block4_data = system::base16_array("010000004944469562ae1c2c74d9a535e00b6f3e40ffbad4f2fda3895501b582000000007a06ea98cd40ba2e3288262b28638cec5337c1456aaf5eedc8e9e5a20f062bdf8cc16649ffff001d2bfee0a90101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d011affffffff0100f2052a01000000434104184f32b212815c6e522e66686324030ff7e5bf08efb21f8b00614fb7690e19131dd31304c54f37baa40db231c918106bb9fd43373e37ae31a0befc6ecaefb867ac00000000"); -constexpr auto block5_data = system::base16_array("0100000085144a84488ea88d221c8bd6c059da090e88f8a2c99690ee55dbba4e00000000e11c48fecdd9e72510ca84f023370c9a38bf91ac5cae88019bee94d24528526344c36649ffff001d1d03e4770101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0120ffffffff0100f2052a0100000043410456579536d150fbce94ee62b47db2ca43af0a730a0467ba55c79e2a7ec9ce4ad297e35cdbb8e42a4643a60eef7c9abee2f5822f86b1da242d9c2301c431facfd8ac00000000"); -constexpr auto block6_data = system::base16_array("01000000fc33f596f822a0a1951ffdbf2a897b095636ad871707bf5d3162729b00000000379dfb96a5ea8c81700ea4ac6b97ae9a9312b2d4301a29580e924ee6761a2520adc46649ffff001d189c4c970101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0123ffffffff0100f2052a0100000043410408ce279174b34c077c7b2043e3f3d45a588b85ef4ca466740f848ead7fb498f0a795c982552fdfa41616a7c0333a269d62108588e260fd5a48ac8e4dbf49e2bcac00000000"); -constexpr auto block7_data = system::base16_array("010000008d778fdc15a2d3fb76b7122a3b5582bea4f21f5a0c693537e7a03130000000003f674005103b42f984169c7d008370967e91920a6a5d64fd51282f75bc73a68af1c66649ffff001d39a59c860101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d012bffffffff0100f2052a01000000434104a59e64c774923d003fae7491b2a7f75d6b7aa3f35606a8ff1cf06cd3317d16a41aa16928b1df1f631f31f28c7da35d4edad3603adb2338c4d4dd268f31530555ac00000000"); -constexpr auto block8_data = system::base16_array("010000004494c8cf4154bdcc0720cd4a59d9c9b285e4b146d45f061d2b6c967100000000e3855ed886605b6d4a99d5fa2ef2e9b0b164e63df3c4136bebf2d0dac0f1f7a667c86649ffff001d1c4b56660101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d012cffffffff0100f2052a01000000434104cc8d85f5e7933cb18f13b97d165e1189c1fb3e9c98b0dd5446b2a1989883ff9e740a8a75da99cc59a21016caf7a7afd3e4e9e7952983e18d1ff70529d62e0ba1ac00000000"); +extern const system::hash_digest block0_hash; +extern const system::hash_digest block1_hash; +extern const system::hash_digest block2_hash; +extern const system::hash_digest block3_hash; +extern const system::hash_digest block4_hash; +extern const system::hash_digest block5_hash; +extern const system::hash_digest block6_hash; +extern const system::hash_digest block7_hash; +extern const system::hash_digest block8_hash; +extern const system::hash_digest block9_hash; -constexpr hash_digest two_hash = system::from_uintx(uint256_t(two)); -constexpr database::context context -{ - 0x01020304, // flags - 0x11121314, // height - 0x21222324 // mtp -}; +extern const system::hash_digest root01; +extern const system::hash_digest root23; +extern const system::hash_digest root03; +extern const system::hash_digest root45; +extern const system::hash_digest root67; +extern const system::hash_digest root47; +extern const system::hash_digest root07; +extern const system::hash_digest root82; +extern const system::hash_digest root84; +extern const system::hash_digest root88; +extern const system::hash_digest root08; -using namespace system::chain; +extern const header_data header0_data; +extern const header_data header1_data; +extern const header_data header2_data; +extern const header_data header3_data; +extern const header_data header4_data; +extern const header_data header5_data; +extern const header_data header6_data; +extern const header_data header7_data; +extern const header_data header8_data; +extern const header_data header9_data; -// defined in blocks.cpp. -block get_bogus_block(); +extern const block_data block1_data; +extern const block_data block2_data; +extern const block_data block3_data; +extern const block_data block4_data; +extern const block_data block5_data; +extern const block_data block6_data; +extern const block_data block7_data; +extern const block_data block8_data; +extern const block_data block9_data; -const auto genesis = system::settings{ selection::mainnet }.genesis_block; -const block block1{ test::block1_data, true }; -const block block2{ test::block2_data, true }; -const block block3{ test::block3_data, true }; -const block block4{ test::block4_data, true }; -const block block5{ test::block5_data, true }; -const block block6{ test::block6_data, true }; -const block block7{ test::block7_data, true }; -const block block8{ test::block8_data, true }; +extern const system::chain::block genesis; +extern const system::chain::block block1; +extern const system::chain::block block2; +extern const system::chain::block block3; +extern const system::chain::block block4; +extern const system::chain::block block5; +extern const system::chain::block block6; +extern const system::chain::block block7; +extern const system::chain::block block8; +extern const system::chain::block block9; -const block block1a -{ - header - { - 0x31323334, // version - genesis.hash(), // previous_block_hash - system::null_hash, // merkle_root - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - // This first transaction is *not* a coinbase. - transaction // tx#1 - { - 0x2a, // version - inputs - { - input - { - point{ system::one_hash, 0x18 }, // missing prevout - script{ { { opcode::op_return }, { opcode::pick } } }, - witness{ "[242424]" }, - 0x2a // sequence - }, - input - { - point{ system::one_hash, 0x2a }, // missing prevout - script{ { { opcode::op_return }, { opcode::roll } } }, - witness{ "[313131]" }, - 0x18 // sequence - }, - input - { - point{ two_hash, 0x2b }, // missing prevout - script{ { { opcode::op_return }, { opcode::roll } } }, - witness{ "[424242]" }, - 0x19 // sequence - } - }, - outputs - { - output - { - 0x18, // value - script{ { { opcode::pick } } } - }, - output - { - 0x2a, // value - script{ { { opcode::roll } } } - } - }, - 0x18 // locktime - } - } -}; -const block block2a -{ - header - { - 0x31323334, // version - block1a.hash(), // previous_block_hash - system::one_hash, // merkle_root - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - // This first transaction is *not* a coinbase. - transaction // tx#2 - { - 0xa2, // version - inputs - { - input - { - // existing prevout - point{ block1a.transactions_ptr()->front()->hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::pick } } }, - witness{ "[242424]" }, - 0xa2 // sequence - }, - input - { - // existing prevout - point{ block1a.transactions_ptr()->front()->hash(false), 0x01 }, - script{ { { opcode::checkmultisig }, { opcode::roll } } }, - witness{ "[313131]" }, - 0x81 // sequence - } - }, - outputs - { - output - { - 0x81, // value - script{ { { opcode::pick } } } - } - }, - 0x81 // locktime - }, - transaction // tx#3 - { - 0xa2, // version - inputs - { - input - { - point{ system::one_hash, 0x20 }, // missing prevout - script{ { { opcode::checkmultisig }, { opcode::pick } } }, - witness{ "[242424]" }, - 0xa2 // sequence - }, - input - { - point{ system::one_hash, 0x21 }, // missing prevout - script{ { { opcode::checkmultisig }, { opcode::roll } } }, - witness{ "[313131]" }, - 0x81 // sequence - } - }, - outputs - { - output - { - 0x81, // value - script{ { { opcode::pick } } } - } - }, - 0x81 // locktime - } - } -}; -const transaction tx4 -{ - 0xa5, // version - inputs - { - input - { - point{ block1a.transactions_ptr()->front()->hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::pick } } }, - witness{ "[252525]" }, - 0xa5 // sequence - }, - input - { - point{ block1a.transactions_ptr()->front()->hash(false), 0x01 }, - script{ { { opcode::checkmultisig }, { opcode::roll } } }, - witness{ "[353535]" }, - 0x85 // sequence - } - }, - outputs - { - output - { - 0x85, // value - script{ { { opcode::pick } } } - } - }, - 0x85 // locktime -}; -const transaction tx5 -{ - 0xa5, // version - inputs - { - input - { - point{ block1a.transactions_ptr()->front()->hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::pick } } }, - witness{ "[252525]" }, - 0xa5 // sequence - } - }, - outputs - { - output - { - 0x85, // value - script{ { { opcode::pick } } } - } - }, - 0x85 // locktime -}; -const block block_spend_1a -{ - header - { - 0x31323334, // version - block1a.hash(), // previous_block_hash - two_hash, // merkle_root (two_hash allows double spend) - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - tx4 - } -}; -const transaction tx_spend_genesis -{ - 0xa6, - inputs - { - input - { - // Spend genesis. - point{ genesis.transactions_ptr()->front()->hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::pick } } }, - witness{ "[262626]" }, - 0xa6 - } - }, - outputs - { - output - { - 0x86, - script{ { { opcode::pick } } } - } - }, - 0x86 -}; -const block block_spend_genesis -{ - header - { - 0x31323334, // version - genesis.hash(), // previous_block_hash - system::null_hash, // merkle_root - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - tx_spend_genesis - } -}; -const block block3a -{ - header - { - 0x31323334, // version - block2a.hash(), // previous_block_hash - two_hash, // merkle_root - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - // This first transaction is *not* a coinbase. - transaction - { - 0xa3, // version - inputs - { - input - { - // existing prevout - point{ block1a.transactions_ptr()->front()->hash(false), 0x01 }, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{ "[949494]" }, - 0xa3 // sequence - }, - input - { - // existing prevout - point{ block1a.transactions_ptr()->front()->hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{ "[919191]" }, - 0x83 // sequence - } - }, - outputs - { - output - { - 0x83, // value - script{ { { opcode::pick } } } - } - }, - 0x83 // locktime - } - } -}; -const block block1b -{ - header - { - 0x31323334, // version - genesis.hash(), // previous_block_hash - system::null_hash, // merkle_root - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - // This first transaction is a coinbase. - transaction // tx#1 - { - 0xb1, - inputs - { - input - { - point{}, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{}, - 0xb1 - } - }, - outputs - { - output - { - 0xb1, - script{ { { opcode::pick } } } - }, - output - { - 0xb1, - script{ { { opcode::pick } } } - } - }, - 0xb1 - } - } -}; -const block block2b -{ - header - { - 0x31323334, // version - block1b.hash(), // previous_block_hash - system::one_hash, // merkle_root - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - // This first transaction is a coinbase. - transaction // tx#2 - { - 0xb2, - inputs - { - input - { - point{ block1b.transactions_ptr()->front()->hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{}, - 0xb2 - }, - input - { - point{ block1b.transactions_ptr()->front()->hash(false), 0x01 }, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{}, - 0xb2 - } - }, - outputs - { - output - { - 0xb2, - script{ { { opcode::pick } } } - } - }, - 0xb2 - } - } -}; -const transaction tx2b -{ - transaction - { - 0xb1, - inputs - { - input - { - // Spends block1b coinbase. - point{ block1b.transactions_ptr()->front()->hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{}, - 0xb1 - } - }, - outputs - { - output - { - 0xb1, - script{ { { opcode::pick } } } - } - }, - 0xb1 - } -}; -const block block_spend_internal_2b -{ - header - { - 0x31323334, // version - block1b.hash(), // previous_block_hash - system::one_hash, // merkle_root - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - tx2b, // tx#2 - transaction // tx#3 - { - 0xb2, - inputs - { - input - { - // Spends tx2b:0. - point{ tx2b.hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{}, - 0xb2 - } - }, - outputs - { - output - { - 0xb2, - script{ { { opcode::pick } } } - } - }, - 0xb2 - } - } -}; -const block block_missing_prevout_2b -{ - header - { - 0x31323334, // version - block1b.hash(), // previous_block_hash - system::one_hash, // merkle_root - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - tx2b, // tx#2 - transaction // tx#3 - { - 0xb2, - inputs - { - input - { - // missing prevout index. - point{ tx2b.hash(false), 0x01 }, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{}, - 0xb2 - } - }, - outputs - { - output - { - 0xb0, // fee will be 0x01 - script{ { { opcode::pick } } } - } - }, - 0xb2 - } - } -}; -const block block_valid_spend_internal_2b -{ - header - { - 0x31323334, // version - block1b.hash(), // previous_block_hash - system::one_hash, // merkle_root - 0x41424344, // timestamp - 0x51525354, // bits - 0x61626364 // nonce - }, - transactions - { - tx2b, // tx#2 - transaction // tx#3 - { - 0xb2, - inputs - { - input - { - point{ tx2b.hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{}, - 0xb2 - } - }, - outputs - { - output - { - 0xb0, // fee will be 0x01 - script{ { { opcode::pick } } } - } - }, - 0xb2 - }, - transaction // tx#4 - { - 0xb2, - inputs - { - input - { - point{ block1b.transactions_ptr()->front()->hash(false), 0x00 }, - script{ { { opcode::checkmultisig }, { opcode::size } } }, - witness{}, - 0xb2 - }, - input - { - point{ block1b.transactions_ptr()->front()->hash(false), 0x01 }, - script{ { { opcode::checkmultisig } } }, - witness{}, - 0xb2 - } - }, - outputs - { - output - { - 0xb2, // fee will be 0xb1 + 0xb1 - 0xb2 = 0xb0 - script{ { { opcode::pick }, { opcode::roll }, { opcode::pick } } } - } - }, - 0xb2 - } - } -}; +extern const system::chain::block bogus_block; +extern const system::chain::block block1a; +extern const system::chain::block block2a; +extern const system::chain::transaction tx4; +extern const system::chain::transaction tx5; +extern const system::chain::block block_spend_1a; +extern const system::chain::transaction tx_spend_genesis; +extern const system::chain::block block_spend_genesis; +extern const system::chain::block block3a; +extern const system::chain::block block1b; +extern const system::chain::block block2b; +extern const system::chain::transaction tx2b; +extern const system::chain::block block_spend_internal_2b; +extern const system::chain::block block_missing_prevout_2b; +extern const system::chain::block block_valid_spend_internal_2b; + +bool setup_three_block_store(query_t& query) NOEXCEPT; +bool setup_three_block_witness_store(query_t& query) NOEXCEPT; } // namespace test diff --git a/test/mocks/map_store.hpp b/test/mocks/map_store.hpp index 09517f92..7701b50d 100644 --- a/test/mocks/map_store.hpp +++ b/test/mocks/map_store.hpp @@ -23,9 +23,6 @@ namespace test { -// nop event handler. -const auto events_handler = [](auto, auto) {}; - // store test accessor. class map_store : public store @@ -38,17 +35,17 @@ class map_store inline code backup_() NOEXCEPT { - return backup(events_handler); + return backup([](auto, auto) {}); } inline code dump_(const std::filesystem::path& folder) NOEXCEPT { - return dump(folder, events_handler); + return dump(folder, [](auto, auto) {}); } inline code restore_() NOEXCEPT { - return restore(events_handler); + return restore([](auto, auto) {}); } inline const settings& configuration() const NOEXCEPT diff --git a/test/query/merkle.cpp b/test/query/merkle.cpp index db358199..4df6557d 100644 --- a/test/query/merkle.cpp +++ b/test/query/merkle.cpp @@ -38,22 +38,6 @@ const auto events_handler = [](auto, auto) {}; // "root ": "e347b1c43fd9b5415bf0d92708db8284b78daf4d0e24f9c3405f45feb85e25db" //} -constexpr auto root01 = system::sha256::double_hash(test::block0_hash, test::block1_hash); -constexpr auto root23 = system::sha256::double_hash(test::block2_hash, test::block3_hash); -constexpr auto root03 = system::sha256::double_hash(root01, root23); - -constexpr auto root45 = system::sha256::double_hash(test::block4_hash, test::block5_hash); -constexpr auto root67 = system::sha256::double_hash(test::block6_hash, test::block7_hash); -constexpr auto root47 = system::sha256::double_hash(root45, root67); - -constexpr auto root07 = system::sha256::double_hash(root03, root47); - -constexpr auto root82 = system::sha256::double_hash(test::block8_hash, test::block8_hash); -constexpr auto root84 = system::sha256::double_hash(root82, root82); -constexpr auto root88 = system::sha256::double_hash(root84, root84); - -constexpr auto root08 = system::sha256::double_hash(root07, root88); - class merkle_accessor : public test::query_accessor { @@ -307,8 +291,8 @@ BOOST_AUTO_TEST_CASE(query_merkle__create_interval__depth_1__expected) BOOST_CHECK( query.create_interval(header1, 1).has_value()); BOOST_CHECK(!query.create_interval(header2, 2).has_value()); BOOST_CHECK( query.create_interval(header3, 3).has_value()); - BOOST_CHECK_EQUAL(query.create_interval(header1, 1).value(), root01); - BOOST_CHECK_EQUAL(query.create_interval(header3, 3).value(), root23); + BOOST_CHECK_EQUAL(query.create_interval(header1, 1).value(), test::root01); + BOOST_CHECK_EQUAL(query.create_interval(header3, 3).value(), test::root23); } BOOST_AUTO_TEST_CASE(query_merkle__create_interval__depth_2__expected) @@ -327,7 +311,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__create_interval__depth_2__expected) const auto header3 = query.to_header(test::block3_hash); BOOST_CHECK(!header3.is_terminal()); BOOST_CHECK(query.create_interval(header3, 3).has_value()); - BOOST_CHECK_EQUAL(query.create_interval(header3, 3).value(), root03); + BOOST_CHECK_EQUAL(query.create_interval(header3, 3).value(), test::root03); } // get_confirmed_interval @@ -416,7 +400,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__merge_merkle__three_leaves_target_two__expect merkle_accessor::merge_merkle(to, std::move(from), 2, 0); BOOST_CHECK_EQUAL(to.size(), 2u); BOOST_CHECK_EQUAL(to[0], test::block2_hash); - BOOST_CHECK_EQUAL(to[1], root01); + BOOST_CHECK_EQUAL(to[1], test::root01); } BOOST_AUTO_TEST_CASE(query_merkle__merge_merkle__four_leaves_target_three__expected) @@ -433,7 +417,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__merge_merkle__four_leaves_target_three__expec merkle_accessor::merge_merkle(to, std::move(from), 3, 0); BOOST_CHECK_EQUAL(to.size(), 2u); BOOST_CHECK_EQUAL(to[0], test::block2_hash); - BOOST_CHECK_EQUAL(to[1], root01); + BOOST_CHECK_EQUAL(to[1], test::root01); } // get_merkle_proof @@ -473,7 +457,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_proof__target_in_first_interval__e BOOST_CHECK_EQUAL(query.get_merkle_proof(proof, {}, 3u, 3u), error::success); BOOST_CHECK_EQUAL(proof.size(), 2u); BOOST_CHECK_EQUAL(proof[0], test::block2_hash); - BOOST_CHECK_EQUAL(proof[1], root01); + BOOST_CHECK_EQUAL(proof[1], test::root01); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_proof__multiple_intervals__expected) @@ -495,13 +479,13 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_proof__multiple_intervals__expecte hashes proof{}; const hashes roots { - root01, - root23 + test::root01, + test::root23 }; BOOST_CHECK_EQUAL(query.get_merkle_proof(proof, roots, 3u, 3u), error::success); BOOST_CHECK_EQUAL(proof.size(), 2u); BOOST_CHECK_EQUAL(proof[0], test::block2_hash); - BOOST_CHECK_EQUAL(proof[1], root01); + BOOST_CHECK_EQUAL(proof[1], test::root01); } // get_merkle_subroots @@ -545,7 +529,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_subroots__one_full_interval__expec BOOST_CHECK_EQUAL(roots.size(), 1u); // At depth 2, the 4th position (block 3) results in an interval subroot as the root. - BOOST_CHECK_EQUAL(roots[0], root03); + BOOST_CHECK_EQUAL(roots[0], test::root03); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_subroots__full_and_partial_interval__expected_two_roots) @@ -571,11 +555,11 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_subroots__full_and_partial_interva hashes roots{}; BOOST_CHECK_EQUAL(query.get_merkle_subroots(roots, 5), error::success); BOOST_CHECK_EQUAL(roots.size(), 2u); - BOOST_CHECK_EQUAL(roots[0], root03); + BOOST_CHECK_EQUAL(roots[0], test::root03); // At depth 2, the 6th position (block 5) results in one complete and one partial root. - constexpr auto root45 = system::sha256::double_hash(test::block4_hash, test::block5_hash); - constexpr auto root4545 = system::sha256::double_hash(root45, root45); + const auto root45 = system::sha256::double_hash(test::block4_hash, test::block5_hash); + const auto root4545 = system::sha256::double_hash(root45, test::root45); BOOST_CHECK_EQUAL(roots[1], root4545); } @@ -603,9 +587,9 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__target_equals_wayp BOOST_CHECK(!query.get_merkle_root_and_proof(root, proof, 3, 3)); BOOST_CHECK_EQUAL(proof.size(), 2u); BOOST_CHECK_EQUAL(proof[0], test::block2_hash); - BOOST_CHECK_EQUAL(proof[1], root01); + BOOST_CHECK_EQUAL(proof[1], test::root01); BOOST_CHECK_EQUAL(root, query.get_merkle_root(3)); - BOOST_CHECK_EQUAL(root, root03); + BOOST_CHECK_EQUAL(root, test::root03); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__target_less_than_waypoint__success) @@ -629,9 +613,9 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__target_less_than_w BOOST_CHECK(!query.get_merkle_root_and_proof(root, proof, 1, 3)); BOOST_CHECK_EQUAL(proof.size(), 2u); BOOST_CHECK_EQUAL(proof[0], test::block0_hash); - BOOST_CHECK_EQUAL(proof[1], root23); + BOOST_CHECK_EQUAL(proof[1], test::root23); BOOST_CHECK_EQUAL(root, query.get_merkle_root(3)); - BOOST_CHECK_EQUAL(root, root03); + BOOST_CHECK_EQUAL(root, test::root03); } bool setup_eight_block_store(merkle_accessor& query) @@ -678,17 +662,17 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_ BOOST_CHECK_EQUAL(roots[7], test::block7_hash); BOOST_CHECK_EQUAL(roots[8], test::block8_hash); - BOOST_CHECK_EQUAL(query.get_merkle_root(8), root08); + BOOST_CHECK_EQUAL(query.get_merkle_root(8), test::root08); hashes proof{}; hash_digest root{}; BOOST_CHECK(!query.get_merkle_root_and_proof(root, proof, 5, 8)); - BOOST_CHECK_EQUAL(root, root08); + BOOST_CHECK_EQUAL(root, test::root08); BOOST_CHECK_EQUAL(proof.size(), 4u); BOOST_CHECK_EQUAL(proof[0], test::block4_hash); - BOOST_CHECK_EQUAL(proof[1], root67); - BOOST_CHECK_EQUAL(proof[2], root03); - BOOST_CHECK_EQUAL(proof[3], root88); + BOOST_CHECK_EQUAL(proof[1], test::root67); + BOOST_CHECK_EQUAL(proof[2], test::root03); + BOOST_CHECK_EQUAL(proof[3], test::root88); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_depth_1__success) @@ -704,23 +688,23 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_ hashes roots{}; BOOST_CHECK_EQUAL(query.get_merkle_subroots(roots, 8), error::success); BOOST_CHECK_EQUAL(roots.size(), 5u); - BOOST_CHECK_EQUAL(roots[0], root01); - BOOST_CHECK_EQUAL(roots[1], root23); - BOOST_CHECK_EQUAL(roots[2], root45); - BOOST_CHECK_EQUAL(roots[3], root67); - BOOST_CHECK_EQUAL(roots[4], root82); + BOOST_CHECK_EQUAL(roots[0], test::root01); + BOOST_CHECK_EQUAL(roots[1], test::root23); + BOOST_CHECK_EQUAL(roots[2], test::root45); + BOOST_CHECK_EQUAL(roots[3], test::root67); + BOOST_CHECK_EQUAL(roots[4], test::root82); - BOOST_CHECK_EQUAL(query.get_merkle_root(8), root08); + BOOST_CHECK_EQUAL(query.get_merkle_root(8), test::root08); hashes proof{}; hash_digest root{}; BOOST_CHECK(!query.get_merkle_root_and_proof(root, proof, 5, 8)); - BOOST_CHECK_EQUAL(root, root08); + BOOST_CHECK_EQUAL(root, test::root08); BOOST_CHECK_EQUAL(proof.size(), 4u); BOOST_CHECK_EQUAL(proof[0], test::block4_hash); - BOOST_CHECK_EQUAL(proof[1], root67); - BOOST_CHECK_EQUAL(proof[2], root03); - BOOST_CHECK_EQUAL(proof[3], root88); + BOOST_CHECK_EQUAL(proof[1], test::root67); + BOOST_CHECK_EQUAL(proof[2], test::root03); + BOOST_CHECK_EQUAL(proof[3], test::root88); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_depth_2__success) @@ -736,21 +720,21 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_ hashes roots{}; BOOST_CHECK_EQUAL(query.get_merkle_subroots(roots, 8), error::success); BOOST_CHECK_EQUAL(roots.size(), 3u); - BOOST_CHECK_EQUAL(roots[0], root03); - BOOST_CHECK_EQUAL(roots[1], root47); - BOOST_CHECK_EQUAL(roots[2], root84); + BOOST_CHECK_EQUAL(roots[0], test::root03); + BOOST_CHECK_EQUAL(roots[1], test::root47); + BOOST_CHECK_EQUAL(roots[2], test::root84); - BOOST_CHECK_EQUAL(query.get_merkle_root(8), root08); + BOOST_CHECK_EQUAL(query.get_merkle_root(8), test::root08); hashes proof{}; hash_digest root{}; BOOST_CHECK(!query.get_merkle_root_and_proof(root, proof, 5, 8)); - BOOST_CHECK_EQUAL(root, root08); + BOOST_CHECK_EQUAL(root, test::root08); BOOST_CHECK_EQUAL(proof.size(), 4u); BOOST_CHECK_EQUAL(proof[0], test::block4_hash); - BOOST_CHECK_EQUAL(proof[1], root67); - BOOST_CHECK_EQUAL(proof[2], root03); - BOOST_CHECK_EQUAL(proof[3], root88); + BOOST_CHECK_EQUAL(proof[1], test::root67); + BOOST_CHECK_EQUAL(proof[2], test::root03); + BOOST_CHECK_EQUAL(proof[3], test::root88); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_depth_3__success) @@ -766,20 +750,20 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_ hashes roots{}; BOOST_CHECK_EQUAL(query.get_merkle_subroots(roots, 8), error::success); BOOST_CHECK_EQUAL(roots.size(), 2u); - BOOST_CHECK_EQUAL(roots[0], root07); - BOOST_CHECK_EQUAL(roots[1], root88); + BOOST_CHECK_EQUAL(roots[0], test::root07); + BOOST_CHECK_EQUAL(roots[1], test::root88); - BOOST_CHECK_EQUAL(query.get_merkle_root(8), root08); + BOOST_CHECK_EQUAL(query.get_merkle_root(8), test::root08); hashes proof{}; hash_digest root{}; BOOST_CHECK(!query.get_merkle_root_and_proof(root, proof, 5, 8)); - BOOST_CHECK_EQUAL(root, root08); + BOOST_CHECK_EQUAL(root, test::root08); BOOST_CHECK_EQUAL(proof.size(), 4u); BOOST_CHECK_EQUAL(proof[0], test::block4_hash); - BOOST_CHECK_EQUAL(proof[1], root67); - BOOST_CHECK_EQUAL(proof[2], root03); - BOOST_CHECK_EQUAL(proof[3], root88); + BOOST_CHECK_EQUAL(proof[1], test::root67); + BOOST_CHECK_EQUAL(proof[2], test::root03); + BOOST_CHECK_EQUAL(proof[3], test::root88); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_depth_4__success) @@ -795,19 +779,19 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_ hashes roots{}; BOOST_CHECK_EQUAL(query.get_merkle_subroots(roots, 8), error::success); BOOST_CHECK_EQUAL(roots.size(), 1u); - BOOST_CHECK_EQUAL(roots[0], root08); + BOOST_CHECK_EQUAL(roots[0], test::root08); - BOOST_CHECK_EQUAL(query.get_merkle_root(8), root08); + BOOST_CHECK_EQUAL(query.get_merkle_root(8), test::root08); hashes proof{}; hash_digest root{}; BOOST_CHECK(!query.get_merkle_root_and_proof(root, proof, 5, 8)); - BOOST_CHECK_EQUAL(root, root08); + BOOST_CHECK_EQUAL(root, test::root08); BOOST_CHECK_EQUAL(proof.size(), 4u); // <<<<< FAIL (proof.size() == 5) BOOST_CHECK_EQUAL(proof[0], test::block4_hash); - BOOST_CHECK_EQUAL(proof[1], root67); - BOOST_CHECK_EQUAL(proof[2], root03); - BOOST_CHECK_EQUAL(proof[3], root88); + BOOST_CHECK_EQUAL(proof[1], test::root67); + BOOST_CHECK_EQUAL(proof[2], test::root03); + BOOST_CHECK_EQUAL(proof[3], test::root88); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_depth_11__success) @@ -823,19 +807,19 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_ hashes roots{}; BOOST_CHECK_EQUAL(query.get_merkle_subroots(roots, 8), error::success); BOOST_CHECK_EQUAL(roots.size(), 1u); - BOOST_CHECK_EQUAL(roots[0], root08); + BOOST_CHECK_EQUAL(roots[0], test::root08); - BOOST_CHECK_EQUAL(query.get_merkle_root(8), root08); + BOOST_CHECK_EQUAL(query.get_merkle_root(8), test::root08); hashes proof{}; hash_digest root{}; BOOST_CHECK(!query.get_merkle_root_and_proof(root, proof, 5, 8)); - BOOST_CHECK_EQUAL(root, root08); + BOOST_CHECK_EQUAL(root, test::root08); BOOST_CHECK_EQUAL(proof.size(), 4u); // <<<<< FAIL (proof.size() == 11) BOOST_CHECK_EQUAL(proof[0], test::block4_hash); - BOOST_CHECK_EQUAL(proof[1], root67); - BOOST_CHECK_EQUAL(proof[2], root03); - BOOST_CHECK_EQUAL(proof[3], root88); + BOOST_CHECK_EQUAL(proof[1], test::root67); + BOOST_CHECK_EQUAL(proof[2], test::root03); + BOOST_CHECK_EQUAL(proof[3], test::root88); } // This tests a potentially sparse path (avoids compression). @@ -862,17 +846,17 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__target_8_depth_0__ BOOST_CHECK_EQUAL(roots[7], test::block7_hash); BOOST_CHECK_EQUAL(roots[8], test::block8_hash); - BOOST_CHECK_EQUAL(query.get_merkle_root(8), root08); + BOOST_CHECK_EQUAL(query.get_merkle_root(8), test::root08); hashes proof{}; hash_digest root{}; BOOST_CHECK(!query.get_merkle_root_and_proof(root, proof, 8, 8)); - BOOST_CHECK_EQUAL(root, root08); + BOOST_CHECK_EQUAL(root, test::root08); BOOST_CHECK_EQUAL(proof.size(), 4u); BOOST_CHECK_EQUAL(proof[0], test::block8_hash); - BOOST_CHECK_EQUAL(proof[1], root82); - BOOST_CHECK_EQUAL(proof[2], root84); - BOOST_CHECK_EQUAL(proof[3], root07); + BOOST_CHECK_EQUAL(proof[1], test::root82); + BOOST_CHECK_EQUAL(proof[2], test::root84); + BOOST_CHECK_EQUAL(proof[3], test::root07); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__partial_interval_with_elevation_depth__success) @@ -885,14 +869,14 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__partial_interval_w BOOST_CHECK_EQUAL(store.create(events_handler), error::success); BOOST_CHECK(setup_eight_block_store(query)); - constexpr auto root42 = system::sha256::double_hash(test::block4_hash, test::block4_hash); - constexpr auto root44 = system::sha256::double_hash(root42, root42); - constexpr auto expected_root = system::sha256::double_hash(root03, root44); + const auto root42 = system::sha256::double_hash(test::block4_hash, test::block4_hash); + const auto root44 = system::sha256::double_hash(root42, root42); + const auto expected_root = system::sha256::double_hash(test::root03, root44); hashes roots{}; BOOST_CHECK_EQUAL(query.get_merkle_subroots(roots, 4), error::success); BOOST_CHECK_EQUAL(roots.size(), 2u); - BOOST_CHECK_EQUAL(roots[0], root03); + BOOST_CHECK_EQUAL(roots[0], test::root03); BOOST_CHECK_EQUAL(roots[1], root44); BOOST_CHECK_EQUAL(query.get_merkle_root(4), expected_root); @@ -906,7 +890,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__partial_interval_w BOOST_CHECK_EQUAL(proof.size(), 3u); BOOST_CHECK_EQUAL(proof[0], test::block4_hash); BOOST_CHECK_EQUAL(proof[1], root42); - BOOST_CHECK_EQUAL(proof[2], root03); + BOOST_CHECK_EQUAL(proof[2], test::root03); } BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__target_greater_than_waypoint__error_invalid_argument) diff --git a/test/query/optional.cpp b/test/query/optional.cpp index b72c4612..b716a8a3 100644 --- a/test/query/optional.cpp +++ b/test/query/optional.cpp @@ -22,10 +22,13 @@ BOOST_FIXTURE_TEST_SUITE(query_optional_tests, test::directory_setup_fixture) -// nop event handler. -const auto events_handler = [](auto, auto) {}; +system::hash_digest genesis_address() +{ + static const auto address = test::genesis.transactions_ptr()->front()-> + outputs_ptr()->front()->script().hash(); -const auto genesis_address = test::genesis.transactions_ptr()->front()->outputs_ptr()->front()->script().hash(); + return address; +} // to_address_outputs @@ -35,12 +38,12 @@ BOOST_AUTO_TEST_CASE(query_optional__to_address_outputs__genesis__expected) settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); output_links out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.to_address_outputs(cancel, out, genesis_address)); + BOOST_REQUIRE(!query.to_address_outputs(cancel, out, genesis_address())); BOOST_REQUIRE_EQUAL(out.size(), 1u); BOOST_REQUIRE_EQUAL(out.front(), query.to_output(0, 0)); } @@ -53,12 +56,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_address_outputs__turbo_genesis__expecte settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); outpoints out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_address_outputs(cancel, out, genesis_address, true)); + BOOST_REQUIRE(!query.get_address_outputs(cancel, out, genesis_address(), true)); BOOST_REQUIRE_EQUAL(out.size(), 1u); ////BOOST_REQUIRE_EQUAL(out.front(), query.to_output(0, 0)); } @@ -69,12 +72,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_address_outputs__genesis__expected) settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); outpoints out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_address_outputs(cancel, out, genesis_address)); + BOOST_REQUIRE(!query.get_address_outputs(cancel, out, genesis_address())); BOOST_REQUIRE_EQUAL(out.size(), 1u); ////BOOST_REQUIRE_EQUAL(out.front(), query.to_output(0, 0)); } @@ -85,12 +88,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_address_outputs__cancel__canceled_false settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); outpoints out{}; std::atomic_bool cancel{ true }; - BOOST_REQUIRE_EQUAL(query.get_address_outputs(cancel, out, genesis_address), error::canceled); + BOOST_REQUIRE_EQUAL(query.get_address_outputs(cancel, out, genesis_address()), error::canceled); BOOST_REQUIRE(out.empty()); } @@ -102,12 +105,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_confirmed_unspent_outputs__turbo_genesi settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); outpoints out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_confirmed_unspent_outputs(cancel, out, genesis_address, true)); + BOOST_REQUIRE(!query.get_confirmed_unspent_outputs(cancel, out, genesis_address(), true)); BOOST_REQUIRE_EQUAL(out.size(), 1u); ////BOOST_REQUIRE_EQUAL(out.front(), 0); } @@ -118,12 +121,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_confirmed_unspent_outputs__genesis__exp settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); outpoints out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_confirmed_unspent_outputs(cancel, out, genesis_address)); + BOOST_REQUIRE(!query.get_confirmed_unspent_outputs(cancel, out, genesis_address())); BOOST_REQUIRE_EQUAL(out.size(), 1u); ////BOOST_REQUIRE_EQUAL(out.front(), 0); } @@ -136,12 +139,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_minimum_unspent_outputs__turbo_above__e settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); outpoints out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address, 5000000001, true)); + BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address(), 5000000001, true)); BOOST_REQUIRE(out.empty()); } @@ -151,12 +154,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_minimum_unspent_outputs__above__exclude settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); outpoints out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address, 5000000001)); + BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address(), 5000000001)); BOOST_REQUIRE(out.empty()); } @@ -166,12 +169,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_minimum_unspent_outputs__at__included) settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); outpoints out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address, 5000000000)); + BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address(), 5000000000)); BOOST_REQUIRE_EQUAL(out.size(), 1u); ////BOOST_REQUIRE_EQUAL(out.front(), 0); } @@ -182,15 +185,15 @@ BOOST_AUTO_TEST_CASE(query_optional__get_minimum_unspent_outputs__below__include settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); outpoints out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address, 0)); + BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address(), 0)); BOOST_REQUIRE_EQUAL(out.size(), 1u); ////BOOST_REQUIRE_EQUAL(out.front(), 0); - BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address, 4999999999)); + BOOST_REQUIRE(!query.get_minimum_unspent_outputs(cancel, out, genesis_address(), 4999999999)); BOOST_REQUIRE_EQUAL(out.size(), 1u); ////BOOST_REQUIRE_EQUAL(out.front(), 0); } @@ -203,12 +206,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_confirmed_balance__turbo_genesis__expec settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); uint64_t out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_confirmed_balance(cancel, out, genesis_address, true)); + BOOST_REQUIRE(!query.get_confirmed_balance(cancel, out, genesis_address(), true)); BOOST_REQUIRE_EQUAL(out, 5000000000u); } @@ -218,12 +221,12 @@ BOOST_AUTO_TEST_CASE(query_optional__get_confirmed_balance__genesis__expected) settings.path = TEST_DIRECTORY; test::chunk_store store{ settings }; test::query_accessor query{ store }; - BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); + BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); BOOST_REQUIRE(query.initialize(test::genesis)); uint64_t out{}; std::atomic_bool cancel{}; - BOOST_REQUIRE(!query.get_confirmed_balance(cancel, out, genesis_address)); + BOOST_REQUIRE(!query.get_confirmed_balance(cancel, out, genesis_address())); BOOST_REQUIRE_EQUAL(out, 5000000000u); } @@ -238,7 +241,7 @@ BOOST_AUTO_TEST_CASE(query_optional__get_confirmed_balance__genesis__expected) //// settings.path = TEST_DIRECTORY; //// test::chunk_store store{ settings }; //// test::query_accessor query{ store }; -//// BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success); +//// BOOST_REQUIRE_EQUAL(store.create(test::events_handler), error::success); //// BOOST_REQUIRE(query.initialize(test::genesis)); //// BOOST_REQUIRE(query.set(test::block1a, context{}, false, false)); //// BOOST_REQUIRE(query.set_filter(0, filter_head0, filter0)); diff --git a/test/query/wire.cpp b/test/query/wire.cpp new file mode 100644 index 00000000..c105454d --- /dev/null +++ b/test/query/wire.cpp @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2011-2026 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/blocks.hpp" +#include "../mocks/chunk_store.hpp" + +BOOST_FIXTURE_TEST_SUITE(query_wire_tests, test::directory_setup_fixture) + +// get_wire_header + +BOOST_AUTO_TEST_CASE(query_wire__get_wire_header__genesis_and_not__expected) +{ + using namespace system; + database::settings settings{}; + settings.path = TEST_DIRECTORY; + test::store_t store{ settings }; + test::query_t query{ store }; + BOOST_CHECK(!store.create(test::events_handler)); + BOOST_CHECK(test::setup_three_block_store(query)); + BOOST_CHECK_EQUAL(query.get_wire_header(0), test::genesis.header().to_data()); + BOOST_CHECK_EQUAL(query.get_wire_header(1), test::block1.header().to_data()); + BOOST_CHECK_EQUAL(query.get_wire_header(2), test::block2.header().to_data()); + BOOST_CHECK(!store.close(test::events_handler)); +} + +// get_wire_tx + +BOOST_AUTO_TEST_CASE(query_wire__get_wire_tx__genesis_and_not__expected) +{ + using namespace system; + database::settings settings{}; + settings.path = TEST_DIRECTORY; + test::store_t store{ settings }; + test::query_t query{ store }; + BOOST_CHECK(!store.create(test::events_handler)); + BOOST_CHECK(test::setup_three_block_store(query)); + BOOST_CHECK_EQUAL(query.get_wire_tx(0, true), test::genesis.transactions_ptr()->front()->to_data(true)); + BOOST_CHECK_EQUAL(query.get_wire_tx(1, true), test::block1.transactions_ptr()->front()->to_data(true)); + BOOST_CHECK_EQUAL(query.get_wire_tx(2, true), test::block2.transactions_ptr()->front()->to_data(true)); + BOOST_CHECK(!store.close(test::events_handler)); +} + +BOOST_AUTO_TEST_CASE(query_wire__get_wire_tx__witness_true__expected) +{ + using namespace system; + database::settings settings{}; + settings.path = TEST_DIRECTORY; + test::store_t store{ settings }; + test::query_t query{ store }; + BOOST_CHECK(!store.create(test::events_handler)); + BOOST_CHECK(test::setup_three_block_witness_store(query)); + BOOST_CHECK_EQUAL(query.get_wire_tx(0, true), test::genesis.transactions_ptr()->at(0)->to_data(true)); + BOOST_CHECK_EQUAL(query.get_wire_tx(1, true), test::block1a.transactions_ptr()->at(0)->to_data(true)); + BOOST_CHECK_EQUAL(query.get_wire_tx(2, true), test::block2a.transactions_ptr()->at(0)->to_data(true)); + BOOST_CHECK_EQUAL(query.get_wire_tx(3, true), test::block2a.transactions_ptr()->at(1)->to_data(true)); + BOOST_CHECK(!store.close(test::events_handler)); +} + +BOOST_AUTO_TEST_CASE(query_wire__get_wire_tx__witness_false__expected) +{ + using namespace system; + database::settings settings{}; + settings.path = TEST_DIRECTORY; + test::store_t store{ settings }; + test::query_t query{ store }; + BOOST_CHECK(!store.create(test::events_handler)); + BOOST_CHECK(test::setup_three_block_witness_store(query)); + BOOST_CHECK_EQUAL(query.get_wire_tx(0, false), test::genesis.transactions_ptr()->at(0)->to_data(false)); + BOOST_CHECK_EQUAL(query.get_wire_tx(1, false), test::block1a.transactions_ptr()->at(0)->to_data(false)); + BOOST_CHECK_EQUAL(query.get_wire_tx(2, false), test::block2a.transactions_ptr()->at(0)->to_data(false)); + BOOST_CHECK_EQUAL(query.get_wire_tx(3, false), test::block2a.transactions_ptr()->at(1)->to_data(false)); + BOOST_CHECK(!store.close(test::events_handler)); +} + +// get_wire_block + +BOOST_AUTO_TEST_CASE(query_wire__get_wire_block__genesis_and_not__expected) +{ + using namespace system; + database::settings settings{}; + settings.path = TEST_DIRECTORY; + test::store_t store{ settings }; + test::query_t query{ store }; + BOOST_CHECK(!store.create(test::events_handler)); + BOOST_CHECK(test::setup_three_block_store(query)); + BOOST_CHECK_EQUAL(query.get_wire_block(0, true), test::genesis.to_data(true)); + BOOST_CHECK_EQUAL(query.get_wire_block(1, true), test::block1.to_data(true)); + BOOST_CHECK(!store.close(test::events_handler)); +} + +BOOST_AUTO_TEST_CASE(query_wire__get_wire_block__witness_true__expected) +{ + using namespace system; + database::settings settings{}; + settings.path = TEST_DIRECTORY; + test::store_t store{ settings }; + test::query_t query{ store }; + BOOST_CHECK(!store.create(test::events_handler)); + BOOST_CHECK(test::setup_three_block_witness_store(query)); + BOOST_CHECK_EQUAL(query.get_wire_block(0, true), test::genesis.to_data(true)); + BOOST_CHECK_EQUAL(query.get_wire_block(1, true), test::block1a.to_data(true)); + BOOST_CHECK(!store.close(test::events_handler)); +} + +BOOST_AUTO_TEST_CASE(query_wire__get_wire_block__witness_false__expected) +{ + using namespace system; + database::settings settings{}; + settings.path = TEST_DIRECTORY; + test::store_t store{ settings }; + test::query_t query{ store }; + BOOST_CHECK(!store.create(test::events_handler)); + BOOST_CHECK(test::setup_three_block_witness_store(query)); + BOOST_CHECK_EQUAL(query.get_wire_block(0, false), test::genesis.to_data(false)); + BOOST_CHECK_EQUAL(query.get_wire_block(1, false), test::block1a.to_data(false)); + BOOST_CHECK(!store.close(test::events_handler)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/tables/caches/prevout.cpp b/test/tables/caches/prevout.cpp index 00c77c42..f8a2f35a 100644 --- a/test/tables/caches/prevout.cpp +++ b/test/tables/caches/prevout.cpp @@ -30,9 +30,8 @@ const std::vector conflicts2{ 0xbaadf00d, 0x01020304 }; BOOST_AUTO_TEST_CASE(prevout__put__at1__expected) { - const auto block = test::get_bogus_block(); - const table::prevout::slab_put_ref slab1{ {}, conflicts1, block }; - const table::prevout::slab_put_ref slab2{ {}, conflicts2, block }; + const table::prevout::slab_put_ref slab1{ {}, conflicts1, test::bogus_block }; + const table::prevout::slab_put_ref slab2{ {}, conflicts2, test::bogus_block }; test::chunk_storage head_store{}; test::chunk_storage body_store{}; table::prevout instance{ head_store, body_store, 5 }; @@ -53,9 +52,8 @@ BOOST_AUTO_TEST_CASE(prevout__put__at1__expected) BOOST_AUTO_TEST_CASE(prevout__put__at2__expected) { - const auto block = test::get_bogus_block(); - const table::prevout::slab_put_ref slab1{ {}, conflicts1, block }; - const table::prevout::slab_put_ref slab2{ {}, conflicts2, block }; + const table::prevout::slab_put_ref slab1{ {}, conflicts1, test::bogus_block }; + const table::prevout::slab_put_ref slab2{ {}, conflicts2, test::bogus_block }; table::prevout::slab_get element{}; test::chunk_storage head_store{}; test::chunk_storage body_store{}; @@ -81,9 +79,8 @@ BOOST_AUTO_TEST_CASE(prevout__put__at2__expected) BOOST_AUTO_TEST_CASE(prevout__put__exists__expected) { - const auto block = test::get_bogus_block(); - const table::prevout::slab_put_ref slab1{ {}, conflicts1, block }; - const table::prevout::slab_put_ref slab2{ {}, conflicts2, block }; + const table::prevout::slab_put_ref slab1{ {}, conflicts1, test::bogus_block }; + const table::prevout::slab_put_ref slab2{ {}, conflicts2, test::bogus_block }; test::chunk_storage head_store{}; test::chunk_storage body_store{}; table::prevout instance{ head_store, body_store, 5 }; @@ -104,9 +101,8 @@ BOOST_AUTO_TEST_CASE(prevout__put__exists__expected) BOOST_AUTO_TEST_CASE(prevout__put__get__expected) { - const auto block = test::get_bogus_block(); - const table::prevout::slab_put_ref slab1{ {}, conflicts1, block }; - const table::prevout::slab_put_ref slab2{ {}, conflicts2, block }; + const table::prevout::slab_put_ref slab1{ {}, conflicts1, test::bogus_block }; + const table::prevout::slab_put_ref slab2{ {}, conflicts2, test::bogus_block }; table::prevout::slab_get element{}; test::chunk_storage head_store{}; test::chunk_storage body_store{};