460 lines
12 KiB
C++
460 lines
12 KiB
C++
#pragma once
|
|
|
|
#include <nano/crypto/blake2/blake2.h>
|
|
#include <nano/lib/blockbuilders.hpp>
|
|
#include <nano/lib/config.hpp>
|
|
#include <nano/lib/epoch.hpp>
|
|
#include <nano/lib/numbers.hpp>
|
|
#include <nano/lib/object_stream.hpp>
|
|
#include <nano/lib/rep_weights.hpp>
|
|
#include <nano/lib/stats.hpp>
|
|
#include <nano/lib/timer.hpp>
|
|
#include <nano/lib/utility.hpp>
|
|
#include <nano/secure/vote.hpp>
|
|
|
|
#include <boost/iterator/transform_iterator.hpp>
|
|
#include <boost/optional/optional.hpp>
|
|
#include <boost/property_tree/ptree_fwd.hpp>
|
|
#include <boost/variant/variant.hpp>
|
|
|
|
#include <array>
|
|
#include <unordered_map>
|
|
|
|
namespace boost
|
|
{
|
|
template <>
|
|
struct hash<::nano::uint256_union>
|
|
{
|
|
size_t operator() (::nano::uint256_union const & value_a) const
|
|
{
|
|
return std::hash<::nano::uint256_union> () (value_a);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct hash<::nano::block_hash>
|
|
{
|
|
size_t operator() (::nano::block_hash const & value_a) const
|
|
{
|
|
return std::hash<::nano::block_hash> () (value_a);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct hash<::nano::hash_or_account>
|
|
{
|
|
size_t operator() (::nano::hash_or_account const & data_a) const
|
|
{
|
|
return std::hash<::nano::hash_or_account> () (data_a);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct hash<::nano::public_key>
|
|
{
|
|
size_t operator() (::nano::public_key const & value_a) const
|
|
{
|
|
return std::hash<::nano::public_key> () (value_a);
|
|
}
|
|
};
|
|
template <>
|
|
struct hash<::nano::uint512_union>
|
|
{
|
|
size_t operator() (::nano::uint512_union const & value_a) const
|
|
{
|
|
return std::hash<::nano::uint512_union> () (value_a);
|
|
}
|
|
};
|
|
template <>
|
|
struct hash<::nano::qualified_root>
|
|
{
|
|
size_t operator() (::nano::qualified_root const & value_a) const
|
|
{
|
|
return std::hash<::nano::qualified_root> () (value_a);
|
|
}
|
|
};
|
|
template <>
|
|
struct hash<::nano::root>
|
|
{
|
|
size_t operator() (::nano::root const & value_a) const
|
|
{
|
|
return std::hash<::nano::root> () (value_a);
|
|
}
|
|
};
|
|
}
|
|
namespace nano
|
|
{
|
|
/**
|
|
* A key pair. The private key is generated from the random pool, or passed in
|
|
* as a hex string. The public key is derived using ed25519.
|
|
*/
|
|
class keypair
|
|
{
|
|
public:
|
|
keypair ();
|
|
keypair (std::string const &);
|
|
keypair (nano::raw_key &&);
|
|
nano::public_key pub;
|
|
nano::raw_key prv;
|
|
};
|
|
|
|
/**
|
|
* Latest information about an account
|
|
*/
|
|
class account_info final
|
|
{
|
|
public:
|
|
account_info () = default;
|
|
account_info (nano::block_hash const &, nano::account const &, nano::block_hash const &, nano::amount const &, nano::seconds_t modified, uint64_t, epoch);
|
|
bool deserialize (nano::stream &);
|
|
bool operator== (nano::account_info const &) const;
|
|
bool operator!= (nano::account_info const &) const;
|
|
size_t db_size () const;
|
|
nano::epoch epoch () const;
|
|
nano::block_hash head{ 0 };
|
|
nano::account representative{};
|
|
nano::block_hash open_block{ 0 };
|
|
nano::amount balance{ 0 };
|
|
/** Seconds since posix epoch */
|
|
nano::seconds_t modified{ 0 };
|
|
uint64_t block_count{ 0 };
|
|
nano::epoch epoch_m{ nano::epoch::epoch_0 };
|
|
};
|
|
|
|
/**
|
|
* Information on an uncollected send
|
|
*/
|
|
class pending_info final
|
|
{
|
|
public:
|
|
pending_info () = default;
|
|
pending_info (nano::account const &, nano::amount const &, nano::epoch);
|
|
size_t db_size () const;
|
|
bool deserialize (nano::stream &);
|
|
bool operator== (nano::pending_info const &) const;
|
|
nano::account source{};
|
|
nano::amount amount{ 0 };
|
|
nano::epoch epoch{ nano::epoch::epoch_0 };
|
|
};
|
|
class pending_key final
|
|
{
|
|
public:
|
|
pending_key () = default;
|
|
pending_key (nano::account const &, nano::block_hash const &);
|
|
bool deserialize (nano::stream &);
|
|
bool operator== (nano::pending_key const &) const;
|
|
nano::account const & key () const;
|
|
nano::account account{};
|
|
nano::block_hash hash{ 0 };
|
|
};
|
|
|
|
class endpoint_key final
|
|
{
|
|
public:
|
|
endpoint_key () = default;
|
|
|
|
/*
|
|
* @param address_a This should be in network byte order
|
|
* @param port_a This should be in host byte order
|
|
*/
|
|
endpoint_key (std::array<uint8_t, 16> const & address_a, uint16_t port_a);
|
|
|
|
/*
|
|
* @return The ipv6 address in network byte order
|
|
*/
|
|
std::array<uint8_t, 16> const & address_bytes () const;
|
|
|
|
/*
|
|
* @return The port in host byte order
|
|
*/
|
|
uint16_t port () const;
|
|
|
|
private:
|
|
// Both stored internally in network byte order
|
|
std::array<uint8_t, 16> address;
|
|
uint16_t network_port{ 0 };
|
|
};
|
|
|
|
enum class no_value
|
|
{
|
|
dummy
|
|
};
|
|
|
|
class unchecked_key final
|
|
{
|
|
public:
|
|
unchecked_key () = default;
|
|
explicit unchecked_key (nano::hash_or_account const & dependency);
|
|
unchecked_key (nano::hash_or_account const &, nano::block_hash const &);
|
|
unchecked_key (nano::uint512_union const &);
|
|
bool deserialize (nano::stream &);
|
|
bool operator== (nano::unchecked_key const &) const;
|
|
bool operator< (nano::unchecked_key const &) const;
|
|
nano::block_hash const & key () const;
|
|
nano::block_hash previous{ 0 };
|
|
nano::block_hash hash{ 0 };
|
|
};
|
|
|
|
/**
|
|
* Information on an unchecked block
|
|
*/
|
|
class unchecked_info final
|
|
{
|
|
public:
|
|
unchecked_info () = default;
|
|
unchecked_info (std::shared_ptr<nano::block> const &);
|
|
void serialize (nano::stream &) const;
|
|
bool deserialize (nano::stream &);
|
|
nano::seconds_t modified () const;
|
|
std::shared_ptr<nano::block> block;
|
|
|
|
private:
|
|
/** Seconds since posix epoch */
|
|
uint64_t modified_m{ 0 };
|
|
};
|
|
|
|
class block_info final
|
|
{
|
|
public:
|
|
block_info () = default;
|
|
block_info (nano::account const &, nano::amount const &);
|
|
nano::account account{};
|
|
nano::amount balance{ 0 };
|
|
};
|
|
|
|
class confirmation_height_info final
|
|
{
|
|
public:
|
|
confirmation_height_info () = default;
|
|
confirmation_height_info (uint64_t, nano::block_hash const &);
|
|
|
|
void serialize (nano::stream &) const;
|
|
bool deserialize (nano::stream &);
|
|
|
|
/** height of the cemented frontier */
|
|
uint64_t height{};
|
|
|
|
/** hash of the highest cemented block, the cemented/confirmed frontier */
|
|
nano::block_hash frontier{};
|
|
};
|
|
|
|
namespace confirmation_height
|
|
{
|
|
/** When the uncemented count (block count - cemented count) is less than this use the unbounded processor */
|
|
uint64_t const unbounded_cutoff{ 16384 };
|
|
}
|
|
|
|
enum class vote_code
|
|
{
|
|
invalid, // Vote is not signed correctly
|
|
replay, // Vote does not have the highest timestamp, it's a replay
|
|
vote, // Vote has the highest timestamp
|
|
indeterminate // Unknown if replay or vote
|
|
};
|
|
|
|
enum class block_status
|
|
{
|
|
progress, // Hasn't been seen before, signed correctly
|
|
bad_signature, // Signature was bad, forged or transmission error
|
|
old, // Already seen and was valid
|
|
negative_spend, // Malicious attempt to spend a negative amount
|
|
fork, // Malicious fork based on previous
|
|
unreceivable, // Source block doesn't exist, has already been received, or requires an account upgrade (epoch blocks)
|
|
gap_previous, // Block marked as previous is unknown
|
|
gap_source, // Block marked as source is unknown
|
|
gap_epoch_open_pending, // Block marked as pending blocks required for epoch open block are unknown
|
|
opened_burn_account, // Block attempts to open the burn account
|
|
balance_mismatch, // Balance and amount delta don't match
|
|
representative_mismatch, // Representative is changed when it is not allowed
|
|
block_position, // This block cannot follow the previous block
|
|
insufficient_work // Insufficient work for this block, even though it passed the minimal validation
|
|
};
|
|
|
|
std::string_view to_string (block_status);
|
|
nano::stat::detail to_stat_detail (block_status);
|
|
|
|
enum class tally_result
|
|
{
|
|
vote,
|
|
changed,
|
|
confirm
|
|
};
|
|
|
|
class network_params;
|
|
|
|
/** Genesis keys and ledger constants for network variants */
|
|
class ledger_constants
|
|
{
|
|
public:
|
|
ledger_constants (nano::work_thresholds & work, nano::networks network_a);
|
|
nano::work_thresholds & work;
|
|
nano::keypair zero_key;
|
|
nano::account nano_beta_account;
|
|
nano::account nano_live_account;
|
|
nano::account nano_test_account;
|
|
std::shared_ptr<nano::block> nano_dev_genesis;
|
|
std::shared_ptr<nano::block> nano_beta_genesis;
|
|
std::shared_ptr<nano::block> nano_live_genesis;
|
|
std::shared_ptr<nano::block> nano_test_genesis;
|
|
std::shared_ptr<nano::block> genesis;
|
|
nano::uint128_t genesis_amount;
|
|
nano::account burn_account;
|
|
nano::account nano_dev_final_votes_canary_account;
|
|
nano::account nano_beta_final_votes_canary_account;
|
|
nano::account nano_live_final_votes_canary_account;
|
|
nano::account nano_test_final_votes_canary_account;
|
|
nano::account final_votes_canary_account;
|
|
uint64_t nano_dev_final_votes_canary_height;
|
|
uint64_t nano_beta_final_votes_canary_height;
|
|
uint64_t nano_live_final_votes_canary_height;
|
|
uint64_t nano_test_final_votes_canary_height;
|
|
uint64_t final_votes_canary_height;
|
|
nano::epochs epochs;
|
|
};
|
|
|
|
namespace dev
|
|
{
|
|
extern nano::keypair genesis_key;
|
|
extern nano::network_params network_params;
|
|
extern nano::ledger_constants & constants;
|
|
extern std::shared_ptr<nano::block> & genesis;
|
|
}
|
|
|
|
/** Constants which depend on random values (always used as singleton) */
|
|
class hardened_constants
|
|
{
|
|
public:
|
|
static hardened_constants & get ();
|
|
|
|
nano::account not_an_account;
|
|
nano::uint128_union random_128;
|
|
|
|
private:
|
|
hardened_constants ();
|
|
};
|
|
|
|
/** Node related constants whose value depends on the active network */
|
|
class node_constants
|
|
{
|
|
public:
|
|
node_constants (nano::network_constants & network_constants);
|
|
std::chrono::minutes backup_interval;
|
|
std::chrono::seconds search_pending_interval;
|
|
std::chrono::minutes unchecked_cleaning_interval;
|
|
std::chrono::milliseconds process_confirmed_interval;
|
|
|
|
/** The maximum amount of samples for a 2 week period on live or 1 day on beta */
|
|
uint64_t max_weight_samples;
|
|
uint64_t weight_period;
|
|
};
|
|
|
|
/** Voting related constants whose value depends on the active network */
|
|
class voting_constants
|
|
{
|
|
public:
|
|
voting_constants (nano::network_constants & network_constants);
|
|
size_t const max_cache;
|
|
std::chrono::seconds const delay;
|
|
};
|
|
|
|
/** Port-mapping related constants whose value depends on the active network */
|
|
class portmapping_constants
|
|
{
|
|
public:
|
|
portmapping_constants (nano::network_constants & network_constants);
|
|
// Timeouts are primes so they infrequently happen at the same time
|
|
std::chrono::seconds lease_duration;
|
|
std::chrono::seconds health_check_period;
|
|
};
|
|
|
|
/** Bootstrap related constants whose value depends on the active network */
|
|
class bootstrap_constants
|
|
{
|
|
public:
|
|
bootstrap_constants (nano::network_constants & network_constants);
|
|
uint32_t lazy_max_pull_blocks;
|
|
uint32_t lazy_min_pull_blocks;
|
|
unsigned frontier_retry_limit;
|
|
unsigned lazy_retry_limit;
|
|
unsigned lazy_destinations_retry_limit;
|
|
std::chrono::milliseconds gap_cache_bootstrap_start_interval;
|
|
uint32_t default_frontiers_age_seconds;
|
|
};
|
|
|
|
/** Constants whose value depends on the active network */
|
|
class network_params
|
|
{
|
|
public:
|
|
/** Populate values based on \p network_a */
|
|
network_params (nano::networks network_a);
|
|
|
|
unsigned kdf_work;
|
|
nano::work_thresholds work;
|
|
nano::network_constants network;
|
|
nano::ledger_constants ledger;
|
|
nano::voting_constants voting;
|
|
nano::node_constants node;
|
|
nano::portmapping_constants portmapping;
|
|
nano::bootstrap_constants bootstrap;
|
|
};
|
|
|
|
enum class confirmation_height_mode
|
|
{
|
|
automatic,
|
|
unbounded,
|
|
bounded
|
|
};
|
|
|
|
/* Holds flags for various cacheable data. For most CLI operations caching is unnecessary
|
|
* (e.g getting the cemented block count) so it can be disabled for performance reasons. */
|
|
class generate_cache
|
|
{
|
|
public:
|
|
bool reps = true;
|
|
bool cemented_count = true;
|
|
bool unchecked_count = true;
|
|
bool account_count = true;
|
|
bool block_count = true;
|
|
|
|
void enable_all ();
|
|
};
|
|
|
|
/* Holds an in-memory cache of various counts */
|
|
class ledger_cache
|
|
{
|
|
public:
|
|
nano::rep_weights rep_weights;
|
|
std::atomic<uint64_t> cemented_count{ 0 };
|
|
std::atomic<uint64_t> block_count{ 0 };
|
|
std::atomic<uint64_t> pruned_count{ 0 };
|
|
std::atomic<uint64_t> account_count{ 0 };
|
|
std::atomic<bool> final_votes_confirmation_canary{ false };
|
|
};
|
|
|
|
/* Defines the possible states for an election to stop in */
|
|
enum class election_status_type : uint8_t
|
|
{
|
|
ongoing = 0,
|
|
active_confirmed_quorum = 1,
|
|
active_confirmation_height = 2,
|
|
inactive_confirmation_height = 3,
|
|
stopped = 5
|
|
};
|
|
|
|
/* Holds a summary of an election */
|
|
class election_status final
|
|
{
|
|
public:
|
|
std::shared_ptr<nano::block> winner;
|
|
nano::amount tally;
|
|
nano::amount final_tally;
|
|
std::chrono::milliseconds election_end;
|
|
std::chrono::milliseconds election_duration;
|
|
unsigned confirmation_request_count;
|
|
unsigned block_count;
|
|
unsigned voter_count;
|
|
election_status_type type;
|
|
};
|
|
|
|
nano::wallet_id random_wallet_id ();
|
|
}
|