9#include <boost/assign/list_of.hpp>
11namespace sysio {
namespace chain {
13 const std::unordered_map<builtin_protocol_feature_t, builtin_protocol_feature_spec, enum_hash<builtin_protocol_feature_t>>
15 boost::assign::map_list_of<builtin_protocol_feature_t, builtin_protocol_feature_spec>
17 "PREACTIVATE_FEATURE",
30 "ONLY_LINK_TO_EXISTING_PERMISSION",
53 "NO_DUPLICATE_DEFERRED_ID",
66 "FIX_LINKAUTH_RESTRICTION",
78 "DISALLOW_EMPTY_PRODUCER_SCHEDULE",
89 "RESTRICT_ACTION_TO_SELF",
102 "ONLY_BILL_FIRST_AUTHORIZER",
168 "WTMSIG_BLOCK_SIGNATURES",
191 "ACTION_RETURN_VALUE",
202 "CONFIGURABLE_WASM_LIMITS2",
215 "BLOCKCHAIN_PARAMETERS",
280 "Unsupported builtin_protocol_feature_t passed to builtin_protocol_feature_codename: ${codename}",
281 (
"codename",
static_cast<uint32_t>(codename)) );
283 return itr->second.codename;
288 flat_set<digest_type>&& dependencies,
290 :description_digest( description_digest )
291 ,dependencies(
std::move(dependencies) )
292 ,subjective_restrictions( restrictions )
293 ,_type( feature_type )
295 switch( feature_type ) {
301 SYS_THROW( protocol_feature_validation_exception,
302 "Unsupported protocol_feature_t passed to constructor: ${type}",
303 (
"type",
static_cast<uint32_t>(feature_type)) );
311 "protocol_feature_activation expects FC to support reflector_init" );
316 SYS_THROW( protocol_feature_validation_exception,
325 flat_set<digest_type>&& dependencies,
332 "Unsupported builtin_protocol_feature_t passed to constructor: ${codename}",
333 (
"codename",
static_cast<uint32_t>(codename)) );
348 SYS_THROW( protocol_feature_validation_exception,
349 "Unsupported builtin protocol feature codename: ${codename}",
373 if( additional_fields ) {
374 for(
const auto& e : *additional_fields ) {
375 if( e.key().compare(
"feature_digest" ) != 0 )
376 mvo( e.key(), e.value() );
380 if( include_subjective_restrictions ) {
383 subjective_restrictions(
"enabled",
enabled );
387 mvo(
"subjective_restrictions", std::move( subjective_restrictions ) );
395 auto add_to_specification = [&specification](
const char* key_name,
auto&&
value ) {
397 obj(
"name", key_name );
398 obj(
"value", std::forward<
decltype(
value)>(
value ) );
399 specification.emplace_back( std::move(obj) );
405 mvo(
"specification", std::move( specification ) );
426 if( itr->earliest_allowed_activation_time > now )
448 "unrecognized protocol feature with digest: ${digest}",
449 (
"digest", feature_digest)
457 const std::function<
bool(
const digest_type&)>& validator
463 for(
const auto&
d : itr->dependencies ) {
464 if( !validator(
d) )
return false;
478 "Unsupported builtin_protocol_feature_t: ${codename}",
479 (
"codename",
static_cast<uint32_t>(codename)) );
481 flat_set<digest_type> dependencies;
482 dependencies.reserve( itr->second.builtin_dependencies.size() );
484 for(
const auto&
d : itr->second.builtin_dependencies ) {
485 dependencies.insert( handle_dependency(
d ) );
488 return {itr->first, itr->second.description_digest, std::move(dependencies), itr->second.subjective_restrictions};
494 "Builtin protocol feature has unsupported builtin_protocol_feature_t: ${codename}",
495 (
"codename",
static_cast<uint32_t>(
f._codename )) );
501 protocol_feature_exception,
502 "builtin protocol feature with codename '${codename}' already added",
503 (
"codename",
f.builtin_feature_codename) );
506 auto feature_digest =
f.digest();
508 const auto& expected_builtin_dependencies = builtin_itr->second.builtin_dependencies;
509 flat_set<builtin_protocol_feature_t> satisfied_builtin_dependencies;
510 satisfied_builtin_dependencies.reserve( expected_builtin_dependencies.size() );
512 for(
const auto&
d :
f.dependencies ) {
515 "builtin protocol feature with codename '${codename}' and digest of ${digest} has a dependency on a protocol feature with digest ${dependency_digest} that is not recognized",
516 (
"codename",
f.builtin_feature_codename)
517 (
"digest", feature_digest)
518 (
"dependency_digest",
d )
521 if( itr->builtin_feature
522 && expected_builtin_dependencies.find( *itr->builtin_feature )
523 != expected_builtin_dependencies.end() )
525 satisfied_builtin_dependencies.insert( *itr->builtin_feature );
529 if( expected_builtin_dependencies.size() > satisfied_builtin_dependencies.size() ) {
530 flat_set<builtin_protocol_feature_t> missing_builtins;
531 missing_builtins.reserve( expected_builtin_dependencies.size() - satisfied_builtin_dependencies.size() );
532 std::set_difference( expected_builtin_dependencies.begin(), expected_builtin_dependencies.end(),
533 satisfied_builtin_dependencies.begin(), satisfied_builtin_dependencies.end(),
538 missing_builtins_with_names.reserve( missing_builtins.size() );
539 for(
const auto& builtin_codename : missing_builtins ) {
542 protocol_feature_exception,
545 missing_builtins_with_names.emplace_back( itr->second.codename );
548 SYS_THROW( protocol_feature_validation_exception,
549 "Not all the builtin dependencies of the builtin protocol feature with codename '${codename}' and digest of ${digest} were satisfied.",
550 (
"missing_dependencies", missing_builtins_with_names)
556 f.description_digest,
558 f.subjective_restrictions.earliest_allowed_activation_time,
559 f.subjective_restrictions.preactivation_required,
560 f.subjective_restrictions.enabled,
564 SYS_ASSERT( res.second, protocol_feature_exception,
565 "builtin protocol feature with codename '${codename}' has a digest of ${digest} but another protocol feature with the same digest has already been added",
566 (
"codename",
f.builtin_feature_codename)(
"digest", feature_digest) );
583 ):_protocol_feature_set(
std::move(pfs) ), _get_deep_mind_logger(get_deep_mind_logger)
599 reset_initialized.cancel();
610 protocol_feature_iterator_exception,
611 "called activation_ordinal() on singular iterator"
614 protocol_feature_iterator_exception,
615 "called activation_ordinal() on end iterator"
623 protocol_feature_iterator_exception,
624 "called activation_block_num() on singular iterator"
627 protocol_feature_iterator_exception,
628 "called activation_block_num() on end iterator"
631 return _pfm->_activated_protocol_features[_index].activation_block_num;
635 SYS_ASSERT( _pfm, protocol_feature_iterator_exception,
"cannot increment singular iterator" );
636 SYS_ASSERT( _index != end_index, protocol_feature_iterator_exception,
"cannot increment end iterator" );
639 if( _index >= _pfm->_activated_protocol_features.size() ) {
647 SYS_ASSERT( _pfm, protocol_feature_iterator_exception,
"cannot decrement singular iterator" );
648 if( _index == end_index ) {
649 SYS_ASSERT( _pfm->_activated_protocol_features.size() > 0,
650 protocol_feature_iterator_exception,
651 "cannot decrement end iterator when no protocol features have been activated"
653 _index = _pfm->_activated_protocol_features.size() - 1;
656 protocol_feature_iterator_exception,
657 "cannot decrement iterator at the beginning of protocol feature activation list" )
678 return const_iterator{
this,
static_cast<std::size_t
>(activation_ordinal)};
729 "unrecognized protocol feature digest: ${digest}", (
"digest", feature_digest) );
733 SYS_ASSERT( last.activation_block_num <= current_block_num,
734 protocol_feature_exception,
735 "last protocol feature activation block num is ${last_activation_block_num} yet "
736 "attempting to activate protocol feature with a current block num of ${current_block_num}"
737 "protocol features is ${last_activation_block_num}",
738 (
"current_block_num", current_block_num)
739 (
"last_activation_block_num", last.activation_block_num)
744 protocol_feature_exception,
745 "invariant failure: encountered non-builtin protocol feature which is not yet supported"
751 "invariant failure while trying to activate feature with digest '${digest}': "
752 "unsupported builtin_protocol_feature_t ${codename}",
753 (
"digest", feature_digest)
758 protocol_feature_exception,
759 "cannot activate already activated builtin feature with digest: ${digest}",
760 (
"digest", feature_digest)
763 if (
auto dm_logger = _get_deep_mind_logger()) {
764 dm_logger->on_activate_feature(*itr);
778 if( e.activation_block_num <= block_num )
break;
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
const ObjectType & get(CompatibleKey &&key) const
An order-preserving dictionary of variants.
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
digest_type digest() const
builtin_protocol_feature_t _codename
static const char * feature_type_string
std::string builtin_feature_codename
builtin_protocol_feature()=default
std::string protocol_feature_type
flat_set< digest_type > dependencies
digest_type description_digest
protocol_feature_base()=default
uint32_t activation_block_num() const
uint32_t activation_ordinal() const
const_iterator & operator++()
const protocol_feature_manager * _pfm
const protocol_feature * get_pointer() const
const_iterator & operator--()
const_iterator cend() const
const_iterator cbegin() const
const_iterator at_activation_ordinal(uint32_t activation_ordinal) const
vector< builtin_protocol_feature_entry > _builtin_protocol_features
void init(chainbase::database &db)
vector< protocol_feature_entry > _activated_protocol_features
bool is_initialized() const
void popped_blocks_to(uint32_t block_num)
const_iterator begin() const
protocol_feature_set _protocol_feature_set
void activate_feature(const digest_type &feature_digest, uint32_t current_block_num)
bool is_builtin_activated(builtin_protocol_feature_t feature_codename, uint32_t current_block_num) const
protocol_feature_manager(protocol_feature_set &&pfs, std::function< deep_mind_handler *()> get_deep_mind_logger)
const_iterator upper_bound(uint32_t block_num) const
friend class const_iterator
const_iterator lower_bound(uint32_t block_num) const
size_t _head_of_builtin_activation_list
vector< protocol_feature_set_type::const_iterator > _recognized_builtin_protocol_features
static builtin_protocol_feature make_default_builtin_protocol_feature(builtin_protocol_feature_t codename, const std::function< digest_type(builtin_protocol_feature_t dependency)> &handle_dependency)
std::optional< digest_type > get_builtin_digest(builtin_protocol_feature_t feature_codename) const
recognized_t is_recognized(const digest_type &feature_digest, time_point now) const
const_iterator find(const K &x) const
bool validate_dependencies(const digest_type &feature_digest, const std::function< bool(const digest_type &)> &validator) const
const protocol_feature & add_feature(const builtin_protocol_feature &f)
const protocol_feature & get_protocol_feature(const digest_type &feature_digest) const
const_iterator end() const
protocol_feature_set_type _recognized_protocol_features
Maintains global state information about consensus protocol rules.
shared_vector< activated_protocol_feature > activated_protocol_features
constexpr bool has_feature_reflector_init_on_unpacked_reflected_types
void pack(Stream &s, const std::deque< T > &value)
scoped_exit< Callback > make_scoped_exit(Callback &&c)
std::vector< fc::variant > variants
const std::unordered_map< builtin_protocol_feature_t, builtin_protocol_feature_spec, enum_hash< builtin_protocol_feature_t > > builtin_protocol_feature_codenames
end_insert_iterator< Container > end_inserter(Container &c)
checksum_type digest_type
builtin_protocol_feature_t
@ no_duplicate_deferred_id
@ configurable_wasm_limits
@ disallow_empty_producer_schedule
@ only_bill_first_authorizer
@ wtmsig_block_signatures
@ fix_linkauth_restriction
@ restrict_action_to_self
@ only_link_to_existing_permission
const char * builtin_protocol_feature_codename(builtin_protocol_feature_t)
static constexpr size_t no_previous
static constexpr uint32_t not_active
uint32_t activation_block_num
bool preactivation_required
digest_type feature_digest
flat_set< digest_type > dependencies
std::optional< builtin_protocol_feature_t > builtin_feature
fc::variant to_variant(bool include_subjective_restrictions=true, fc::mutable_variant_object *additional_fields=nullptr) const
time_point earliest_allowed_activation_time
digest_type description_digest