Remove coupling of block processor and unchecked_map on unchecked_info::modified. (#3728)

* Currently the modified timestamp is updated by the block processor which is a violation of separations of concerns with the unchecked_map. This moves responsibility of setting modification timestamp in to unchecked_map.

* The block_arrival container tracks blocks that are from realtime traffic instead of bootstrap traffic. This is sufficient to trigger process_live on its own. Checking the modification timestamp from unchecked_map is unrelated.

* Encapsulating nano::unchecked_info::modified since it's only set by the unchecked_map class itself when writing.

* Remove nano::unchecked_info friend class in favor of setting nano::unchecked_info::modified in the constructor.

* Removes the unnecessary origination field from block_processor::add

Co-authored-by: Thiago Silva <thiago@nano.org>
This commit is contained in:
clemahieu 2022-02-22 15:52:47 +00:00 committed by GitHub
commit 5186a22506
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 41 additions and 42 deletions

View file

@ -95,13 +95,13 @@ TEST (gap_cache, two_dependencies)
auto send2 (std::make_shared<nano::send_block> (send1->hash (), key.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *system.work.generate (send1->hash ()))); auto send2 (std::make_shared<nano::send_block> (send1->hash (), key.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *system.work.generate (send1->hash ())));
auto open (std::make_shared<nano::open_block> (send1->hash (), key.pub, key.pub, key.prv, key.pub, *system.work.generate (key.pub))); auto open (std::make_shared<nano::open_block> (send1->hash (), key.pub, key.pub, key.prv, key.pub, *system.work.generate (key.pub)));
ASSERT_EQ (0, node1.gap_cache.size ()); ASSERT_EQ (0, node1.gap_cache.size ());
node1.block_processor.add (send2, nano::seconds_since_epoch ()); node1.block_processor.add (send2);
node1.block_processor.flush (); node1.block_processor.flush ();
ASSERT_EQ (1, node1.gap_cache.size ()); ASSERT_EQ (1, node1.gap_cache.size ());
node1.block_processor.add (open, nano::seconds_since_epoch ()); node1.block_processor.add (open);
node1.block_processor.flush (); node1.block_processor.flush ();
ASSERT_EQ (2, node1.gap_cache.size ()); ASSERT_EQ (2, node1.gap_cache.size ());
node1.block_processor.add (send1, nano::seconds_since_epoch ()); node1.block_processor.add (send1);
node1.block_processor.flush (); node1.block_processor.flush ();
ASSERT_TIMELY (5s, node1.gap_cache.size () == 0); ASSERT_TIMELY (5s, node1.gap_cache.size () == 0);
auto transaction (node1.store.tx_begin_read ()); auto transaction (node1.store.tx_begin_read ());

View file

@ -2205,8 +2205,8 @@ TEST (node, block_confirm)
auto send1_copy = builder.make_block () auto send1_copy = builder.make_block ()
.from (*send1) .from (*send1)
.build_shared (); .build_shared ();
node1.block_processor.add (send1, nano::seconds_since_epoch ()); node1.block_processor.add (send1);
node2.block_processor.add (send1_copy, nano::seconds_since_epoch ()); node2.block_processor.add (send1_copy);
ASSERT_TIMELY (5s, node1.ledger.block_or_pruned_exists (send1->hash ()) && node2.ledger.block_or_pruned_exists (send1_copy->hash ())); ASSERT_TIMELY (5s, node1.ledger.block_or_pruned_exists (send1->hash ()) && node2.ledger.block_or_pruned_exists (send1_copy->hash ()));
ASSERT_TRUE (node1.ledger.block_or_pruned_exists (send1->hash ())); ASSERT_TRUE (node1.ledger.block_or_pruned_exists (send1->hash ()));
ASSERT_TRUE (node2.ledger.block_or_pruned_exists (send1_copy->hash ())); ASSERT_TRUE (node2.ledger.block_or_pruned_exists (send1_copy->hash ()));

View file

@ -49,7 +49,7 @@ TEST (unchecked_map, construction)
TEST (unchecked_map, put_one) TEST (unchecked_map, put_one)
{ {
context context; context context;
nano::unchecked_info info{ block (), nano::dev::genesis_key.pub, nano::seconds_since_epoch () }; nano::unchecked_info info{ block (), nano::dev::genesis_key.pub };
context.unchecked.put (info.block->previous (), info); context.unchecked.put (info.block->previous (), info);
} }

View file

@ -1824,7 +1824,7 @@ int main (int argc, char * const * argv)
{ {
std::cout << boost::str (boost::format ("%1% blocks retrieved") % count) << std::endl; std::cout << boost::str (boost::format ("%1% blocks retrieved") % count) << std::endl;
} }
nano::unchecked_info unchecked_info (block, account, 0, nano::signature_verification::unknown); nano::unchecked_info unchecked_info (block, account, nano::signature_verification::unknown);
node.node->block_processor.add (unchecked_info); node.node->block_processor.add (unchecked_info);
if (block->type () == nano::block_type::state && block->previous ().is_zero () && source_node->ledger.is_epoch_link (block->link ())) if (block->type () == nano::block_type::state && block->previous ().is_zero () && source_node->ledger.is_epoch_link (block->link ()))
{ {

View file

@ -97,9 +97,9 @@ bool nano::block_processor::half_full ()
return size () >= node.flags.block_processor_full_size / 2; return size () >= node.flags.block_processor_full_size / 2;
} }
void nano::block_processor::add (std::shared_ptr<nano::block> const & block_a, uint64_t origination) void nano::block_processor::add (std::shared_ptr<nano::block> const & block_a)
{ {
nano::unchecked_info info (block_a, 0, origination, nano::signature_verification::unknown); nano::unchecked_info info (block_a, 0, nano::signature_verification::unknown);
add (info); add (info);
} }
@ -256,7 +256,7 @@ void nano::block_processor::process_batch (nano::unique_lock<nano::mutex> & lock
} }
else else
{ {
info = nano::unchecked_info (forced.front (), 0, nano::seconds_since_epoch (), nano::signature_verification::unknown); info = nano::unchecked_info (forced.front (), 0, nano::signature_verification::unknown);
forced.pop_front (); forced.pop_front ();
hash = info.block->hash (); hash = info.block->hash ();
force = true; force = true;
@ -353,7 +353,7 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction
block->serialize_json (block_string, node.config.logging.single_line_record ()); block->serialize_json (block_string, node.config.logging.single_line_record ());
node.logger.try_log (boost::str (boost::format ("Processing block %1%: %2%") % hash.to_string () % block_string)); node.logger.try_log (boost::str (boost::format ("Processing block %1%: %2%") % hash.to_string () % block_string));
} }
if ((info_a.modified > nano::seconds_since_epoch () - 300 && node.block_arrival.recent (hash)) || forced_a) if (node.block_arrival.recent (hash) || forced_a)
{ {
events_a.events.emplace_back ([this, hash, block = info_a.block, result, origin_a] (nano::transaction const & post_event_transaction_a) { process_live (post_event_transaction_a, hash, block, result, origin_a); }); events_a.events.emplace_back ([this, hash, block = info_a.block, result, origin_a] (nano::transaction const & post_event_transaction_a) { process_live (post_event_transaction_a, hash, block, result, origin_a); });
} }
@ -376,10 +376,6 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction
node.logger.try_log (boost::str (boost::format ("Gap previous for: %1%") % hash.to_string ())); node.logger.try_log (boost::str (boost::format ("Gap previous for: %1%") % hash.to_string ()));
} }
info_a.verified = result.verified; info_a.verified = result.verified;
if (info_a.modified == 0)
{
info_a.modified = nano::seconds_since_epoch ();
}
node.unchecked.put (block->previous (), info_a); node.unchecked.put (block->previous (), info_a);
events_a.events.emplace_back ([this, hash] (nano::transaction const & /* unused */) { this->node.gap_cache.add (hash); }); events_a.events.emplace_back ([this, hash] (nano::transaction const & /* unused */) { this->node.gap_cache.add (hash); });
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_previous); node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_previous);
@ -392,10 +388,6 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction
node.logger.try_log (boost::str (boost::format ("Gap source for: %1%") % hash.to_string ())); node.logger.try_log (boost::str (boost::format ("Gap source for: %1%") % hash.to_string ()));
} }
info_a.verified = result.verified; info_a.verified = result.verified;
if (info_a.modified == 0)
{
info_a.modified = nano::seconds_since_epoch ();
}
node.unchecked.put (node.ledger.block_source (transaction_a, *(block)), info_a); node.unchecked.put (node.ledger.block_source (transaction_a, *(block)), info_a);
events_a.events.emplace_back ([this, hash] (nano::transaction const & /* unused */) { this->node.gap_cache.add (hash); }); events_a.events.emplace_back ([this, hash] (nano::transaction const & /* unused */) { this->node.gap_cache.add (hash); });
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source); node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source);
@ -408,10 +400,6 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction
node.logger.try_log (boost::str (boost::format ("Gap pending entries for epoch open: %1%") % hash.to_string ())); node.logger.try_log (boost::str (boost::format ("Gap pending entries for epoch open: %1%") % hash.to_string ()));
} }
info_a.verified = result.verified; info_a.verified = result.verified;
if (info_a.modified == 0)
{
info_a.modified = nano::seconds_since_epoch ();
}
node.unchecked.put (block->account (), info_a); // Specific unchecked key starting with epoch open block account public key node.unchecked.put (block->account (), info_a); // Specific unchecked key starting with epoch open block account public key
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source); node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source);
break; break;
@ -503,7 +491,7 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction
nano::process_return nano::block_processor::process_one (nano::write_transaction const & transaction_a, block_post_events & events_a, std::shared_ptr<nano::block> const & block_a) nano::process_return nano::block_processor::process_one (nano::write_transaction const & transaction_a, block_post_events & events_a, std::shared_ptr<nano::block> const & block_a)
{ {
nano::unchecked_info info (block_a, block_a->account (), 0, nano::signature_verification::unknown); nano::unchecked_info info (block_a, block_a->account (), nano::signature_verification::unknown);
auto result (process_one (transaction_a, events_a, info)); auto result (process_one (transaction_a, events_a, info));
return result; return result;
} }

View file

@ -56,7 +56,7 @@ public:
bool half_full (); bool half_full ();
void add_local (nano::unchecked_info const & info_a); void add_local (nano::unchecked_info const & info_a);
void add (nano::unchecked_info const &); void add (nano::unchecked_info const &);
void add (std::shared_ptr<nano::block> const &, uint64_t = 0); void add (std::shared_ptr<nano::block> const &);
void force (std::shared_ptr<nano::block> const &); void force (std::shared_ptr<nano::block> const &);
void wait_write (); void wait_write ();
bool should_log (); bool should_log ();

View file

@ -144,7 +144,7 @@ bool nano::bootstrap_attempt::process_block (std::shared_ptr<nano::block> const
} }
else else
{ {
nano::unchecked_info info (block_a, known_account_a, 0, nano::signature_verification::unknown); nano::unchecked_info info (block_a, known_account_a, nano::signature_verification::unknown);
node->block_processor.add (info); node->block_processor.add (info);
} }
return stop_pull; return stop_pull;

View file

@ -268,7 +268,7 @@ bool nano::bootstrap_attempt_lazy::process_block_lazy (std::shared_ptr<nano::blo
} }
lazy_block_state_backlog_check (block_a, hash); lazy_block_state_backlog_check (block_a, hash);
lock.unlock (); lock.unlock ();
nano::unchecked_info info (block_a, known_account_a, 0, nano::signature_verification::unknown); nano::unchecked_info info (block_a, known_account_a, nano::signature_verification::unknown);
node->block_processor.add (info); node->block_processor.add (info);
} }
// Force drop lazy bootstrap connection for long bulk_pull // Force drop lazy bootstrap connection for long bulk_pull

View file

@ -4078,7 +4078,7 @@ void nano::json_handler::unchecked_get ()
if (key.hash == hash) if (key.hash == hash)
{ {
nano::unchecked_info const & info (i->second); nano::unchecked_info const & info (i->second);
response_l.put ("modified_timestamp", std::to_string (info.modified)); response_l.put ("modified_timestamp", std::to_string (info.modified ()));
if (json_block_l) if (json_block_l)
{ {
@ -4126,7 +4126,7 @@ void nano::json_handler::unchecked_keys ()
nano::unchecked_info const & info (i->second); nano::unchecked_info const & info (i->second);
entry.put ("key", i->first.key ().to_string ()); entry.put ("key", i->first.key ().to_string ());
entry.put ("hash", info.block->hash ().to_string ()); entry.put ("hash", info.block->hash ().to_string ());
entry.put ("modified_timestamp", std::to_string (info.modified)); entry.put ("modified_timestamp", std::to_string (info.modified ()));
if (json_block_l) if (json_block_l)
{ {
boost::property_tree::ptree block_node_l; boost::property_tree::ptree block_node_l;

View file

@ -566,7 +566,7 @@ std::unique_ptr<nano::container_info_component> nano::collect_container_info (no
void nano::node::process_active (std::shared_ptr<nano::block> const & incoming) void nano::node::process_active (std::shared_ptr<nano::block> const & incoming)
{ {
block_arrival.add (incoming->hash ()); block_arrival.add (incoming->hash ());
block_processor.add (incoming, nano::seconds_since_epoch ()); block_processor.add (incoming);
} }
nano::process_return nano::node::process (nano::block & block_a) nano::process_return nano::node::process (nano::block & block_a)
@ -581,7 +581,7 @@ nano::process_return nano::node::process_local (std::shared_ptr<nano::block> con
// Add block hash as recently arrived to trigger automatic rebroadcast and election // Add block hash as recently arrived to trigger automatic rebroadcast and election
block_arrival.add (block_a->hash ()); block_arrival.add (block_a->hash ());
// Set current time to trigger automatic rebroadcast and election // Set current time to trigger automatic rebroadcast and election
nano::unchecked_info info (block_a, block_a->account (), nano::seconds_since_epoch (), nano::signature_verification::unknown); nano::unchecked_info info (block_a, block_a->account (), nano::signature_verification::unknown);
// Notify block processor to release write lock // Notify block processor to release write lock
block_processor.wait_write (); block_processor.wait_write ();
// Process block // Process block
@ -595,7 +595,7 @@ void nano::node::process_local_async (std::shared_ptr<nano::block> const & block
// Add block hash as recently arrived to trigger automatic rebroadcast and election // Add block hash as recently arrived to trigger automatic rebroadcast and election
block_arrival.add (block_a->hash ()); block_arrival.add (block_a->hash ());
// Set current time to trigger automatic rebroadcast and election // Set current time to trigger automatic rebroadcast and election
nano::unchecked_info info (block_a, block_a->account (), nano::seconds_since_epoch (), nano::signature_verification::unknown); nano::unchecked_info info (block_a, block_a->account (), nano::signature_verification::unknown);
block_processor.add_local (info); block_processor.add_local (info);
} }
@ -950,7 +950,7 @@ void nano::node::unchecked_cleanup ()
{ {
nano::unchecked_key const & key (i->first); nano::unchecked_key const & key (i->first);
nano::unchecked_info const & info (i->second); nano::unchecked_info const & info (i->second);
if ((now - info.modified) > static_cast<uint64_t> (config.unchecked_cutoff_time.count ())) if ((now - info.modified ()) > static_cast<uint64_t> (config.unchecked_cutoff_time.count ()))
{ {
digests.push_back (network.publish_filter.hash (info.block)); digests.push_back (network.publish_filter.hash (info.block));
cleaning_list.push_back (key); cleaning_list.push_back (key);

View file

@ -1,5 +1,6 @@
#include <nano/lib/locks.hpp> #include <nano/lib/locks.hpp>
#include <nano/lib/threading.hpp> #include <nano/lib/threading.hpp>
#include <nano/lib/timer.hpp>
#include <nano/node/unchecked_map.hpp> #include <nano/node/unchecked_map.hpp>
#include <nano/secure/store.hpp> #include <nano/secure/store.hpp>
@ -96,7 +97,7 @@ nano::unchecked_map::item_visitor::item_visitor (unchecked_map & unchecked, nano
void nano::unchecked_map::item_visitor::operator() (insert const & item) void nano::unchecked_map::item_visitor::operator() (insert const & item)
{ {
auto const & [dependency, info] = item; auto const & [dependency, info] = item;
unchecked.store.unchecked.put (transaction, dependency, info); unchecked.store.unchecked.put (transaction, dependency, { info.block, info.account, info.verified });
} }
void nano::unchecked_map::item_visitor::operator() (query const & item) void nano::unchecked_map::item_visitor::operator() (query const & item)

View file

@ -354,16 +354,16 @@ nano::account const & nano::pending_key::key () const
return account; return account;
} }
nano::unchecked_info::unchecked_info (std::shared_ptr<nano::block> const & block_a, nano::account const & account_a, uint64_t modified_a, nano::signature_verification verified_a) : nano::unchecked_info::unchecked_info (std::shared_ptr<nano::block> const & block_a, nano::account const & account_a, nano::signature_verification verified_a) :
block (block_a), block (block_a),
account (account_a), account (account_a),
modified (modified_a), modified_m (nano::seconds_since_epoch ()),
verified (verified_a) verified (verified_a)
{ {
} }
nano::unchecked_info::unchecked_info (std::shared_ptr<nano::block> const & block) : nano::unchecked_info::unchecked_info (std::shared_ptr<nano::block> const & block) :
unchecked_info{ block, block->account (), nano::seconds_since_epoch (), nano::signature_verification::unknown } unchecked_info{ block, block->account (), nano::signature_verification::unknown }
{ {
} }
@ -372,7 +372,7 @@ void nano::unchecked_info::serialize (nano::stream & stream_a) const
debug_assert (block != nullptr); debug_assert (block != nullptr);
nano::serialize_block (stream_a, *block); nano::serialize_block (stream_a, *block);
nano::write (stream_a, account.bytes); nano::write (stream_a, account.bytes);
nano::write (stream_a, modified); nano::write (stream_a, modified_m);
nano::write (stream_a, verified); nano::write (stream_a, verified);
} }
@ -385,7 +385,7 @@ bool nano::unchecked_info::deserialize (nano::stream & stream_a)
try try
{ {
nano::read (stream_a, account.bytes); nano::read (stream_a, account.bytes);
nano::read (stream_a, modified); nano::read (stream_a, modified_m);
nano::read (stream_a, verified); nano::read (stream_a, verified);
} }
catch (std::runtime_error const &) catch (std::runtime_error const &)
@ -396,6 +396,11 @@ bool nano::unchecked_info::deserialize (nano::stream & stream_a)
return error; return error;
} }
uint64_t nano::unchecked_info::modified () const
{
return modified_m;
}
nano::endpoint_key::endpoint_key (std::array<uint8_t, 16> const & address_a, uint16_t port_a) : nano::endpoint_key::endpoint_key (std::array<uint8_t, 16> const & address_a, uint16_t port_a) :
address (address_a), network_port (boost::endian::native_to_big (port_a)) address (address_a), network_port (boost::endian::native_to_big (port_a))
{ {

View file

@ -199,14 +199,19 @@ class unchecked_info final
{ {
public: public:
unchecked_info () = default; unchecked_info () = default;
unchecked_info (std::shared_ptr<nano::block> const &, nano::account const &, uint64_t, nano::signature_verification = nano::signature_verification::unknown); unchecked_info (std::shared_ptr<nano::block> const &, nano::account const &, nano::signature_verification = nano::signature_verification::unknown);
unchecked_info (std::shared_ptr<nano::block> const &); unchecked_info (std::shared_ptr<nano::block> const &);
void serialize (nano::stream &) const; void serialize (nano::stream &) const;
bool deserialize (nano::stream &); bool deserialize (nano::stream &);
uint64_t modified () const;
std::shared_ptr<nano::block> block; std::shared_ptr<nano::block> block;
nano::account account{}; nano::account account{};
private:
/** Seconds since posix epoch */ /** Seconds since posix epoch */
uint64_t modified{ 0 }; uint64_t modified_m{ 0 };
public:
nano::signature_verification verified{ nano::signature_verification::unknown }; nano::signature_verification verified{ nano::signature_verification::unknown };
}; };

View file

@ -531,7 +531,7 @@ TEST (node, mass_vote_by_hash)
} }
for (auto i (blocks.begin ()), n (blocks.end ()); i != n; ++i) for (auto i (blocks.begin ()), n (blocks.end ()); i != n; ++i)
{ {
system.nodes[0]->block_processor.add (*i, nano::seconds_since_epoch ()); system.nodes[0]->block_processor.add (*i);
} }
} }