提交 5056effe 编写于 作者: D Daniel Larimer

chain compiles...

上级 a771c5f8
......@@ -10,16 +10,11 @@ add_library( eos_chain
wasm_interface.cpp
fork_database.cpp
block_schedule.cpp
chain_controller.cpp
get_config.cpp
block_log.cpp
chain_administration_interface.cpp
message_handling_contexts.cpp
chain_controller.cpp
${HEADERS}
)
......
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <eos/chain/chain_administration_interface.hpp>
eosio::chain::chain_administration_interface::~chain_administration_interface() {}
......@@ -13,12 +13,9 @@ fc::variant_object get_config()
{
fc::mutable_variant_object result;
result["KeyPrefix"] = config::KeyPrefix;
result["BlockIntervalSeconds"] = config::BlockIntervalSeconds;
result["MaxBlockSize"] = config::DefaultMaxBlockSize;
result["MaxSecondsUntilExpiration"] = config::DefaultMaxTrxLifetime;
result["ProducerCount"] = config::BlocksPerRound;
result["IrreversibleThresholdPercent"] = config::IrreversibleThresholdPercent;
result["block_interval_ms"] = config::block_interval_ms;
result["producer_count"] = config::producer_count;
/// TODO: add extra config parms
return result;
}
......
......@@ -18,123 +18,124 @@ namespace eosio { namespace chain {
namespace detail {
using meta_permission = static_variant<key_weight, permission_level_weight>;
using meta_permission = static_variant<key_weight, permission_level_weight>;
struct get_weight_visitor {
using result_type = uint32_t;
template<typename Permission>
uint32_t operator()(const Permission& permission) { return permission.weight; }
};
// Orders permissions descending by weight, and breaks ties with Key permissions being less than Account permissions
struct meta_permission_comparator {
bool operator()(const meta_permission& a, const meta_permission& b) const {
get_weight_visitor scale;
if (a.visit(scale) > b.visit(scale)) return true;
return a.contains<key_weight>() && !b.contains<permission_level_weight>();
}
};
using meta_permission_set = boost::container::flat_multiset<meta_permission, meta_permission_comparator>;
}
/**
* @brief This class determines whether a set of signing keys are sufficient to satisfy an authority or not
*
* To determine whether an authority is satisfied or not, we first determine which keys have approved of a message, and
* then determine whether that list of keys is sufficient to satisfy the authority. This class takes a list of keys and
* provides the @ref satisfied method to determine whether that list of keys satisfies a provided authority.
*
* @tparam F A callable which takes a single argument of type @ref AccountPermission and returns the corresponding
* authority
*/
template<typename F>
class authority_checker {
F permission_to_authority;
uint16_t recursion_depth_limit;
vector<public_key_type> signing_keys;
vector<bool> _used_keys;
struct weight_tally_visitor {
struct get_weight_visitor {
using result_type = uint32_t;
authority_checker& checker;
uint16_t recursionDepth;
uint32_t totalWeight = 0;
weight_tally_visitor(authority_checker& checker, uint16_t recursionDepth)
: checker(checker), recursionDepth(recursionDepth) {}
template<typename Permission>
uint32_t operator()(const Permission& permission) { return permission.weight; }
};
uint32_t operator()(const key_weight& permission) {
auto itr = boost::find(checker.signing_keys, permission.key);
if (itr != checker.signing_keys.end()) {
checker._used_keys[itr - checker.signing_keys.begin()] = true;
totalWeight += permission.weight;
}
return totalWeight;
}
uint32_t operator()(const permission_level_weight& permission) {
if (recursionDepth < checker.recursion_depth_limit
&& checker.satisfied(permission.permission, recursionDepth + 1))
totalWeight += permission.weight;
return totalWeight;
// Orders permissions descending by weight, and breaks ties with Key permissions being less than Account permissions
struct meta_permission_comparator {
bool operator()(const meta_permission& a, const meta_permission& b) const {
get_weight_visitor scale;
if (a.visit(scale) > b.visit(scale)) return true;
return a.contains<key_weight>() && !b.contains<permission_level_weight>();
}
};
public:
authority_checker(F permission_to_authority, uint16_t recursion_depth_limit, const flat_set<public_key_type>& signing_keys)
: permission_to_authority(permission_to_authority),
recursion_depth_limit(recursion_depth_limit),
signing_keys(signing_keys.begin(), signing_keys.end()),
_used_keys(signing_keys.size(), false)
{}
bool satisfied(const permission_level& permission, uint16_t depth = 0) {
return satisfied(permission_to_authority(permission), depth);
}
template<typename AuthorityType>
bool satisfied(const AuthorityType& authority, uint16_t depth = 0) {
// This check is redundant, since weight_tally_visitor did it too, but I'll leave it here for future-proofing
if (depth > recursion_depth_limit)
using meta_permission_set = boost::container::flat_multiset<meta_permission, meta_permission_comparator>;
} /// namespace detail
/**
* @brief This class determines whether a set of signing keys are sufficient to satisfy an authority or not
*
* To determine whether an authority is satisfied or not, we first determine which keys have approved of a message, and
* then determine whether that list of keys is sufficient to satisfy the authority. This class takes a list of keys and
* provides the @ref satisfied method to determine whether that list of keys satisfies a provided authority.
*
* @tparam F A callable which takes a single argument of type @ref AccountPermission and returns the corresponding
* authority
*/
template<typename F>
class authority_checker {
F permission_to_authority;
uint16_t recursion_depth_limit;
vector<public_key_type> signing_keys;
vector<bool> _used_keys;
struct weight_tally_visitor {
using result_type = uint32_t;
authority_checker& checker;
uint16_t recursionDepth;
uint32_t totalWeight = 0;
weight_tally_visitor(authority_checker& checker, uint16_t recursionDepth)
: checker(checker), recursionDepth(recursionDepth) {}
uint32_t operator()(const key_weight& permission) {
auto itr = boost::find(checker.signing_keys, permission.key);
if (itr != checker.signing_keys.end()) {
checker._used_keys[itr - checker.signing_keys.begin()] = true;
totalWeight += permission.weight;
}
return totalWeight;
}
uint32_t operator()(const permission_level_weight& permission) {
if (recursionDepth < checker.recursion_depth_limit
&& checker.satisfied(permission.permission, recursionDepth + 1))
totalWeight += permission.weight;
return totalWeight;
}
};
public:
authority_checker(F permission_to_authority, uint16_t recursion_depth_limit, const flat_set<public_key_type>& signing_keys)
: permission_to_authority(permission_to_authority),
recursion_depth_limit(recursion_depth_limit),
signing_keys(signing_keys.begin(), signing_keys.end()),
_used_keys(signing_keys.size(), false)
{}
bool satisfied(const permission_level& permission, uint16_t depth = 0) {
return satisfied(permission_to_authority(permission), depth);
}
template<typename AuthorityType>
bool satisfied(const AuthorityType& authority, uint16_t depth = 0) {
// This check is redundant, since weight_tally_visitor did it too, but I'll leave it here for future-proofing
if (depth > recursion_depth_limit)
return false;
// Save the current used keys; if we do not satisfy this authority, the newly used keys aren't actually used
auto KeyReverter = fc::make_scoped_exit([this, keys = _used_keys] () mutable {
_used_keys = keys;
});
// Sort key permissions and account permissions together into a single set of meta_permissions
detail::meta_permission_set permissions;
permissions.insert(authority.keys.begin(), authority.keys.end());
permissions.insert(authority.accounts.begin(), authority.accounts.end());
// Check all permissions, from highest weight to lowest, seeing if signing_keys satisfies them or not
weight_tally_visitor visitor(*this, depth);
for (const auto& permission : permissions)
// If we've got enough weight, to satisfy the authority, return!
if (permission.visit(visitor) >= authority.threshold) {
KeyReverter.cancel();
return true;
}
return false;
}
// Save the current used keys; if we do not satisfy this authority, the newly used keys aren't actually used
auto KeyReverter = fc::make_scoped_exit([this, keys = _used_keys] () mutable {
_used_keys = keys;
});
// Sort key permissions and account permissions together into a single set of meta_permissions
detail::meta_permission_set permissions;
permissions.insert(authority.keys.begin(), authority.keys.end());
permissions.insert(authority.accounts.begin(), authority.accounts.end());
// Check all permissions, from highest weight to lowest, seeing if signing_keys satisfies them or not
weight_tally_visitor visitor(*this, depth);
for (const auto& permission : permissions)
// If we've got enough weight, to satisfy the authority, return!
if (permission.visit(visitor) >= authority.threshold) {
KeyReverter.cancel();
return true;
}
return false;
}
bool all_keys_used() const { return boost::algorithm::all_of_equal(_used_keys, true); }
bool all_keys_used() const { return boost::algorithm::all_of_equal(_used_keys, true); }
flat_set<public_key_type> used_keys() const {
auto range = utilities::FilterDataByMarker(signing_keys, _used_keys, true);
return {range.begin(), range.end()};
}
flat_set<public_key_type> unused_keys() const {
auto range = utilities::FilterDataByMarker(signing_keys, _used_keys, false);
return {range.begin(), range.end()};
}
}; /// authority_checker
flat_set<public_key_type> used_keys() const {
auto range = utilities::FilterDataByMarker(signing_keys, _used_keys, true);
return {range.begin(), range.end()};
template<typename F>
authority_checker<F> make_auth_checker(F&& pta, uint16_t recursion_depth_limit, const flat_set<public_key_type>& signing_keys) {
return authority_checker<F>(std::forward<F>(pta), recursion_depth_limit, signing_keys);
}
flat_set<public_key_type> unused_keys() const {
auto range = utilities::FilterDataByMarker(signing_keys, _used_keys, false);
return {range.begin(), range.end()};
}
};
template<typename F>
authority_checker<F> make_authority_checker(F&& pta, uint16_t recursion_depth_limit, const flat_set<public_key_type>& signing_keys) {
return authority_checker<F>(std::forward<F>(pta), recursion_depth_limit, signing_keys);
}
}} // namespace eosio::chain
} } // namespace eosio::chain
......@@ -177,7 +177,7 @@ namespace eosio { namespace chain {
{
/* TODO: figure out pending trx
auto old_pending = std::move( _pending_transactions );
_pending_tx_session.reset();
_pending_block_session.reset();
auto on_exit = fc::make_scoped_exit( [&](){
for( const auto& t : old_pending ) {
try {
......@@ -233,7 +233,7 @@ namespace eosio { namespace chain {
const dynamic_global_property_object& get_dynamic_global_properties()const;
const producer_object& get_producer(const account_name& ownername)const;
time_point head_block_timestamp() const;
time_point head_block_time()const;
uint32_t head_block_num()const;
block_id_type head_block_id()const;
account_name head_block_producer()const;
......@@ -347,7 +347,7 @@ namespace eosio { namespace chain {
fork_database& _fork_db;
block_log& _block_log;
optional<database::session> _pending_tx_session;
optional<database::session> _pending_block_session;
optional<signed_block> _pending_block;
deque<signed_transaction> _pending_transactions; ///< transactions that are waiting to get added to pending block
uint32_t _pending_transaction_count = 0;
......
......@@ -25,7 +25,8 @@ public:
/// Retrieve the chain_config to use at blockchain start
virtual chain_config get_chain_start_configuration() = 0;
/// Retrieve the first round of block producers
virtual std::array<account_name, config::producer_count> get_chain_start_producers() = 0;
//virtual std::array<account_name, config::producer_count> get_chain_start_producers() = 0;
virtual producer_schedule_type get_chain_start_producers() = 0;
/**
* @brief Install necessary indices and message handlers that chain_controller doesn't know about
......
......@@ -26,8 +26,8 @@ const static int block_interval_ms = 500;
const static uint64_t block_timestamp_epoch = 946684800000ll; // epoch is year 2000.
/** Percentages are fixed point with a denominator of 10,000 */
const static int Percent100 = 10000;
const static int Percent1 = 100;
const static int percent_100 = 10000;
const static int percent_1 = 100;
const static int DefaultPerAuthAccountTimeFrameSeconds = 18;
const static int DefaultPerAuthAccount = 1800;
......@@ -48,15 +48,15 @@ const static uint32_t ProducersAuthorityThreshold = 14;
/**
* The number of sequential blocks produced by a single producer
*/
const static int producer_repeitions = 4;
const static int producer_repititions = 4;
/**
* The number of blocks produced per round is based upon all producers having a chance
* to produce all of their consecutive blocks.
*/
const static int blocks_per_round = producer_count * producer_repeitions;
const static int blocks_per_round = producer_count * producer_repititions;
const static int irreversible_threshold_percent= 70 * Percent1;
const static int irreversible_threshold_percent= 70 * percent_1;
const static int max_producer_votes = 30;
const static auto staked_balance_cooldown_sec = fc::days(3).to_seconds();
......@@ -64,5 +64,5 @@ const static auto staked_balance_cooldown_sec = fc::days(3).to_seconds();
template<typename Number>
Number EOS_PERCENT(Number value, int percentage) {
return value * percentage / eosio::config::Percent100;
return value * percentage / eosio::config::percent_100;
}
......@@ -34,7 +34,7 @@ namespace eosio { namespace chain {
/// The account which is defining its permission requirements
account_name account;
/// The contract which account requires @ref required_permission to invoke
account_name code;
account_name code; /// TODO: rename to scope
/// The message type which account requires @ref required_permission to invoke
/// May be empty; if so, it sets a default @ref required_permission for all messages to @ref code
action_name message_type;
......@@ -42,7 +42,7 @@ namespace eosio { namespace chain {
permission_name required_permission;
};
struct by_message_type;
struct by_action_name;
struct by_permission_name;
using permission_link_index = chainbase::shared_multi_index_container<
permission_link_object,
......@@ -50,7 +50,7 @@ namespace eosio { namespace chain {
ordered_unique<tag<by_id>,
BOOST_MULTI_INDEX_MEMBER(permission_link_object, permission_link_object::id_type, id)
>,
ordered_unique<tag<by_message_type>,
ordered_unique<tag<by_action_name>,
composite_key<permission_link_object,
BOOST_MULTI_INDEX_MEMBER(permission_link_object, account_name, account),
BOOST_MULTI_INDEX_MEMBER(permission_link_object, account_name, code),
......
......@@ -109,7 +109,7 @@ namespace eosio { namespace chain {
return ((head_blocknum/0xffff)*0xffff) + head_blocknum%0xffff;
}
void set_reference_block( const block_id_type& reference_block );
bool verify_reference_block( const block_id_type& reference_block );
bool verify_reference_block( const block_id_type& reference_block )const;
};
/**
......
......@@ -17,7 +17,7 @@ void transaction_header::set_reference_block( const block_id_type& reference_blo
ref_block_prefix = reference_block._hash[1];
}
bool transaction_header::verify_reference_block( const block_id_type& reference_block ) {
bool transaction_header::verify_reference_block( const block_id_type& reference_block )const {
return ref_block_num == (decltype(ref_block_num))fc::endian_reverse_u32(reference_block._hash[0]) &&
ref_block_prefix == (decltype(ref_block_prefix))reference_block._hash[1];
}
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册