Skip to content

Commit 27a4841

Browse files
authored
Merge pull request #693 from evoskuil/master
Change get_spent() to return outpoint (with spend value).
2 parents f3266a9 + 0f3d6ea commit 27a4841

File tree

5 files changed

+110
-60
lines changed

5 files changed

+110
-60
lines changed

include/bitcoin/database/impl/query/objects.ipp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -305,25 +305,32 @@ typename CLASS::output::cptr CLASS::get_output(
305305
}
306306

307307
TEMPLATE
308-
typename CLASS::point CLASS::get_spent(const output_link& link) const NOEXCEPT
308+
typename CLASS::outpoint CLASS::get_spent(
309+
const output_link& link) const NOEXCEPT
309310
{
310-
if (const auto tx = to_output_tx(link); !tx.is_terminal())
311-
if (const auto index = to_output_index(tx, link);
312-
index != point::null_index)
313-
return { get_tx_key(tx), index };
311+
table::output::get_parent_value out{};
312+
if (!store_.output.get(link, out))
313+
return {};
314+
315+
const auto index = to_output_index(out.parent_fk, link);
316+
if (index == point::null_index)
317+
return {};
314318

315-
return {};
319+
return { { get_tx_key(out.parent_fk), index }, out.value };
316320
}
317321

318322
TEMPLATE
319323
typename CLASS::point CLASS::get_spender(const point_link& link) const NOEXCEPT
320324
{
321-
if (const auto tx = to_spending_tx(link); !tx.is_terminal())
322-
if (const auto index = to_input_index(tx, link);
323-
index != point::null_index)
324-
return { get_tx_key(tx), index };
325+
const auto tx = to_spending_tx(link);
326+
if (tx.is_terminal())
327+
return {};
328+
329+
const auto index = to_input_index(tx, link);
330+
if (index == point::null_index)
331+
return {};
325332

326-
return {};
333+
return { get_tx_key(tx), index };
327334
}
328335

329336
TEMPLATE

include/bitcoin/database/impl/query/optional.ipp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifndef LIBBITCOIN_DATABASE_QUERY_OPTIONAL_IPP
2020
#define LIBBITCOIN_DATABASE_QUERY_OPTIONAL_IPP
2121

22+
#include <atomic>
2223
#include <algorithm>
2324
#include <ranges>
2425
#include <utility>
@@ -32,19 +33,19 @@ namespace database {
3233
// ----------------------------------------------------------------------------
3334
// TODO: use point keys (for multimap compression).
3435

35-
// TODO: test more.
3636
TEMPLATE
37-
bool CLASS::to_address_outputs(output_links& out,
38-
const hash_digest& key) const NOEXCEPT
37+
bool CLASS::to_address_outputs(const std::atomic_bool& cancel,
38+
output_links& out, const hash_digest& key) const NOEXCEPT
3939
{
4040
out.clear();
41+
42+
// Pushing into the vector is more efficient than precomputation of size.
4143
for (auto it = store_.address.it(key); it; ++it)
4244
{
4345
table::address::record address{};
44-
if (!store_.address.get(it, address))
46+
if (cancel || !store_.address.get(it, address))
4547
{
4648
out.clear();
47-
out.shrink_to_fit();
4849
return false;
4950
}
5051

@@ -56,11 +57,11 @@ bool CLASS::to_address_outputs(output_links& out,
5657

5758
// TODO: test more.
5859
TEMPLATE
59-
bool CLASS::to_confirmed_unspent_outputs(output_links& out,
60-
const hash_digest& key) const NOEXCEPT
60+
bool CLASS::to_confirmed_unspent_outputs(const std::atomic_bool& cancel,
61+
output_links& out, const hash_digest& key) const NOEXCEPT
6162
{
6263
output_links output_fks{};
63-
if (!to_address_outputs(output_fks, key))
64+
if (!to_address_outputs(cancel, output_fks, key))
6465
return false;
6566

6667
out.clear();
@@ -75,11 +76,11 @@ bool CLASS::to_confirmed_unspent_outputs(output_links& out,
7576

7677
// TODO: test more.
7778
TEMPLATE
78-
bool CLASS::to_minimum_unspent_outputs(output_links& out,
79-
const hash_digest& key, uint64_t minimum) const NOEXCEPT
79+
bool CLASS::to_minimum_unspent_outputs(const std::atomic_bool& cancel,
80+
output_links& out, const hash_digest& key, uint64_t minimum) const NOEXCEPT
8081
{
8182
output_links unspent_fks{};
82-
if (!to_confirmed_unspent_outputs(unspent_fks, key))
83+
if (!to_confirmed_unspent_outputs(cancel, unspent_fks, key))
8384
return false;
8485

8586
out.clear();
@@ -104,12 +105,12 @@ bool CLASS::to_minimum_unspent_outputs(output_links& out,
104105

105106
// TODO: test more.
106107
TEMPLATE
107-
bool CLASS::get_confirmed_balance(uint64_t& out,
108-
const hash_digest& key) const NOEXCEPT
108+
bool CLASS::get_confirmed_balance(const std::atomic_bool& cancel,
109+
uint64_t& out, const hash_digest& key) const NOEXCEPT
109110
{
110111
out = zero;
111112
output_links unspent_fks{};
112-
if (!to_confirmed_unspent_outputs(unspent_fks, key))
113+
if (!to_confirmed_unspent_outputs(cancel, unspent_fks, key))
113114
return false;
114115

115116
for (auto unspent_fk: unspent_fks)

include/bitcoin/database/query.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifndef LIBBITCOIN_DATABASE_QUERY_HPP
2020
#define LIBBITCOIN_DATABASE_QUERY_HPP
2121

22+
#include <atomic>
2223
#include <mutex>
2324
#include <utility>
2425
#include <bitcoin/system.hpp>
@@ -65,6 +66,7 @@ class query
6566
using point = system::chain::point;
6667
using input = system::chain::input;
6768
using output = system::chain::output;
69+
using outpoint = system::chain::outpoint;
6870
using header = system::chain::header;
6971
using script = system::chain::script;
7072
using witness = system::chain::witness;
@@ -394,8 +396,8 @@ class query
394396
input::cptr get_input(const tx_link& link, uint32_t index,
395397
bool witness) const NOEXCEPT;
396398

397-
point get_spent(const output_link& link) const NOEXCEPT;
398399
point get_spender(const point_link& link) const NOEXCEPT;
400+
outpoint get_spent(const output_link& link) const NOEXCEPT;
399401
script::cptr get_output_script(const output_link& link) const NOEXCEPT;
400402
output::cptr get_output(const output_link& link) const NOEXCEPT;
401403
output::cptr get_output(const tx_link& link, uint32_t index) const NOEXCEPT;
@@ -570,15 +572,14 @@ class query
570572
/// Optional Tables.
571573
/// -----------------------------------------------------------------------
572574

573-
/// Address, set internal to tx (natural-keyed).
574-
bool to_address_outputs(output_links& out,
575-
const hash_digest& key) const NOEXCEPT;
576-
bool to_confirmed_unspent_outputs(output_links& out,
577-
const hash_digest& key) const NOEXCEPT;
578-
bool to_minimum_unspent_outputs(output_links& out, const hash_digest& key,
579-
uint64_t value) const NOEXCEPT;
580-
bool get_confirmed_balance(uint64_t& out,
581-
const hash_digest& key) const NOEXCEPT;
575+
bool to_address_outputs(const std::atomic_bool& cancel,
576+
output_links& out, const hash_digest& key) const NOEXCEPT;
577+
bool to_confirmed_unspent_outputs(const std::atomic_bool& cancel,
578+
output_links& out, const hash_digest& key) const NOEXCEPT;
579+
bool to_minimum_unspent_outputs(const std::atomic_bool& cancel,
580+
output_links& out, const hash_digest& key, uint64_t value) const NOEXCEPT;
581+
bool get_confirmed_balance(const std::atomic_bool& cancel,
582+
uint64_t& out, const hash_digest& key) const NOEXCEPT;
582583

583584
bool is_filtered_body(const header_link& link) const NOEXCEPT;
584585
bool get_filter_body(filter& out, const header_link& link) const NOEXCEPT;

include/bitcoin/database/tables/archives/output.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,26 @@ struct output
133133
system::chain::script::cptr script{};
134134
};
135135

136+
struct get_parent_value
137+
: public schema::output
138+
{
139+
link count() const NOEXCEPT
140+
{
141+
BC_ASSERT(false);
142+
return {};
143+
}
144+
145+
inline bool from_data(reader& source) NOEXCEPT
146+
{
147+
parent_fk = source.read_little_endian<tx::integer, tx::size>();
148+
value = source.read_variable();
149+
return source;
150+
}
151+
152+
tx::integer parent_fk{};
153+
uint64_t value{};
154+
};
155+
136156
struct get_parent
137157
: public schema::output
138158
{

test/query/optional.cpp

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const auto events_handler = [](auto, auto) {};
2727

2828
const auto genesis_address = test::genesis.transactions_ptr()->front()->outputs_ptr()->front()->script().hash();
2929

30-
BOOST_AUTO_TEST_CASE(query_optional__get_confirmed_balance__genesis__expected)
30+
BOOST_AUTO_TEST_CASE(query_optional__to_address_outputs__genesis__expected)
3131
{
3232
settings settings{};
3333
settings.path = TEST_DIRECTORY;
@@ -36,12 +36,14 @@ BOOST_AUTO_TEST_CASE(query_optional__get_confirmed_balance__genesis__expected)
3636
BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success);
3737
BOOST_REQUIRE(query.initialize(test::genesis));
3838

39-
uint64_t out{};
40-
BOOST_REQUIRE(query.get_confirmed_balance(out, genesis_address));
41-
BOOST_REQUIRE_EQUAL(out, 5000000000u);
39+
output_links out{};
40+
const std::atomic_bool cancel{};
41+
BOOST_REQUIRE(query.to_address_outputs(cancel, out, genesis_address));
42+
BOOST_REQUIRE_EQUAL(out.size(), 1u);
43+
BOOST_REQUIRE_EQUAL(out.front(), query.to_output(0, 0));
4244
}
4345

44-
BOOST_AUTO_TEST_CASE(query_optional__to_address_outputs__genesis__expected)
46+
BOOST_AUTO_TEST_CASE(query_optional__to_address_outputs__cancel__canceled_false)
4547
{
4648
settings settings{};
4749
settings.path = TEST_DIRECTORY;
@@ -51,9 +53,9 @@ BOOST_AUTO_TEST_CASE(query_optional__to_address_outputs__genesis__expected)
5153
BOOST_REQUIRE(query.initialize(test::genesis));
5254

5355
output_links out{};
54-
BOOST_REQUIRE(query.to_address_outputs(out, genesis_address));
55-
BOOST_REQUIRE_EQUAL(out.size(), 1u);
56-
BOOST_REQUIRE_EQUAL(out.front(), query.to_output(0, 0));
56+
const std::atomic_bool cancel{ true };
57+
BOOST_REQUIRE(!query.to_address_outputs(cancel, out, genesis_address));
58+
BOOST_REQUIRE(out.empty());
5759
}
5860

5961
BOOST_AUTO_TEST_CASE(query_optional__to_confirmed_unspent_outputs__genesis__expected)
@@ -66,24 +68,26 @@ BOOST_AUTO_TEST_CASE(query_optional__to_confirmed_unspent_outputs__genesis__expe
6668
BOOST_REQUIRE(query.initialize(test::genesis));
6769

6870
output_links out{};
69-
BOOST_REQUIRE(query.to_confirmed_unspent_outputs(out, genesis_address));
71+
const std::atomic_bool cancel{};
72+
BOOST_REQUIRE(query.to_confirmed_unspent_outputs(cancel, out, genesis_address));
7073
BOOST_REQUIRE_EQUAL(out.size(), 1u);
7174
BOOST_REQUIRE_EQUAL(out.front(), 0);
7275
}
7376

74-
////BOOST_AUTO_TEST_CASE(query_optional__to_minimum_unspent_outputs__above__excluded)
75-
////{
76-
//// settings settings{};
77-
//// settings.path = TEST_DIRECTORY;
78-
//// test::chunk_store store{ settings };
79-
//// test::query_accessor query{ store };
80-
//// BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success);
81-
//// BOOST_REQUIRE(query.initialize(test::genesis));
82-
////
83-
//// output_links out{};
84-
//// BOOST_REQUIRE(query.to_minimum_unspent_outputs(out, genesis_address, 5000000001));
85-
//// BOOST_REQUIRE(out.empty());
86-
////}
77+
BOOST_AUTO_TEST_CASE(query_optional__to_minimum_unspent_outputs__above__excluded)
78+
{
79+
settings settings{};
80+
settings.path = TEST_DIRECTORY;
81+
test::chunk_store store{ settings };
82+
test::query_accessor query{ store };
83+
BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success);
84+
BOOST_REQUIRE(query.initialize(test::genesis));
85+
86+
output_links out{};
87+
const std::atomic_bool cancel{};
88+
BOOST_REQUIRE(query.to_minimum_unspent_outputs(cancel, out, genesis_address, 5000000001));
89+
BOOST_REQUIRE(out.empty());
90+
}
8791

8892
BOOST_AUTO_TEST_CASE(query_optional__to_minimum_unspent_outputs__at__included)
8993
{
@@ -95,7 +99,8 @@ BOOST_AUTO_TEST_CASE(query_optional__to_minimum_unspent_outputs__at__included)
9599
BOOST_REQUIRE(query.initialize(test::genesis));
96100

97101
output_links out{};
98-
BOOST_REQUIRE(query.to_minimum_unspent_outputs(out, genesis_address, 5000000000));
102+
const std::atomic_bool cancel{};
103+
BOOST_REQUIRE(query.to_minimum_unspent_outputs(cancel, out, genesis_address, 5000000000));
99104
BOOST_REQUIRE_EQUAL(out.size(), 1u);
100105
BOOST_REQUIRE_EQUAL(out.front(), 0);
101106
}
@@ -110,14 +115,30 @@ BOOST_AUTO_TEST_CASE(query_optional__to_minimum_unspent_outputs__below__included
110115
BOOST_REQUIRE(query.initialize(test::genesis));
111116

112117
output_links out{};
113-
BOOST_REQUIRE(query.to_minimum_unspent_outputs(out, genesis_address, 0));
118+
const std::atomic_bool cancel{};
119+
BOOST_REQUIRE(query.to_minimum_unspent_outputs(cancel, out, genesis_address, 0));
114120
BOOST_REQUIRE_EQUAL(out.size(), 1u);
115121
BOOST_REQUIRE_EQUAL(out.front(), 0);
116-
BOOST_REQUIRE(query.to_minimum_unspent_outputs(out, genesis_address, 4999999999));
122+
BOOST_REQUIRE(query.to_minimum_unspent_outputs(cancel, out, genesis_address, 4999999999));
117123
BOOST_REQUIRE_EQUAL(out.size(), 1u);
118124
BOOST_REQUIRE_EQUAL(out.front(), 0);
119125
}
120126

127+
BOOST_AUTO_TEST_CASE(query_optional__get_confirmed_balance__genesis__expected)
128+
{
129+
settings settings{};
130+
settings.path = TEST_DIRECTORY;
131+
test::chunk_store store{ settings };
132+
test::query_accessor query{ store };
133+
BOOST_REQUIRE_EQUAL(store.create(events_handler), error::success);
134+
BOOST_REQUIRE(query.initialize(test::genesis));
135+
136+
uint64_t out{};
137+
const std::atomic_bool cancel{};
138+
BOOST_REQUIRE(query.get_confirmed_balance(cancel, out, genesis_address));
139+
BOOST_REQUIRE_EQUAL(out, 5000000000u);
140+
}
141+
121142
////BOOST_AUTO_TEST_CASE(query_optional__set_filter__get_filter_and_head__expected)
122143
////{
123144
//// const auto& filter_head0 = system::null_hash;

0 commit comments

Comments
 (0)