@@ -304,21 +304,6 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,
304304 const auto checked = is_under_checkpoint (height) ||
305305 query.is_milestone (link);
306306
307- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
308- // Failed on block [363353] with block_internal_double_spend (!checked).
309- // The block object remains in scope during the call, but the pointer owns
310- // the memory. There is a local pointer object copied above, but it may be
311- // deleted once it is no longer referenced. This makes the block reference
312- // below weak. The message pointer object is also held by the calling
313- // closure, however it can be deleted by the compiler due to subsequent
314- // non-use. The copied block pointer holds the block object, but it may be
315- // also deleted if not referenced. Passing a block pointer into check,
316- // allowing block->check() to be called would resolve that issue, but not
317- // the issue of calling set_code (see below). But it's not clear how ~block
318- // could have occured here with query.set_code(*block) pending below.
319- // It hasn't failed when using a prevout table, which seems unrelated.
320- // But if it's a race to overwrite freed block memory, it's very possible.
321- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
322307 // Tx commitments and malleation are checked under bypass. Invalidity is
323308 // only stored when a strong header has been stored, later to be found out
324309 // as invalid and not malleable. Stored invalidity prevents repeat
@@ -330,11 +315,6 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,
330315 code == system::error::invalid_witness_commitment ||
331316 code == system::error::block_malleated)
332317 {
333- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
334- // These references to block didn't keep it in scope.
335- // But because block is const they could precede the check. Could
336- // be a compiler optimization as these are called by check(true).
337- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
338318 LOGR (" Uncommitted block [" << encode_hash (hash) << " :" << height
339319 << " ] from [" << authority () << " ] " << code.message ()
340320 << " txs(" << block->transactions () << " )"
@@ -363,18 +343,6 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,
363343 // Commit block.txs.
364344 // ........................................................................
365345
366- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
367- // For early segwit blocks this often fails to set the witness.
368- // There is no failure code, the witness is just empty and stored empty.
369- // That causes a validation failure with invalid_witness (!checked).
370- // It may have also failed in a way that invalidates confirmation queries.
371- // Passing a block pointer here would only hold the block in scope until
372- // it iterates transactions, with no subsequent reference. Then transaction
373- // pointers could hold themselves in scope, however block owns their memory
374- // and ~block() frees that memory even if the transaction pointer is alive.
375- // It hasn't failed when using a prevout table, which seems unrelated.
376- // But if it's a race to overwrite freed block memory, it's very possible.
377- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
378346 // This invokes set_strong when checked.
379347 if (const auto code = query.set_code (*block, link, checked))
380348 {
@@ -385,17 +353,11 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,
385353 return false ;
386354 }
387355
388- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
389- // TODO: verify that ~block() free during contained object access is the
390- // problem by switching to the default memory allocator w/non-prevout run
391- // and the code below disabled.
392- // TODO: pass shared_ptr in to check(block) and set_code(block) from here.
393- // This may guarantee the pointer (vs. block&) lifetime until return.
356+ // ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
394357 // This is an attempt to keep the shared pointer in scope.
395358 // Given that block is const this could also be reordered prior to check().
396359 // But this is not called in this scope, only by message deserialization.
397- // Passing the block pointer through the store
398- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360+ // ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
399361 if (!block->is_valid ())
400362 {
401363 stop (fault (error::protocol2));
@@ -411,10 +373,10 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec,
411373 notify (ec, chase::checked, height);
412374 fire (events::block_archived, height);
413375
414- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
376+ // ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
415377 // block->serialized_size may keep block in scope during set_code above.
416378 // However the compiler may reorder this calculation since block is const.
417- // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
379+ // ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
418380 count (block->serialized_size (true ));
419381 map_->erase (it);
420382 if (is_idle ())
0 commit comments