37 PermissionToAuthorityFunc permission_to_authority;
38 const std::function<void()>& checktime;
40 flat_set<permission_level> provided_permissions;
48 const flat_set<public_key_type>& provided_keys,
49 const flat_set<permission_level>& provided_permissions,
51 const std::function<
void()>& checktime
53 :permission_to_authority(permission_to_authority)
54 ,checktime( checktime )
55 ,provided_keys(provided_keys.begin(), provided_keys.end())
56 ,provided_permissions(provided_permissions)
57 ,_used_keys(provided_keys.size(), false)
58 ,provided_delay(provided_delay)
59 ,recursion_depth_limit(recursion_depth_limit)
61 SYS_ASSERT(
static_cast<bool>(checktime), authorization_exception,
"checktime cannot be empty" );
78 provided_delay =
delay;
81 provided_delay = override_provided_delay;
83 return satisfied( permission, cached_perms );
89 if( cached_perms ==
nullptr )
90 cached_perms = initialize_permission_cache( cached_permissions );
92 weight_tally_visitor
visitor(*
this, *cached_perms, 0);
96 template<
typename AuthorityType>
103 provided_delay =
delay;
106 provided_delay = override_provided_delay;
111 template<
typename AuthorityType>
115 if( cached_perms ==
nullptr )
116 cached_perms = initialize_permission_cache( cached_permissions );
121 bool all_keys_used()
const {
return boost::algorithm::all_of_equal(_used_keys,
true); }
125 return {range.begin(), range.end()};
129 return {range.begin(), range.end()};
132 static std::optional<permission_cache_status>
136 auto itr = permissions.find( level );
137 if( itr != permissions.end() )
141 if( itr != permissions.end() )
144 return std::optional<permission_cache_status>();
149 for(
const auto&
p : provided_permissions ) {
152 return &cached_permissions;
155 template<
typename AuthorityType>
165 weight_tally_visitor visitor(*
this, cached_permissions, depth);
166 auto emplace_permission = [&permissions, &visitor](
int priority,
const auto& mp) {
168 std::make_tuple(mp.weight, priority),
175 permissions.reserve(authority.waits.size() + authority.keys.size() + authority.accounts.size());
176 std::for_each(authority.accounts.begin(), authority.accounts.end(), std::bind(emplace_permission, 1, std::placeholders::_1));
177 std::for_each(authority.keys.begin(), authority.keys.end(), std::bind(emplace_permission, 2, std::placeholders::_1));
178 std::for_each(authority.waits.begin(), authority.waits.end(), std::bind(emplace_permission, 3, std::placeholders::_1));
181 for(
const auto&
p: permissions )
183 if(
p.second() >= authority.threshold ) {
184 KeyReverter.cancel();
190 struct weight_tally_visitor {
200 ,cached_permissions(cached_permissions)
201 ,recursion_depth(recursion_depth)
204 uint32_t operator()(
const wait_weight& permission) {
205 if( checker.provided_delay >=
fc::seconds(permission.wait_sec) ) {
206 total_weight += permission.weight;
211 template<
typename KeyWeight,
typename = std::enable_if_t<detail::is_any_of_v<KeyWeight, shared_key_weight, key_weight>>>
212 uint32_t operator()(
const KeyWeight& permission) {
213 auto itr = boost::find( checker.provided_keys, permission.key );
214 if( itr != checker.provided_keys.end() ) {
215 checker._used_keys[itr - checker.provided_keys.begin()] =
true;
216 total_weight += permission.weight;
221 uint32_t operator()(
const permission_level_weight& permission) {
224 if( recursion_depth < checker.recursion_depth_limit ) {
226 typename permission_cache_type::iterator itr = cached_permissions.end();
228 bool propagate_error =
false;
230 auto&& auth = checker.permission_to_authority( permission.permission );
231 propagate_error =
true;
232 auto res = cached_permissions.emplace( permission.permission,
being_evaluated );
234 r = checker.satisfied( std::forward<
decltype(auth)>(auth), cached_permissions, recursion_depth + 1 );
235 }
catch(
const permission_query_exception& ) {
236 if( propagate_error )
243 total_weight += permission.weight;
250 total_weight += permission.weight;
auto make_auth_checker(PermissionToAuthorityFunc &&pta, uint16_t recursion_depth_limit, const flat_set< public_key_type > &provided_keys, const flat_set< permission_level > &provided_permissions=flat_set< permission_level >(), fc::microseconds provided_delay=fc::microseconds(0), const std::function< void()> &_checktime=std::function< void()>())
authority_checker