Remove timestamp count (#3064)
This commit is contained in:
parent
d35800a50a
commit
d8e2a323ce
18 changed files with 21 additions and 187 deletions
|
@ -35,7 +35,6 @@ add_executable(
|
|||
telemetry.cpp
|
||||
toml.cpp
|
||||
timer.cpp
|
||||
timestamp.cpp
|
||||
uint256_union.cpp
|
||||
utility.cpp
|
||||
vote_processor.cpp
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
#include <nano/lib/locks.hpp>
|
||||
#include <nano/lib/numbers.hpp>
|
||||
#include <nano/lib/timestamp.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
|
||||
TEST (timestamp, now)
|
||||
{
|
||||
nano::timestamp_generator generator;
|
||||
ASSERT_FALSE (nano::timestamp_generator::is_steady);
|
||||
auto before_ms = std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ());
|
||||
auto before = generator.timestamp_from_ms (before_ms);
|
||||
ASSERT_EQ (before_ms, generator.ms_from_timestamp (before));
|
||||
auto now = generator.now ();
|
||||
auto after_ms = std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ());
|
||||
auto after (generator.timestamp_from_ms (after_ms));
|
||||
ASSERT_EQ (after_ms, generator.ms_from_timestamp (after));
|
||||
ASSERT_LE (before, now);
|
||||
ASSERT_LE (now, after);
|
||||
}
|
||||
|
||||
TEST (timestamp, basic)
|
||||
{
|
||||
nano::timestamp_generator generator;
|
||||
auto one = generator.now ();
|
||||
ASSERT_NE (0, generator.mask_time (one));
|
||||
auto two = generator.now ();
|
||||
ASSERT_NE (0, generator.mask_time (two));
|
||||
ASSERT_LT (one, two);
|
||||
}
|
||||
|
||||
TEST (timestamp, count)
|
||||
{
|
||||
nano::timestamp_generator generator;
|
||||
auto one = generator.now ();
|
||||
auto two = generator.now ();
|
||||
while (generator.mask_time (one) != generator.mask_time (two))
|
||||
{
|
||||
one = two;
|
||||
two = generator.now ();
|
||||
}
|
||||
ASSERT_EQ (one + 1, two);
|
||||
}
|
||||
|
||||
TEST (timestamp, parallel)
|
||||
{
|
||||
auto constexpr thread_count = 100;
|
||||
auto iteration_count = 1000;
|
||||
std::mutex mutex;
|
||||
std::unordered_set<uint64_t> timestamps;
|
||||
timestamps.reserve (thread_count * iteration_count);
|
||||
nano::timestamp_generator generator;
|
||||
std::vector<std::thread> threads;
|
||||
for (auto i = 0; i < thread_count; ++i)
|
||||
{
|
||||
threads.emplace_back ([×tamps, &generator, &mutex, &iteration_count]() {
|
||||
for (auto i = 0; i < iteration_count; ++i)
|
||||
{
|
||||
auto stamp = generator.now ();
|
||||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
auto inserted = timestamps.insert (stamp);
|
||||
ASSERT_TRUE (inserted.second);
|
||||
}
|
||||
});
|
||||
}
|
||||
for (auto & i : threads)
|
||||
{
|
||||
i.join ();
|
||||
}
|
||||
}
|
|
@ -208,7 +208,7 @@ TEST (vote_processor, no_broadcast_local)
|
|||
ASSERT_TRUE (node.wallets.reps ().exists (nano::dev_genesis_key.pub));
|
||||
ASSERT_FALSE (node.wallets.reps ().have_half_rep ());
|
||||
// Process a vote
|
||||
auto vote = std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, node.timestamps.now (), std::vector<nano::block_hash>{ send->hash () });
|
||||
auto vote = std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::milliseconds_since_epoch (), std::vector<nano::block_hash>{ send->hash () });
|
||||
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote));
|
||||
// Make sure the vote was processed
|
||||
auto election (node.active.election (send->qualified_root ()));
|
||||
|
@ -241,7 +241,7 @@ TEST (vote_processor, no_broadcast_local)
|
|||
ASSERT_EQ (node.config.vote_minimum, node.weight (nano::dev_genesis_key.pub));
|
||||
node.block_confirm (send2);
|
||||
// Process a vote
|
||||
auto vote2 = std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, node.timestamps.now (), std::vector<nano::block_hash>{ send2->hash () });
|
||||
auto vote2 = std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::milliseconds_since_epoch (), std::vector<nano::block_hash>{ send2->hash () });
|
||||
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote2));
|
||||
// Make sure the vote was processed
|
||||
auto election2 (node.active.election (send2->qualified_root ()));
|
||||
|
@ -275,7 +275,7 @@ TEST (vote_processor, no_broadcast_local)
|
|||
ASSERT_TRUE (node.wallets.reps ().exists (nano::dev_genesis_key.pub));
|
||||
ASSERT_TRUE (node.wallets.reps ().have_half_rep ());
|
||||
// Process a vote
|
||||
auto vote3 = std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, node.timestamps.now (), std::vector<nano::block_hash>{ open->hash () });
|
||||
auto vote3 = std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::milliseconds_since_epoch (), std::vector<nano::block_hash>{ open->hash () });
|
||||
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote3));
|
||||
// Make sure the vote was processed
|
||||
auto election3 (node.active.election (open->qualified_root ()));
|
||||
|
|
|
@ -72,9 +72,6 @@ add_library(
|
|||
threading.cpp
|
||||
timer.hpp
|
||||
timer.cpp
|
||||
timestamp_fwd.hpp
|
||||
timestamp.hpp
|
||||
timestamp.cpp
|
||||
tomlconfig.hpp
|
||||
tomlconfig.cpp
|
||||
utility.hpp
|
||||
|
|
|
@ -97,4 +97,14 @@ private:
|
|||
unsigned measurements{ 0 };
|
||||
void update_ticks ();
|
||||
};
|
||||
|
||||
inline uint64_t milliseconds_since_epoch ()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ()).count ();
|
||||
}
|
||||
|
||||
inline uint64_t seconds_since_epoch ()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::seconds> (std::chrono::system_clock::now ().time_since_epoch ()).count ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
|
||||
namespace nano
|
||||
{
|
||||
/**
|
||||
* Returns seconds passed since unix epoch (posix time)
|
||||
*/
|
||||
inline uint64_t seconds_since_epoch ()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::seconds> (std::chrono::system_clock::now ().time_since_epoch ()).count ();
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a unique 64-bit timestamp each time timestamp_now is called.
|
||||
The upper 44-bits are the number of milliseconds since unix epoch
|
||||
The lower 20 bits are a monotonically increasing counter from 0, each millisecond
|
||||
*/
|
||||
|
||||
template <typename CLOCK>
|
||||
class timestamp_generator_base
|
||||
{
|
||||
public:
|
||||
// If CLOCK::is_steady, this class will be a steady
|
||||
static bool constexpr is_steady = CLOCK::is_steady;
|
||||
|
||||
static uint64_t mask_time (uint64_t timestamp)
|
||||
{
|
||||
auto result = timestamp & time_mask;
|
||||
return result;
|
||||
}
|
||||
static uint64_t mask_count (uint64_t timestamp)
|
||||
{
|
||||
auto result = timestamp & count_mask;
|
||||
return result;
|
||||
}
|
||||
// Return a timestamp based on `ms' the number of milliseconds since the UTC epoch
|
||||
static uint64_t timestamp_from_ms (std::chrono::milliseconds ms)
|
||||
{
|
||||
auto result = static_cast<uint64_t> (ms.count ()) << count_bits;
|
||||
return result;
|
||||
}
|
||||
// Return the number of milliseconds since the UTC epoch, represented in `timestamp'
|
||||
static std::chrono::milliseconds ms_from_timestamp (uint64_t timestamp)
|
||||
{
|
||||
auto result = timestamp >> count_bits;
|
||||
return std::chrono::milliseconds{ result };
|
||||
}
|
||||
// If CLOCK::is_steady, now is guaranteed to produce monotonically increasing timestamps
|
||||
static uint64_t now ()
|
||||
{
|
||||
uint64_t stored;
|
||||
uint64_t result;
|
||||
do
|
||||
{
|
||||
stored = last.load ();
|
||||
std::chrono::milliseconds delta = std::chrono::duration_cast<std::chrono::milliseconds> (CLOCK::now ().time_since_epoch ());
|
||||
auto now_l = timestamp_from_ms (delta);
|
||||
// If `delta` hasn't changed since the last call, increment the counter, otherwise use the current value with a zero counter.
|
||||
result = mask_time (stored) == now_l ? stored + 1 : now_l;
|
||||
} while (!last.compare_exchange_weak (stored, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static inline std::atomic<uint64_t> last{ 0 };
|
||||
static int constexpr time_bits{ 44 }; // 44 bits for milliseconds = 17,592,186,044,416 ~ 545 years.
|
||||
static int constexpr count_bits{ 20 }; // 20-bit monotonic counter, 1,048,576 samples per ms
|
||||
static_assert (time_bits + count_bits == 64);
|
||||
static uint64_t constexpr time_mask{ ~0ULL << count_bits }; // Portion associated with timer
|
||||
static uint64_t constexpr count_mask{ ~0ULL >> time_bits }; // Portion associated with counter
|
||||
};
|
||||
using timestamp_generator = timestamp_generator_base<std::chrono::system_clock>;
|
||||
} // namespace nano
|
|
@ -1,10 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace nano
|
||||
{
|
||||
template <typename>
|
||||
class timestamp_generator_base;
|
||||
using timestamp_generator = timestamp_generator_base<std::chrono::system_clock>;
|
||||
}
|
|
@ -24,7 +24,7 @@ confirmation_height_processor (confirmation_height_processor_a),
|
|||
node (node_a),
|
||||
multipliers_cb (20, 1.),
|
||||
trended_active_multiplier (1.0),
|
||||
generator (node_a.timestamps, node_a.config, node_a.ledger, node_a.wallets, node_a.vote_processor, node_a.history, node_a.network, node_a.stats),
|
||||
generator (node_a.config, node_a.ledger, node_a.wallets, node_a.vote_processor, node_a.history, node_a.network, node_a.stats),
|
||||
check_all_elections_period (node_a.network_params.network.is_dev_network () ? 10ms : 5s),
|
||||
election_time_to_live (node_a.network_params.network.is_dev_network () ? 0s : 2s),
|
||||
prioritized_cutoff (std::max<size_t> (1, node_a.config.active_elections_size / 10)),
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <nano/lib/alarm.hpp>
|
||||
#include <nano/lib/config.hpp>
|
||||
#include <nano/lib/stats.hpp>
|
||||
#include <nano/lib/timestamp.hpp>
|
||||
#include <nano/lib/work.hpp>
|
||||
#include <nano/lib/worker.hpp>
|
||||
#include <nano/node/active_transactions.hpp>
|
||||
|
@ -158,7 +157,6 @@ public:
|
|||
bool init_error () const;
|
||||
bool epoch_upgrader (nano::private_key const &, nano::epoch, uint64_t, uint64_t);
|
||||
std::pair<uint64_t, decltype (nano::ledger::bootstrap_weights)> get_bootstrap_weights () const;
|
||||
nano::timestamp_generator timestamps;
|
||||
nano::worker worker;
|
||||
nano::write_database_queue write_database_queue;
|
||||
boost::asio::io_context & io_ctx;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <nano/lib/stats.hpp>
|
||||
#include <nano/lib/threading.hpp>
|
||||
#include <nano/lib/timestamp.hpp>
|
||||
#include <nano/node/active_transactions.hpp>
|
||||
#include <nano/node/common.hpp>
|
||||
#include <nano/node/network.hpp>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <nano/lib/locks.hpp>
|
||||
#include <nano/lib/numbers.hpp>
|
||||
#include <nano/lib/timestamp_fwd.hpp>
|
||||
#include <nano/node/transport/transport.hpp>
|
||||
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
|
|
|
@ -111,9 +111,8 @@ std::unique_ptr<nano::container_info_component> nano::collect_container_info (na
|
|||
return composite;
|
||||
}
|
||||
|
||||
nano::vote_generator::vote_generator (nano::timestamp_generator & timestamps_a, nano::node_config const & config_a, nano::ledger & ledger_a, nano::wallets & wallets_a, nano::vote_processor & vote_processor_a, nano::local_vote_history & history_a, nano::network & network_a, nano::stat & stats_a) :
|
||||
nano::vote_generator::vote_generator (nano::node_config const & config_a, nano::ledger & ledger_a, nano::wallets & wallets_a, nano::vote_processor & vote_processor_a, nano::local_vote_history & history_a, nano::network & network_a, nano::stat & stats_a) :
|
||||
config (config_a),
|
||||
timestamps{ timestamps_a },
|
||||
ledger (ledger_a),
|
||||
wallets (wallets_a),
|
||||
vote_processor (vote_processor_a),
|
||||
|
@ -282,7 +281,7 @@ void nano::vote_generator::vote (std::vector<nano::block_hash> const & hashes_a,
|
|||
debug_assert (hashes_a.size () == roots_a.size ());
|
||||
std::vector<std::shared_ptr<nano::vote>> votes_l;
|
||||
wallets.foreach_representative ([this, &hashes_a, &votes_l](nano::public_key const & pub_a, nano::raw_key const & prv_a) {
|
||||
votes_l.emplace_back (std::make_shared<nano::vote> (pub_a, prv_a, timestamps.now (), hashes_a));
|
||||
votes_l.emplace_back (std::make_shared<nano::vote> (pub_a, prv_a, nano::milliseconds_since_epoch (), hashes_a));
|
||||
});
|
||||
for (auto const & vote_l : votes_l)
|
||||
{
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <nano/lib/locks.hpp>
|
||||
#include <nano/lib/numbers.hpp>
|
||||
#include <nano/lib/timestamp_fwd.hpp>
|
||||
#include <nano/lib/utility.hpp>
|
||||
#include <nano/node/wallet.hpp>
|
||||
#include <nano/secure/common.hpp>
|
||||
|
@ -87,7 +86,7 @@ private:
|
|||
using request_t = std::pair<std::vector<candidate_t>, std::shared_ptr<nano::transport::channel>>;
|
||||
|
||||
public:
|
||||
vote_generator (nano::timestamp_generator & timestamps_a, nano::node_config const & config_a, nano::ledger & ledger_a, nano::wallets & wallets_a, nano::vote_processor & vote_processor_a, nano::local_vote_history & history_a, nano::network & network_a, nano::stat & stats_a);
|
||||
vote_generator (nano::node_config const & config_a, nano::ledger & ledger_a, nano::wallets & wallets_a, nano::vote_processor & vote_processor_a, nano::local_vote_history & history_a, nano::network & network_a, nano::stat & stats_a);
|
||||
/** Queue items for vote generation, or broadcast votes already in cache */
|
||||
void add (nano::root const &, nano::block_hash const &);
|
||||
/** Queue blocks for vote generation, returning the number of successful candidates.*/
|
||||
|
@ -103,7 +102,6 @@ private:
|
|||
void broadcast_action (std::shared_ptr<nano::vote> const &) const;
|
||||
std::function<void(std::shared_ptr<nano::vote> const &, std::shared_ptr<nano::transport::channel> &)> reply_action; // must be set only during initialization by using set_reply_action
|
||||
nano::node_config const & config;
|
||||
nano::timestamp_generator & timestamps;
|
||||
nano::ledger & ledger;
|
||||
nano::wallets & wallets;
|
||||
nano::vote_processor & vote_processor;
|
||||
|
|
|
@ -447,11 +447,10 @@ std::string from_topic (nano::websocket::topic topic_a)
|
|||
|
||||
void nano::websocket::session::send_ack (std::string action_a, std::string id_a)
|
||||
{
|
||||
auto milli_since_epoch = std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ()).count ();
|
||||
nano::websocket::message msg (nano::websocket::topic::ack);
|
||||
boost::property_tree::ptree & message_l = msg.contents;
|
||||
message_l.add ("ack", action_a);
|
||||
message_l.add ("time", std::to_string (milli_since_epoch));
|
||||
message_l.add ("time", std::to_string (nano::milliseconds_since_epoch ()));
|
||||
if (!id_a.empty ())
|
||||
{
|
||||
message_l.add ("id", id_a);
|
||||
|
@ -915,12 +914,9 @@ nano::websocket::message nano::websocket::message_builder::new_block_arrived (na
|
|||
|
||||
void nano::websocket::message_builder::set_common_fields (nano::websocket::message & message_a)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
auto milli_since_epoch = std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ()).count ();
|
||||
|
||||
// Common message information
|
||||
message_a.contents.add ("topic", from_topic (message_a.topic));
|
||||
message_a.contents.add ("time", std::to_string (milli_since_epoch));
|
||||
message_a.contents.add ("time", std::to_string (nano::milliseconds_since_epoch ()));
|
||||
}
|
||||
|
||||
std::string nano::websocket::message::to_string () const
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <nano/lib/config.hpp>
|
||||
#include <nano/lib/rep_weights.hpp>
|
||||
#include <nano/lib/threading.hpp>
|
||||
#include <nano/lib/timestamp.hpp>
|
||||
#include <nano/lib/timer.hpp>
|
||||
#include <nano/secure/blockstore.hpp>
|
||||
#include <nano/secure/buffer.hpp>
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <nano/lib/rep_weights.hpp>
|
||||
#include <nano/lib/stats.hpp>
|
||||
#include <nano/lib/timestamp.hpp>
|
||||
#include <nano/lib/utility.hpp>
|
||||
#include <nano/lib/work.hpp>
|
||||
#include <nano/secure/blockstore.hpp>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <nano/lib/rep_weights.hpp>
|
||||
#include <nano/lib/timer.hpp>
|
||||
#include <nano/secure/common.hpp>
|
||||
|
||||
#include <map>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue