From 10f7c95e73d8abad95245c3dd5c9285e12867a8b Mon Sep 17 00:00:00 2001 From: evoskuil Date: Fri, 23 Feb 2024 21:29:32 -0500 Subject: [PATCH 1/3] Comment typos. --- include/bitcoin/system/chain/prevout.hpp | 2 +- src/chain/transaction.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/bitcoin/system/chain/prevout.hpp b/include/bitcoin/system/chain/prevout.hpp index e71657ab6a..a61a3757e7 100644 --- a/include/bitcoin/system/chain/prevout.hpp +++ b/include/bitcoin/system/chain/prevout.hpp @@ -52,7 +52,7 @@ class BC_API prevout final /// For a non-coinbase input this indicates spent at height. bool spent{ true }; - // The output is of a coinbase transaction. + /// The output is of a coinbase transaction. bool coinbase{ false }; }; diff --git a/src/chain/transaction.cpp b/src/chain/transaction.cpp index e33a5242d3..7b366da0e6 100644 --- a/src/chain/transaction.cpp +++ b/src/chain/transaction.cpp @@ -1284,7 +1284,7 @@ code transaction::accept(const context&) const NOEXCEPT // Do NOT invoke on coinbase. // Node performs these checks through database query. -// This assume that prevout and metadata caching are completed on all inputs. +// This assumes that prevout and metadata caching are completed on all inputs. code transaction::confirm(const context& ctx) const NOEXCEPT { BC_ASSERT(!is_coinbase()); From d5f12a62384f63e5eebe5da26daf11c8e654c19a Mon Sep 17 00:00:00 2001 From: evoskuil Date: Fri, 23 Feb 2024 21:30:54 -0500 Subject: [PATCH 2/3] Enable tx.connect() empty block guard. --- src/chain/transaction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chain/transaction.cpp b/src/chain/transaction.cpp index 7b366da0e6..061030472a 100644 --- a/src/chain/transaction.cpp +++ b/src/chain/transaction.cpp @@ -1312,8 +1312,8 @@ code transaction::connect(const context& ctx) const NOEXCEPT { BC_ASSERT(!is_coinbase()); - ////if (is_coinbase()) - //// return error::transaction_success; + if (is_coinbase()) + return error::transaction_success; code ec; using namespace machine; From cf753cdd15a5919de99e2110e41d25827197eed8 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Fri, 23 Feb 2024 21:31:11 -0500 Subject: [PATCH 3/3] Change block.populate() to allow forward refs and own coinbase ref. --- include/bitcoin/system/chain/block.hpp | 3 +- src/chain/block.cpp | 51 +++++++++----------------- 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/include/bitcoin/system/chain/block.hpp b/include/bitcoin/system/chain/block.hpp index fbe555a29a..15ad80ce0b 100644 --- a/include/bitcoin/system/chain/block.hpp +++ b/include/bitcoin/system/chain/block.hpp @@ -105,8 +105,7 @@ class BC_API block code connect(const context& ctx) const NOEXCEPT; code confirm(const context& ctx) const NOEXCEPT; - /// Populate previous output metadata internal to the block. - /// Does not populate forward references (consensus limited). + /// Populate previous outputs (only, no metadata) internal to the block. void populate() const NOEXCEPT; protected: diff --git a/src/chain/block.cpp b/src/chain/block.cpp index 53036c4736..d9a3a23da0 100644 --- a/src/chain/block.cpp +++ b/src/chain/block.cpp @@ -564,48 +564,32 @@ bool block::is_unspent_coinbase_collision() const NOEXCEPT if (txs_->empty() || txs_->front()->inputs_ptr()->empty()) return false; - // May only commit duplicate coinbase that is already confirmed spent. + // May only commit duplicate coinbase that is already confirmed spent. + // Metadata population defaults coinbase to spent (not a collision). return !txs_->front()->inputs_ptr()->front()->metadata.spent; } +// Search is not ordered, forward references are caught by block.check. void block::populate() const NOEXCEPT { - // Coinbase, outputs only, inputs only. - if (txs_->size() < 3u) - return; - BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) - std::unordered_map map{}; - - // Skip coinbase tx. - auto tx = std::next(txs_->begin()); + std::unordered_map points{}; uint32_t index{}; - // Outputs only (first tx). - for (const auto& out: *(*tx)->outputs_ptr()) - map.emplace(point{ (*tx)->hash(false), index++ }, out); + // Populate outputs hash table. + for (auto tx = txs_->begin(); tx != txs_->end(); ++tx, index = 0) + for (const auto& out: *(*tx)->outputs_ptr()) + points.emplace(point{ (*tx)->hash(false), index++ }, out); - // Search is ordered, no forward references or coinbase spend (consensus). - for (++tx; tx != std::prev(txs_->end()); ++tx) + // Populate input prevouts from hash table. + for (auto tx = txs_->begin(); tx != txs_->end(); ++tx) { for (const auto& in: *(*tx)->inputs_ptr()) { - const auto element = map.find(in->point()); - if (element != map.end()) - in->prevout = element->second; + const auto point = points.find(in->point()); + if (point != points.end()) + in->prevout = point->second; } - - index = 0; - for (const auto& out: *(*tx)->outputs_ptr()) - map.emplace(point{ (*tx)->hash(false), index++ }, out); - } - - // Inputs only (last tx). - for (const auto& in: *(*tx)->inputs_ptr()) - { - const auto element = map.find(in->point()); - if (element != map.end()) - in->prevout = element->second; } BC_POP_WARNING() @@ -668,10 +652,11 @@ code block::connect_transactions(const context& ctx) const NOEXCEPT code block::confirm_transactions(const context& ctx) const NOEXCEPT { code ec; - - for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx) - if ((ec = (*tx)->confirm(ctx))) - return ec; + + if (!is_empty()) + for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx) + if ((ec = (*tx)->confirm(ctx))) + return ec; return error::block_success; }