Skip to content

Commit 19bfa9c

Browse files
authored
Merge pull request #691 from evoskuil/master
Enhance spender queries.
2 parents fdea6c5 + 000c451 commit 19bfa9c

File tree

4 files changed

+39
-33
lines changed

4 files changed

+39
-33
lines changed

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ code CLASS::unspent_duplicates(const header_link& link,
176176
// unspendable
177177
// ----------------------------------------------------------------------------
178178

179+
TEMPLATE
180+
bool CLASS::is_strong(const tx_link& tx) const NOEXCEPT
181+
{
182+
// Try all txs with same hash as self (any instance will suffice).
183+
return !to_strong(get_tx_key(tx)).is_terminal();
184+
}
185+
179186
// protected
180187
TEMPLATE
181188
error::error_t CLASS::unspendable(uint32_t sequence, bool coinbase,
@@ -184,14 +191,10 @@ error::error_t CLASS::unspendable(uint32_t sequence, bool coinbase,
184191
// Ensure prevout tx is in a strong block, first try self link.
185192
auto strong = to_block(tx);
186193

187-
// Extremely rare, normally implies a duplicate tx.
188-
if (strong.is_terminal())
189-
{
190-
// Try all txs with same hash as self (any instance will suffice).
191-
strong = to_strong(get_tx_key(tx));
192-
if (strong.is_terminal())
193-
return error::unconfirmed_spend;
194-
}
194+
// Unassociated to block is rare, generally implies a duplicate tx.
195+
// Not strong (in any block) implies the spend is not confirmed.
196+
if (strong.is_terminal() && !is_strong(tx))
197+
return error::unconfirmed_spend;
195198

196199
const auto relative = ctx.is_enabled(system::chain::flags::bip68_rule) &&
197200
transaction::is_relative_locktime_applied(coinbase, version, sequence);

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,17 @@ typename CLASS::output::cptr CLASS::get_output(
304304
return out.output;
305305
}
306306

307+
TEMPLATE
308+
typename CLASS::point CLASS::get_spender(const point_link& link) const NOEXCEPT
309+
{
310+
if (const auto tx = to_spending_tx(link); !tx.is_terminal())
311+
if (const auto index = to_input_index(tx, link);
312+
index != point::null_index)
313+
return { get_tx_key(tx), index };
314+
315+
return {};
316+
}
317+
307318
TEMPLATE
308319
typename CLASS::inputs_ptr CLASS::get_spenders(
309320
const output_link& link, bool witness) const NOEXCEPT

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

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ header_link CLASS::to_strong(const hash_digest& tx_hash) const NOEXCEPT
187187
txs.push_back(*it);
188188

189189
// Find the first strong tx of the set and return its block.
190-
for (auto tx: txs)
190+
for (const auto& tx: txs)
191191
{
192192
const auto block = to_block(tx);
193193
if (!block.is_terminal())
@@ -222,9 +222,13 @@ header_link CLASS::to_confirmed_block(
222222
}
223223

224224
TEMPLATE
225-
point_link CLASS::to_confirmed_spender(const point&) const NOEXCEPT
225+
point_link CLASS::to_confirmed_spender(const point& prevout) const NOEXCEPT
226226
{
227-
// TODO: implement.
227+
// see is_spent_output().
228+
for (const auto& in: to_spenders(prevout))
229+
if (is_confirmed_input(in))
230+
return in;
231+
228232
return {};
229233
}
230234

@@ -261,20 +265,6 @@ uint32_t CLASS::to_output_index(const tx_link& parent_fk,
261265
return point::null_index;
262266
}
263267

264-
// Assumes singular which doesn't make sense.
265-
// protected/to_spenders
266-
////TEMPLATE
267-
////spend_link CLASS::to_spender(const tx_link& link,
268-
//// const spend_key& point) const NOEXCEPT
269-
////{
270-
//// table::spend::get_key spend{};
271-
//// for (const auto& spend_fk: to_spends(link))
272-
//// if (store_.spend.get(spend_fk, spend) && (spend.key == point))
273-
//// return spend_fk;
274-
////
275-
//// return {};
276-
////}
277-
278268
TEMPLATE
279269
point_links CLASS::to_spenders(const output_link& link) const NOEXCEPT
280270
{
@@ -286,12 +276,6 @@ point_links CLASS::to_spenders(const output_link& link) const NOEXCEPT
286276
return to_spenders(out.parent_fk, to_output_index(out.parent_fk, link));
287277
}
288278

289-
TEMPLATE
290-
point_links CLASS::to_spenders(const point& point) const NOEXCEPT
291-
{
292-
return to_spenders(point.hash(), point.index());
293-
}
294-
295279
TEMPLATE
296280
point_links CLASS::to_spenders(const tx_link& output_tx,
297281
uint32_t output_index) const NOEXCEPT
@@ -302,13 +286,19 @@ point_links CLASS::to_spenders(const tx_link& output_tx,
302286
TEMPLATE
303287
point_links CLASS::to_spenders(const hash_digest& point_hash,
304288
uint32_t output_index) const NOEXCEPT
289+
{
290+
return to_spenders({ point_hash, output_index });
291+
}
292+
293+
TEMPLATE
294+
point_links CLASS::to_spenders(const point& point) const NOEXCEPT
305295
{
306296
// Avoid returning spend links for coinbase inputs (not spenders).
307-
if (output_index == point::null_index)
297+
if (point.index() == point::null_index)
308298
return {};
309299

310300
point_links points{};
311-
for (auto it = store_.point.it({ point_hash, output_index }); it; ++it)
301+
for (auto it = store_.point.it(point); it; ++it)
312302
points.push_back(*it);
313303

314304
return points;

include/bitcoin/database/query.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ class query
397397
script::cptr get_output_script(const output_link& link) const NOEXCEPT;
398398
output::cptr get_output(const output_link& link) const NOEXCEPT;
399399
output::cptr get_output(const tx_link& link, uint32_t index) const NOEXCEPT;
400+
point get_spender(const point_link& link) const NOEXCEPT;
400401
inputs_ptr get_spenders(const output_link& link,
401402
bool witness) const NOEXCEPT;
402403

@@ -524,6 +525,7 @@ class query
524525
code block_confirmable(const header_link& link) const NOEXCEPT;
525526
bool is_prevouts_cached(const header_link& link) const NOEXCEPT;
526527

528+
bool is_strong(const tx_link& link) const NOEXCEPT;
527529
bool set_strong(const header_link& link) NOEXCEPT;
528530
bool set_unstrong(const header_link& link) NOEXCEPT;
529531
bool set_prevouts(const header_link& link, const block& block) NOEXCEPT;

0 commit comments

Comments
 (0)