Skip to content

Commit ed7b9cb

Browse files
authored
Merge pull request #775 from evoskuil/master
Don't collect fees on confirmed address history queries.
2 parents 1410930 + edb7154 commit ed7b9cb

6 files changed

Lines changed: 90 additions & 37 deletions

File tree

include/bitcoin/database/impl/query/address/address_history.ipp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ code CLASS::get_unconfirmed_history(const stopper& cancel, histories& out,
6868
}
6969

7070
uint64_t fee{};
71-
auto height = history::unrooted_height;
7271
if (!get_tx_fee(fee, link))
7372
fee = history::missing_prevout;
74-
else if (is_confirmed_all_prevouts(link))
73+
74+
auto height = history::unrooted_height;
75+
if (is_confirmed_all_prevouts(link))
7576
height = history::rooted_height;
7677

7778
return history{ { std::move(hash), height }, fee,
@@ -115,9 +116,10 @@ code CLASS::get_confirmed_history(const stopper& cancel, histories& out,
115116
return history{};
116117
}
117118

118-
uint64_t fee{};
119-
if (!get_tx_fee(fee, link))
120-
fee = history::missing_prevout;
119+
// Electrum uses fees only on unconfirmed (and expensive).
120+
constexpr auto fee = history::missing_prevout;
121+
////if (!get_tx_fee(fee, link))
122+
//// fee = history::missing_prevout;
121123

122124
return history{ { std::move(hash), height }, fee, position };
123125
});
@@ -176,10 +178,8 @@ history CLASS::get_tx_history(hash_digest&& key,
176178
if (link.is_terminal())
177179
return {};
178180

179-
uint64_t fee{};
180-
if (!get_tx_fee(fee, link))
181-
fee = history::missing_prevout;
182-
181+
// Electrum uses fees only on unconfirmed (and expensive).
182+
auto fee = history::missing_prevout;
183183
auto height = history::unrooted_height;
184184
auto position = history::unconfirmed_position;
185185
if (const auto block = find_confirmed_block(link); !block.is_terminal())
@@ -190,13 +190,17 @@ history CLASS::get_tx_history(hash_digest&& key,
190190
}
191191
else
192192
{
193+
if (!get_tx_fee(fee, link))
194+
fee = history::missing_prevout;
195+
193196
if (is_confirmed_all_prevouts(link))
194197
height = history::rooted_height;
195198
}
196199

197200
return { { std::move(key), height }, fee, position };
198201
}
199202

203+
// server/electrum
200204
TEMPLATE
201205
histories CLASS::get_spenders_history(
202206
const system::chain::point& prevout) const NOEXCEPT

include/bitcoin/database/impl/query/address/address_outpoints.ipp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,30 @@ code CLASS::get_address_outpoints(const stopper& cancel, outpoints& out,
117117
});
118118
}
119119

120+
// TODO: server/native
121+
TEMPLATE
122+
code CLASS::get_address_outpoints(const stopper& cancel, address_link& cursor,
123+
outpoints& out, const hash_digest& key, bool turbo) const NOEXCEPT
124+
{
125+
out.clear();
126+
output_links links{};
127+
if (const code ec = to_address_outputs(cancel, cursor, links, key))
128+
return ec;
129+
130+
return parallel_outpoint_transform(cancel, turbo, out, links,
131+
[this](const output_link& link, auto& cancel, auto& fail) NOEXCEPT
132+
{
133+
if (cancel || fail)
134+
return outpoint{};
135+
136+
const auto point = get_outpoint(link);
137+
if (!point.point().is_valid())
138+
fail = true;
139+
140+
return point;
141+
});
142+
}
143+
120144
// utilities
121145
// ----------------------------------------------------------------------------
122146
// private/static

include/bitcoin/database/query.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,8 @@ class query
630630
const hash_digest& key, uint64_t value, bool turbo=false) const NOEXCEPT;
631631
code get_address_outpoints(const stopper& cancel, outpoints& out,
632632
const hash_digest& key, bool turbo=false) const NOEXCEPT;
633+
code get_address_outpoints(const stopper& cancel, address_link& cursor,
634+
outpoints& out, const hash_digest& key, bool turbo=false) const NOEXCEPT;
633635

634636
/// Electrum queries (histories, deduped, electrum sort).
635637
code get_unconfirmed_history(const stopper& cancel, histories& out,
@@ -657,6 +659,7 @@ class query
657659
bool turbo=false) const NOEXCEPT;
658660

659661
/// History queries.
662+
// TODO: add point_link cursor to new get_spenders(cursor, point) query.
660663
history get_tx_history(const tx_link& link) const NOEXCEPT;
661664
history get_tx_history(const hash_digest& key) const NOEXCEPT;
662665
histories get_spenders_history(const point& prevout) const NOEXCEPT;

include/bitcoin/database/types/history.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ struct BCD_API history
2929
{
3030
static constexpr size_t rooted_height = zero;
3131
static constexpr size_t unrooted_height = max_size_t;
32-
static constexpr size_t missing_prevout = max_uint64;
3332
static constexpr size_t unconfirmed_position = max_size_t;
33+
static constexpr uint64_t missing_prevout = max_uint64;
3434

3535
static void filter_sort_and_dedup(std::vector<history>& history) NOEXCEPT;
3636

test/query/address/address_history.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ BOOST_AUTO_TEST_CASE(query_address__get_history__genesis__expected)
4242

4343
out.clear();
4444
BOOST_REQUIRE(!query.get_confirmed_history(cancel, out, test::genesis_address0));
45-
BOOST_REQUIRE_EQUAL(out.at(0).fee, 0u);
45+
BOOST_REQUIRE_EQUAL(out.at(0).fee, history::missing_prevout);
4646
BOOST_REQUIRE_EQUAL(out.at(0).position, 0u);
4747
BOOST_REQUIRE_EQUAL(out.at(0).tx.height(), 0u);
4848
BOOST_REQUIRE_EQUAL(out.at(0).tx.hash(), test::genesis.transactions_ptr()->at(0)->hash(false));
4949

5050
out.clear();
5151
BOOST_REQUIRE(!query.get_history(cancel, out, test::genesis_address0));
52-
BOOST_REQUIRE_EQUAL(out.at(0).fee, 0u);
52+
BOOST_REQUIRE_EQUAL(out.at(0).fee, history::missing_prevout);
5353
BOOST_REQUIRE_EQUAL(out.at(0).position, 0u);
5454
BOOST_REQUIRE_EQUAL(out.at(0).tx.height(), 0u);
5555
BOOST_REQUIRE_EQUAL(out.at(0).tx.hash(), test::genesis.transactions_ptr()->at(0)->hash(false));
@@ -96,34 +96,34 @@ BOOST_AUTO_TEST_CASE(query_address__get_unconfirmed_history__turbo_block1a_addre
9696
BOOST_REQUIRE_EQUAL(out.size(), 4u);
9797

9898
// Identities (not part of sort).
99-
BOOST_REQUIRE_EQUAL(out.at(0).tx.hash(), test::tx4.hash(false)); // tx4
100-
BOOST_REQUIRE_EQUAL(out.at(1).tx.hash(), test::block2b.transactions_ptr()->at(0)->hash(false)); // tx8
101-
BOOST_REQUIRE_EQUAL(out.at(2).tx.hash(), test::tx5.hash(false)); // tx5
102-
BOOST_REQUIRE_EQUAL(out.at(3).tx.hash(), test::block1b.transactions_ptr()->at(0)->hash(false)); // tx7
99+
BOOST_CHECK_EQUAL(out.at(0).tx.hash(), test::tx5.hash(false)); // tx5
100+
BOOST_CHECK_EQUAL(out.at(1).tx.hash(), test::tx4.hash(false)); // tx4
101+
BOOST_CHECK_EQUAL(out.at(2).tx.hash(), test::block2b.transactions_ptr()->at(0)->hash(false)); // tx8
102+
BOOST_CHECK_EQUAL(out.at(3).tx.hash(), test::block1b.transactions_ptr()->at(0)->hash(false)); // tx7
103103

104104
// Confirmed by height ascending (not part of sort).
105105

106106
// Unconfirmed rooted before unrooted.
107-
BOOST_REQUIRE_EQUAL(out.at(0).tx.height(), history::rooted_height); // spends block1a (tx0 both outputs).
108-
BOOST_REQUIRE_EQUAL(out.at(1).tx.height(), history::unrooted_height); // bk2btx0 unrooted (spends bk1).
109-
BOOST_REQUIRE_EQUAL(out.at(2).tx.height(), history::unrooted_height); // spend exceeds value (treated as missing prevout).
110-
BOOST_REQUIRE_EQUAL(out.at(3).tx.height(), history::unrooted_height); // bk1btx0 unrooted (missing prevouts).
107+
BOOST_CHECK_EQUAL(out.at(0).tx.height(), history::rooted_height); // tx5 spends block1a
108+
BOOST_CHECK_EQUAL(out.at(1).tx.height(), history::rooted_height); // tx4 spends block1a
109+
BOOST_CHECK_EQUAL(out.at(2).tx.height(), history::unrooted_height); // block2b spends block1b
110+
BOOST_CHECK_EQUAL(out.at(3).tx.height(), history::unrooted_height); // block1b missing prevouts
111111

112112
// Confirmed height by block position (not part of sort).
113-
BOOST_REQUIRE_EQUAL(out.at(0).position, history::unconfirmed_position);
114-
BOOST_REQUIRE_EQUAL(out.at(1).position, history::unconfirmed_position);
115-
BOOST_REQUIRE_EQUAL(out.at(2).position, history::unconfirmed_position);
116-
BOOST_REQUIRE_EQUAL(out.at(3).position, history::unconfirmed_position);
113+
BOOST_CHECK_EQUAL(out.at(0).position, history::unconfirmed_position);
114+
BOOST_CHECK_EQUAL(out.at(1).position, history::unconfirmed_position);
115+
BOOST_CHECK_EQUAL(out.at(2).position, history::unconfirmed_position);
116+
BOOST_CHECK_EQUAL(out.at(3).position, history::unconfirmed_position);
117117

118118
// Unconfirmed system::encode_hash(hash) lexically sorted.
119-
BOOST_REQUIRE(encode_hash(out.at(1).tx.hash()) < encode_hash(out.at(2).tx.hash()));
120-
BOOST_REQUIRE(encode_hash(out.at(2).tx.hash()) < encode_hash(out.at(3).tx.hash()));
119+
BOOST_CHECK(encode_hash(out.at(0).tx.hash()) < encode_hash(out.at(1).tx.hash()));
120+
BOOST_CHECK(encode_hash(out.at(2).tx.hash()) < encode_hash(out.at(3).tx.hash()));
121121

122122
// Fee (not part of sort).
123-
BOOST_REQUIRE_EQUAL(out.at(0).fee, floored_subtract(0x18u + 0x2au, 0x08u));
124-
BOOST_REQUIRE_EQUAL(out.at(1).fee, floored_subtract(0xb1u + 0xb1u, 0xb2u));
125-
BOOST_REQUIRE_EQUAL(out.at(2).fee, history::missing_prevout); // spend exceeds value (treated as missing prevout).
126-
BOOST_REQUIRE_EQUAL(out.at(3).fee, 0u); // coinbase (archived with null single point).
123+
BOOST_CHECK_EQUAL(out.at(0).fee, history::missing_prevout); // spend exceeds value (treated as missing prevout).
124+
BOOST_CHECK_EQUAL(out.at(1).fee, floored_subtract(0x18u + 0x2au, 0x08u));
125+
BOOST_CHECK_EQUAL(out.at(2).fee, floored_subtract(0xb1u + 0xb1u, 0xb2u));
126+
BOOST_CHECK_EQUAL(out.at(3).fee, 0u); // coinbase (archived with null single point).
127127
}
128128

129129
BOOST_AUTO_TEST_CASE(query_address__get_confirmed_history__turbo_block1a_address0__expected)
@@ -229,7 +229,7 @@ BOOST_AUTO_TEST_CASE(query_address__get_history__turbo_block1a_address0__expecte
229229
BOOST_REQUIRE_EQUAL(out.at(4).fee, history::missing_prevout); // tx5/tx4
230230
BOOST_REQUIRE_EQUAL(out.at(5).fee, floored_subtract(0x18u + 0x2au, 0x08u)); // tx4/tx8
231231
BOOST_REQUIRE_EQUAL(out.at(6).fee, floored_subtract(0xb1u + 0xb1u, 0xb2u)); // tx8/tx5
232-
BOOST_REQUIRE_EQUAL(out.at(7).fee, 0u); // tx7
232+
BOOST_REQUIRE_EQUAL(out.at(7).fee, history::missing_prevout); // tx7
233233
}
234234

235235
// get_tx_history1
@@ -260,14 +260,14 @@ BOOST_AUTO_TEST_CASE(query_address__get_tx_history__genesis__expected)
260260
const auto hash = test::genesis.transactions_ptr()->at(0)->hash(false);
261261
auto history = query.get_tx_history(0);
262262
BOOST_REQUIRE(history.valid());
263-
BOOST_REQUIRE_EQUAL(history.fee, 0u);
263+
BOOST_REQUIRE_EQUAL(history.fee, history::missing_prevout);
264264
BOOST_REQUIRE_EQUAL(history.position, 0u);
265265
BOOST_REQUIRE_EQUAL(history.tx.height(), 0u);
266266
BOOST_REQUIRE_EQUAL(history.tx.hash(), hash);
267267

268268
history = query.get_tx_history(hash);
269269
BOOST_REQUIRE(history.valid());
270-
BOOST_REQUIRE_EQUAL(history.fee, 0u);
270+
BOOST_REQUIRE_EQUAL(history.fee, history::missing_prevout);
271271
BOOST_REQUIRE_EQUAL(history.position, 0u);
272272
BOOST_REQUIRE_EQUAL(history.tx.height(), 0u);
273273
BOOST_REQUIRE_EQUAL(history.tx.hash(), hash);

test/query/address/address_outpoints.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ BOOST_AUTO_TEST_CASE(query_address__get_minimum_unspent_outpoints__below__includ
124124
BOOST_REQUIRE(*out.begin() == query.get_outpoint(query.to_output(0, 0)));
125125
}
126126

127-
// get_address_outpoints
127+
// get_address_outpoints1
128128

129-
BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints__turbo_genesis__expected)
129+
BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints1__turbo_genesis__expected)
130130
{
131131
settings settings{};
132132
settings.path = TEST_DIRECTORY;
@@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints__turbo_genesis__expect
142142
BOOST_REQUIRE(*out.begin() == query.get_outpoint(query.to_output(0, 0)));
143143
}
144144

145-
BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints__genesis__expected)
145+
BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints1__genesis__expected)
146146
{
147147
settings settings{};
148148
settings.path = TEST_DIRECTORY;
@@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints__genesis__expected)
158158
BOOST_REQUIRE(*out.begin() == query.get_outpoint(query.to_output(0, 0)));
159159
}
160160

161-
BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints__cancel__canceled_false)
161+
BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints1__cancel__canceled_false)
162162
{
163163
settings settings{};
164164
settings.path = TEST_DIRECTORY;
@@ -173,4 +173,26 @@ BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints__cancel__canceled_fals
173173
BOOST_REQUIRE(out.empty());
174174
}
175175

176+
// get_address_outpoints2
177+
178+
BOOST_AUTO_TEST_CASE(query_address__get_address_outpoints2__progressive_cursor__expected)
179+
{
180+
settings settings{};
181+
settings.path = TEST_DIRECTORY;
182+
test::chunk_store store{ settings };
183+
test::query_accessor query{ store };
184+
BOOST_REQUIRE(!store.create(test::events_handler));
185+
BOOST_REQUIRE(query.initialize(test::genesis));
186+
187+
outpoints out{};
188+
address_link cursor{};
189+
const std::atomic_bool cancel{};
190+
BOOST_REQUIRE(!query.get_address_outpoints(cancel, cursor, out, test::genesis_address0));
191+
BOOST_REQUIRE_EQUAL(out.size(), 1u);
192+
BOOST_REQUIRE_EQUAL(cursor, 0u);
193+
BOOST_REQUIRE(*out.begin() == query.get_outpoint(query.to_output(0, 0)));
194+
195+
// TODO: add same tx again.
196+
}
197+
176198
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)