Skip to content

Commit c110681

Browse files
committed
Add orphan block transaction scavenging.
1 parent 494f83c commit c110681

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

include/bitcoin/node/protocols/protocol_block_in.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class BCN_API protocol_block_in
5858
bool handle_receive_inventory(const code& ec, inventory_const_ptr message);
5959
bool handle_receive_not_found(const code& ec, not_found_const_ptr message);
6060
void handle_store_block(const code& ec, block_const_ptr message);
61+
void handle_orphan_block(const code& ec, size_t position,
62+
block_const_ptr message);
6163
void handle_fetch_block_locator(const code& ec, get_headers_ptr message,
6264
const hash_digest& stop_hash);
6365

src/protocols/protocol_block_in.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,39 @@ bool protocol_block_in::handle_receive_block(const code& ec,
321321
return true;
322322
}
323323

324+
void protocol_block_in::handle_orphan_block(const code& ec,
325+
size_t position, block_const_ptr message)
326+
{
327+
if (stopped(ec))
328+
return;
329+
330+
const auto& txs = message->transactions();
331+
332+
if (!ec && position > 0)
333+
{
334+
BITCOIN_ASSERT(position < txs.size());
335+
const auto encoded = encode_hash(txs[position].hash());
336+
337+
LOG_DEBUG(LOG_NODE)
338+
<< "Scavenged transaction [" << encoded << "] from ["
339+
<< authority() << "].";
340+
}
341+
342+
// Start by incrementing past the presumed coinbase, and so-on.
343+
if (++position >= txs.size())
344+
{
345+
// Ask the peer for blocks from the chain top up to this orphan.
346+
send_get_blocks(message->hash());
347+
return;
348+
}
349+
350+
// TODO: store txs in shared pointer list within block.
351+
auto tx = std::make_shared<const message::transaction>(txs[position]);
352+
353+
// Recursion is broken up by the organizer's priority pool transition.
354+
chain_.organize(tx, BIND3(handle_orphan_block, _1, position, message));
355+
}
356+
324357
// The block has been saved to the block chain (or not).
325358
// This will be picked up by subscription in block_out and will cause the block
326359
// to be announced to non-originating peers.
@@ -331,16 +364,18 @@ void protocol_block_in::handle_store_block(const code& ec,
331364
return;
332365

333366
const auto hash = message->header().hash();
367+
const auto encoded = encode_hash(hash);
334368

335-
// Ask the peer for blocks from the chain top up to this orphan.
336369
if (ec == error::orphan_block)
337-
send_get_blocks(hash);
338-
339-
const auto encoded = encode_hash(hash);
370+
{
371+
LOG_DEBUG(LOG_NODE)
372+
<< "Scavenging orphan block [" << encoded << "] from ["
373+
<< authority() << "]";
374+
handle_orphan_block(error::success, 0, message);
375+
return;
376+
}
340377

341-
if (ec == error::orphan_block ||
342-
ec == error::duplicate_block ||
343-
ec == error::insufficient_work)
378+
if (ec == error::duplicate_block || ec == error::insufficient_work)
344379
{
345380
LOG_DEBUG(LOG_NODE)
346381
<< "Captured block [" << encoded << "] from [" << authority()

0 commit comments

Comments
 (0)