diff --git a/include/bitcoin/database/impl/primitives/hashhead.ipp b/include/bitcoin/database/impl/primitives/hashhead.ipp index 61afb972..ae46e71c 100644 --- a/include/bitcoin/database/impl/primitives/hashhead.ipp +++ b/include/bitcoin/database/impl/primitives/hashhead.ipp @@ -273,7 +273,7 @@ INLINE constexpr CLASS::cell CLASS::next_cell(bool& collision, cell previous, using namespace system; const auto prev = to_filter(previous); const auto next = filter_t::screen(prev, entropy); - collision = filter_t::is_collision(prev, next); + collision = false; //// filter_t::is_collision(prev, next); return bit_or(shift_left(next, link_bits), current); } } diff --git a/include/bitcoin/database/impl/query/archive_write.ipp b/include/bitcoin/database/impl/query/archive_write.ipp index fbac5d04..21d527fc 100644 --- a/include/bitcoin/database/impl/query/archive_write.ipp +++ b/include/bitcoin/database/impl/query/archive_write.ipp @@ -192,6 +192,7 @@ code CLASS::set_code(const tx_link& tx_fk, const transaction& tx) NOEXCEPT if (ad_fk.is_terminal()) return error::tx_address_allocate; + constexpr auto value_parent_diff = sizeof(uint64_t) - tx_link::size; const auto ptr = store_.address.get_memory(); for (const auto& output: *ous) { @@ -199,7 +200,11 @@ code CLASS::set_code(const tx_link& tx_fk, const transaction& tx) NOEXCEPT table::address::record{ {}, out_fk })) return error::tx_address_put; - out_fk.value += output->serialized_size(); + // See outs::put_ref. + // Calculate next corresponding output fk from serialized size. + // (variable_size(value) + (value + script)) - (value - parent) + out_fk.value += (variable_size(output->value()) + + output->serialized_size() - value_parent_diff); } } diff --git a/include/bitcoin/database/impl/query/objects.ipp b/include/bitcoin/database/impl/query/objects.ipp index 2aeaca17..6448f23f 100644 --- a/include/bitcoin/database/impl/query/objects.ipp +++ b/include/bitcoin/database/impl/query/objects.ipp @@ -304,6 +304,41 @@ typename CLASS::output::cptr CLASS::get_output( return out.output; } +TEMPLATE +typename CLASS::point CLASS::get_spent(const output_link& link) const NOEXCEPT +{ + ////const auto tx = to_output_tx(link); + ////const auto hash = get_tx_key(tx); + ////const auto index = to_output_index(tx, link); + ////if (tx.is_terminal()) + ////{ + //// return { {}, 42 }; + ////} + ////else if (hash == system::null_hash && index == point::null_index) + ////{ + //// return { {}, 96 }; + ////} + ////else if (hash == system::null_hash && index != point::null_index) + ////{ + //// return { {}, index }; + ////} + ////else if (hash != system::null_hash && index == point::null_index) + ////{ + //// return { hash, 69 }; + ////} + ////else // if (hash != system::null_hash && index != point::null_index) + ////{ + //// return { hash, index }; + ////} + + if (const auto tx = to_output_tx(link); !tx.is_terminal()) + if (const auto index = to_output_index(tx, link); + index != point::null_index) + return { get_tx_key(tx), index }; + + return {}; +} + TEMPLATE typename CLASS::point CLASS::get_spender(const point_link& link) const NOEXCEPT { diff --git a/include/bitcoin/database/impl/query/validate.ipp b/include/bitcoin/database/impl/query/validate.ipp index d2b41f78..30f93720 100644 --- a/include/bitcoin/database/impl/query/validate.ipp +++ b/include/bitcoin/database/impl/query/validate.ipp @@ -124,17 +124,23 @@ code CLASS::get_block_state(const header_link& link) const NOEXCEPT } TEMPLATE -code CLASS::get_block_state(uint64_t& fees, - const header_link& link) const NOEXCEPT +uint64_t CLASS::get_block_fees(const header_link& link) const NOEXCEPT { - table::validated_bk::slab valid{}; - if (!store_.validated_bk.at(to_validated_bk(link), valid)) - return is_associated(link) ? error::unvalidated : error::unassociated; + // TODO: optimize. + const auto block = get_block(link, false); + return block && populate_without_metadata(*block) ? block->fees() : + max_uint64; +} - // TODO: Fees only valid if block_valid is the current state (iterate for valid). - fees = valid.fees; +TEMPLATE +uint64_t CLASS::get_tx_fee(const tx_link& link) const NOEXCEPT +{ + // TODO: optimize. + const auto tx = get_transaction(link, false); + if (is_coinbase(link)) + return {}; - return to_block_code(valid.code); + return tx && populate_without_metadata(*tx) ? tx->fee() : max_uint64; } TEMPLATE diff --git a/include/bitcoin/database/query.hpp b/include/bitcoin/database/query.hpp index 96bfd1bd..397fd57f 100644 --- a/include/bitcoin/database/query.hpp +++ b/include/bitcoin/database/query.hpp @@ -394,10 +394,11 @@ class query input::cptr get_input(const tx_link& link, uint32_t index, bool witness) const NOEXCEPT; + point get_spent(const output_link& link) const NOEXCEPT; + point get_spender(const point_link& link) const NOEXCEPT; script::cptr get_output_script(const output_link& link) const NOEXCEPT; output::cptr get_output(const output_link& link) const NOEXCEPT; output::cptr get_output(const tx_link& link, uint32_t index) const NOEXCEPT; - point get_spender(const point_link& link) const NOEXCEPT; inputs_ptr get_spenders(const output_link& link, bool witness) const NOEXCEPT; @@ -473,9 +474,10 @@ class query /// ----------------------------------------------------------------------- /// States. - code get_header_state(const header_link& link) const NOEXCEPT; + uint64_t get_tx_fee(const tx_link& link) const NOEXCEPT; + uint64_t get_block_fees(const header_link& link) const NOEXCEPT; code get_block_state(const header_link& link) const NOEXCEPT; - code get_block_state(uint64_t& fees, const header_link& link) const NOEXCEPT; + code get_header_state(const header_link& link) const NOEXCEPT; code get_tx_state(const tx_link& link, const context& ctx) const NOEXCEPT; code get_tx_state(uint64_t& fee, size_t& sigops, const tx_link& link, const context& ctx) const NOEXCEPT; diff --git a/include/bitcoin/database/tables/archives/outs.hpp b/include/bitcoin/database/tables/archives/outs.hpp index 71bcac5f..b7a9063e 100644 --- a/include/bitcoin/database/tables/archives/outs.hpp +++ b/include/bitcoin/database/tables/archives/outs.hpp @@ -106,8 +106,7 @@ struct outs { using namespace system; static_assert(tx::size <= sizeof(uint64_t)); - constexpr auto value_parent_difference = sizeof(uint64_t) - - tx::size; + constexpr auto value_parent_diff = sizeof(uint64_t) - tx::size; auto out_fk = output_fk; const auto& outs = *tx_.outputs_ptr(); @@ -118,7 +117,7 @@ struct outs // Calculate next corresponding output fk from serialized size. // (variable_size(value) + (value + script)) - (value - parent) out_fk += (variable_size(out->value()) + out->serialized_size() - - value_parent_difference); + value_parent_diff); }); BC_ASSERT(!sink || sink.get_write_position() == count() * minrow); diff --git a/test/query/validate.cpp b/test/query/validate.cpp index de68e838..aedaa71f 100644 --- a/test/query/validate.cpp +++ b/test/query/validate.cpp @@ -167,7 +167,6 @@ BOOST_AUTO_TEST_CASE(query_validate__get_block_state__invalid_link__unassociated uint64_t fees{}; BOOST_REQUIRE_EQUAL(query.get_header_state(1), error::unvalidated); BOOST_REQUIRE_EQUAL(query.get_block_state(1), error::unassociated); - BOOST_REQUIRE_EQUAL(query.get_block_state(fees, 1), error::unassociated); BOOST_REQUIRE_EQUAL(fees, 0u); } @@ -185,7 +184,6 @@ BOOST_AUTO_TEST_CASE(query_validate__get_block_state__unassociated_link__unassoc uint64_t fees{}; BOOST_REQUIRE_EQUAL(query.get_header_state(1), error::unvalidated); BOOST_REQUIRE_EQUAL(query.get_block_state(1), error::unassociated); - BOOST_REQUIRE_EQUAL(query.get_block_state(fees, 1), error::unassociated); BOOST_REQUIRE_EQUAL(fees, 0u); } @@ -202,7 +200,6 @@ BOOST_AUTO_TEST_CASE(query_validate__get_block_state__unvalidated_link__unvalida uint64_t fees{}; BOOST_REQUIRE_EQUAL(query.get_header_state(1), error::unvalidated); BOOST_REQUIRE_EQUAL(query.get_block_state(1), error::unvalidated); - BOOST_REQUIRE_EQUAL(query.get_block_state(fees, 1), error::unvalidated); BOOST_REQUIRE_EQUAL(fees, 0u); } @@ -219,13 +216,11 @@ BOOST_AUTO_TEST_CASE(query_validate__get_block_state__confirmable__block_confirm uint64_t fees{}; BOOST_REQUIRE_EQUAL(query.get_header_state(0), error::unvalidated); BOOST_REQUIRE_EQUAL(query.get_block_state(0), error::unvalidated); - BOOST_REQUIRE_EQUAL(query.get_block_state(fees, 0), error::unvalidated); BOOST_REQUIRE_EQUAL(fees, 0u); BOOST_REQUIRE(query.set_block_confirmable(1)); BOOST_REQUIRE_EQUAL(query.get_header_state(1), error::block_confirmable); BOOST_REQUIRE_EQUAL(query.get_block_state(1), error::block_confirmable); - BOOST_REQUIRE_EQUAL(query.get_block_state(fees, 1), error::block_confirmable); BOOST_REQUIRE_EQUAL(fees, 0u); } @@ -239,12 +234,9 @@ BOOST_AUTO_TEST_CASE(query_validate__get_block_state__valid__block_valid) BOOST_REQUIRE(query.initialize(test::genesis)); BOOST_REQUIRE(query.set(test::block1, context{}, false, false)); - uint64_t fees{}; BOOST_REQUIRE(query.set_block_valid(1, 42)); BOOST_REQUIRE_EQUAL(query.get_header_state(1), error::block_valid); BOOST_REQUIRE_EQUAL(query.get_block_state(1), error::block_valid); - BOOST_REQUIRE_EQUAL(query.get_block_state(fees, 1), error::block_valid); - BOOST_REQUIRE_EQUAL(fees, 42u); } BOOST_AUTO_TEST_CASE(query_validate__get_block_state__unconfirmable__block_unconfirmable) @@ -257,12 +249,9 @@ BOOST_AUTO_TEST_CASE(query_validate__get_block_state__unconfirmable__block_uncon BOOST_REQUIRE(query.initialize(test::genesis)); BOOST_REQUIRE(query.set(test::block1, context{}, false, false)); - uint64_t fees{}; BOOST_REQUIRE(query.set_block_unconfirmable(1)); BOOST_REQUIRE_EQUAL(query.get_header_state(1), error::block_unconfirmable); BOOST_REQUIRE_EQUAL(query.get_block_state(1), error::block_unconfirmable); - BOOST_REQUIRE_EQUAL(query.get_block_state(fees, 1), error::block_unconfirmable); - BOOST_REQUIRE_EQUAL(fees, 0u); } BOOST_AUTO_TEST_CASE(query_validate__get_tx_state__invalid_link__unvalidated)