diff --git a/include/bitcoin/node/impl/chasers/chaser_organize.ipp b/include/bitcoin/node/impl/chasers/chaser_organize.ipp index a85cf4e3..fa540fb4 100644 --- a/include/bitcoin/node/impl/chasers/chaser_organize.ipp +++ b/include/bitcoin/node/impl/chasers/chaser_organize.ipp @@ -125,6 +125,7 @@ void CLASS::do_organize(typename Block::cptr block, using namespace system; BC_ASSERT(stranded()); + // shared_ptr copy keeps block ref in scope until completion of set_code. const auto& hash = block->get_hash(); const auto& header = get_header(*block); auto& query = archive(); @@ -564,6 +565,7 @@ code CLASS::push_block(const system::hash_digest& key) NOEXCEPT if (!handle) return error::organize15; + // handle keeps the block reference in scope until completion of set_code. const auto& value = handle.mapped(); return push_block(*value.block, value.state->context()); } diff --git a/src/protocols/protocol_block_in_31800.cpp b/src/protocols/protocol_block_in_31800.cpp index e48b7cc5..ef9fd9d1 100644 --- a/src/protocols/protocol_block_in_31800.cpp +++ b/src/protocols/protocol_block_in_31800.cpp @@ -351,8 +351,11 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec, // Commit block.txs. // ........................................................................ + // This must not be a reference to the shared pointer, as otherwise the + // shared_ptr may be taken out of scope before the tx write completes. + // set_code() uses weak references to many elements of the transaction ref. + const auto txs_ptr = block->transactions_ptr(); const auto size = block->serialized_size(true); - const auto& txs_ptr = block->transactions_ptr(); // This invokes set_strong when checked. if (const auto code = query.set_code(*txs_ptr, link, size, checked))