BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
restriction_predicate.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
26 
28 #include "sliced_lists.hxx"
29 
30 namespace graphene { namespace protocol {
31 
33  auto f = typelist::runtime::dispatch(operation::list(), op_type, [&rs](auto t) -> restriction_predicate_function {
34  using Op = typename decltype(t)::type;
35  if (typelist::contains<operation_list_1::list, Op>())
36  return get_restriction_pred_list_1(typelist::index_of<operation_list_1::list, Op>(), std::move(rs));
37  if (typelist::contains<operation_list_2::list, Op>())
38  return get_restriction_pred_list_2(typelist::index_of<operation_list_2::list, Op>(), std::move(rs));
39  if (typelist::contains<operation_list_3::list, Op>())
40  return get_restriction_pred_list_3(typelist::index_of<operation_list_3::list, Op>(), std::move(rs));
41  if (typelist::contains<operation_list_5::list, Op>())
42  return get_restriction_pred_list_5(typelist::index_of<operation_list_5::list, Op>(), std::move(rs));
43  if (typelist::contains<operation_list_6::list, Op>())
44  return get_restriction_pred_list_6(typelist::index_of<operation_list_6::list, Op>(), std::move(rs));
45  if (typelist::contains<operation_list_9::list, Op>())
46  return get_restriction_pred_list_9(typelist::index_of<operation_list_9::list, Op>(), std::move(rs));
47  if (typelist::contains<operation_list_10::list, Op>())
48  return get_restriction_pred_list_10(typelist::index_of<operation_list_10::list, Op>(), std::move(rs));
49  if (typelist::contains<operation_list_11::list, Op>())
50  return get_restriction_pred_list_11(typelist::index_of<operation_list_11::list, Op>(), std::move(rs));
51  if (typelist::contains<unsupported_operations_list::list, Op>())
52  FC_THROW_EXCEPTION( fc::assert_exception, "Unsupported operation detected!" );
53 
54  // Compile time check that we'll never get to the exception below
55  static_assert(typelist::contains<typelist::concat<operation_list_1::list, operation_list_2::list,
61  Op>(), "");
62  FC_THROW_EXCEPTION(fc::assert_exception,
63  "LOGIC ERROR: Operation type not handled by custom authorities implementation. "
64  "Please report this error.");
65  });
66 
67  // Wrap function in a layer that, if the function returns an error, reverses the order of the rejection path. This
68  // is because the order the path is created in, from the top of the call stack to the bottom, is counterintuitive.
69  return [f=std::move(f)](const operation& op) { return f(op).reverse_path(); };
70 }
71 
73  if (success)
74  return *this;
75  const auto reverse_subpaths = [](rejection_indicator& indicator) {
76  if (indicator.is_type<vector<predicate_result>>()) {
77  auto& results = indicator.get<vector<predicate_result>>();
78  for (predicate_result& result : results)
79  result.reverse_path();
80  }
81  };
82  std::reverse(rejection_path.begin(), rejection_path.end());
83  std::for_each(rejection_path.begin(), rejection_path.end(), reverse_subpaths);
84  return *this;
85 }
86 
87 // These are some compile-time tests of the metafunctions and predicate type analysis. They are turned off to make
88 // building faster; they only need to be enabled when making changes in restriction_predicate.hxx
89 #if false
90 static_assert(!is_container<int>, "");
91 static_assert(is_container<vector<int>>, "");
92 static_assert(is_container<flat_set<int>>, "");
93 static_assert(is_container<string>, "");
94 static_assert(is_flat_set<flat_set<int>>, "");
95 static_assert(!is_flat_set<vector<int>>, "");
96 
97 static_assert(predicate_eq<int, int64_t>()(10, 20) == false, "");
98 static_assert(predicate_eq<int, int64_t>()(10, 5) == false, "");
99 static_assert(predicate_eq<int, int64_t>()(10, 10) == true, "");
100 
101 static_assert(predicate_eq<void_t, void_t>::valid == false, "");
102 static_assert(predicate_eq<int, void_t>::valid == false, "");
103 static_assert(predicate_eq<void_t, int64_t>::valid == false, "");
104 static_assert(predicate_eq<int, int64_t>::valid == true, "");
105 static_assert(predicate_eq<long, int64_t>::valid == true, "");
106 static_assert(predicate_eq<vector<bool>, int64_t>::valid == true, "");
107 static_assert(predicate_eq<flat_set<char>, int64_t>::valid == true, "");
108 static_assert(predicate_eq<short, int64_t>::valid == true, "");
109 static_assert(predicate_eq<bool, int64_t>::valid == false, "");
110 static_assert(predicate_eq<int, bool>::valid == false, "");
111 static_assert(predicate_eq<fc::optional<int>, int64_t>::valid == true, "");
112 static_assert(predicate_eq<fc::optional<long>, int64_t>::valid == true, "");
113 static_assert(predicate_eq<fc::optional<long>, void_t>::valid == true, "");
114 static_assert(predicate_eq<flat_set<bool>, flat_set<bool>>::valid == true, "");
115 static_assert(predicate_eq<flat_set<bool>, string>::valid == false, "");
116 static_assert(predicate_eq<string, string>::valid == true, "");
117 static_assert(predicate_ne<int, void_t>::valid == false, "");
118 static_assert(predicate_ne<void_t, int64_t>::valid == false, "");
119 static_assert(predicate_ne<int, int64_t>::valid == true, "");
120 static_assert(predicate_ne<long, int64_t>::valid == true, "");
121 static_assert(predicate_ne<vector<bool>, int64_t>::valid == true, "");
122 static_assert(predicate_ne<flat_set<char>, int64_t>::valid == true, "");
123 static_assert(predicate_ne<short, int64_t>::valid == true, "");
124 static_assert(predicate_ne<bool, int64_t>::valid == false, "");
125 static_assert(predicate_ne<int, bool>::valid == false, "");
126 static_assert(predicate_ne<fc::optional<int>, int64_t>::valid == true, "");
127 static_assert(predicate_ne<fc::optional<long>, int64_t>::valid == true, "");
128 static_assert(predicate_ne<fc::optional<long>, void_t>::valid == true, "");
129 static_assert(predicate_ne<string, string>::valid == true, "");
130 
131 static_assert(predicate_compare<int, int64_t>()(20, 10) == 1, "");
132 static_assert(predicate_compare<int, int64_t>()(5, 10) == -1, "");
133 static_assert(predicate_compare<int, int64_t>()(10, 10) == 0, "");
134 static_assert(predicate_lt<int, int64_t>()(20, 10) == false, "");
135 static_assert(predicate_lt<int, int64_t>()(5, 10) == true, "");
136 static_assert(predicate_lt<int, int64_t>()(10, 10) == false, "");
137 static_assert(predicate_le<int, int64_t>()(20, 10) == false, "");
138 static_assert(predicate_le<int, int64_t>()(5, 10) == true, "");
139 static_assert(predicate_le<int, int64_t>()(10, 10) == true, "");
140 static_assert(predicate_gt<int, int64_t>()(20, 10) == true, "");
141 static_assert(predicate_gt<int, int64_t>()(5, 10) == false, "");
142 static_assert(predicate_gt<int, int64_t>()(10, 10) == false, "");
143 static_assert(predicate_ge<int, int64_t>()(20, 10) == true, "");
144 static_assert(predicate_ge<int, int64_t>()(5, 10) == false, "");
145 static_assert(predicate_ge<int, int64_t>()(10, 10) == true, "");
146 
147 static_assert(predicate_compare<int, int64_t>::valid == true, "");
148 static_assert(predicate_compare<short, int64_t>::valid == true, "");
149 static_assert(predicate_compare<string, string>::valid == true, "");
150 static_assert(predicate_compare<vector<int>, int64_t>::valid == false, "");
151 static_assert(predicate_compare<fc::optional<int>, int64_t>::valid == true, "");
152 static_assert(predicate_compare<fc::optional<short>, int64_t>::valid == true, "");
153 static_assert(predicate_compare<fc::optional<string>, string>::valid == true, "");
154 static_assert(predicate_lt<int, int64_t>::valid == true, "");
155 static_assert(predicate_lt<short, int64_t>::valid == true, "");
156 static_assert(predicate_lt<string, string>::valid == true, "");
157 static_assert(predicate_lt<vector<int>, int64_t>::valid == false, "");
158 static_assert(predicate_lt<fc::optional<int>, int64_t>::valid == true, "");
159 static_assert(predicate_lt<fc::optional<short>, int64_t>::valid == true, "");
160 static_assert(predicate_lt<fc::optional<string>, string>::valid == true, "");
161 
162 static_assert(predicate_in<string, string>::valid == false, "");
163 static_assert(predicate_in<int, flat_set<string>>::valid == false, "");
164 static_assert(predicate_in<string, flat_set<string>>::valid == true, "");
165 static_assert(predicate_in<flat_set<string>, flat_set<string>>::valid == false, "");
166 static_assert(predicate_in<fc::optional<string>, flat_set<string>>::valid == true, "");
167 static_assert(predicate_not_in<string, string>::valid == false, "");
168 static_assert(predicate_not_in<int, flat_set<string>>::valid == false, "");
169 static_assert(predicate_not_in<string, flat_set<string>>::valid == true, "");
170 static_assert(predicate_not_in<flat_set<string>, flat_set<string>>::valid == false, "");
171 static_assert(predicate_not_in<fc::optional<string>, flat_set<string>>::valid == true, "");
172 
173 static_assert(predicate_has_all<string, string>::valid == false, "");
174 static_assert(predicate_has_all<int, flat_set<string>>::valid == false, "");
175 static_assert(predicate_has_all<string, flat_set<string>>::valid == false, "");
176 static_assert(predicate_has_all<flat_set<string>, flat_set<string>>::valid == true, "");
177 static_assert(predicate_has_all<fc::optional<string>, flat_set<string>>::valid == false, "");
178 static_assert(predicate_has_all<fc::optional<flat_set<string>>, flat_set<string>>::valid == true, "");
179 static_assert(predicate_has_none<string, string>::valid == false, "");
180 static_assert(predicate_has_none<int, flat_set<string>>::valid == false, "");
181 static_assert(predicate_has_none<string, flat_set<string>>::valid == false, "");
182 static_assert(predicate_has_none<flat_set<string>, flat_set<string>>::valid == true, "");
183 static_assert(predicate_has_none<fc::optional<string>, flat_set<string>>::valid == false, "");
184 static_assert(predicate_has_none<fc::optional<flat_set<string>>, flat_set<string>>::valid == true, "");
185 
186 #endif
187 
188 } } // namespace graphene::protocol
fc::static_variant::tag_type
int64_t tag_type
Definition: static_variant.hpp:46
graphene::protocol::predicate_not_in
Definition: restriction_predicate.hxx:282
graphene::protocol::get_restriction_pred_list_1
result_type get_restriction_pred_list_1(size_t idx, vector< restriction > rs)
Definition: list_1.cpp:31
graphene::protocol::get_restriction_predicate
restriction_predicate_function get_restriction_predicate(vector< restriction > rs, operation::tag_type op_type)
get_restriction_predicate Get a predicate function for the supplied restriction
Definition: restriction_predicate.cpp:32
graphene::protocol::predicate_gt
Definition: restriction_predicate.hxx:232
graphene::protocol::predicate_lt
Definition: restriction_predicate.hxx:224
fc::typelist::list
The actual list type.
Definition: typelist.hpp:17
graphene::protocol::get_restriction_pred_list_2
result_type get_restriction_pred_list_2(size_t idx, vector< restriction > rs)
Definition: list_2.cpp:32
graphene::protocol::get_restriction_pred_list_3
result_type get_restriction_pred_list_3(size_t idx, vector< restriction > rs)
Definition: list_3.cpp:32
graphene::protocol::predicate_ne
Definition: restriction_predicate.hxx:188
graphene::protocol::get_restriction_pred_list_9
result_type get_restriction_pred_list_9(size_t idx, vector< restriction > rs)
Definition: list_9.cpp:32
fc::static_variant< transfer_operation, limit_order_create_operation, limit_order_cancel_operation, call_order_update_operation, fill_order_operation, account_create_operation, account_update_operation, account_whitelist_operation, account_upgrade_operation, account_transfer_operation, asset_create_operation, asset_update_operation, asset_update_bitasset_operation, asset_update_feed_producers_operation, asset_issue_operation, asset_reserve_operation, asset_fund_fee_pool_operation, asset_settle_operation, asset_global_settle_operation, asset_publish_feed_operation, witness_create_operation, witness_update_operation, proposal_create_operation, proposal_update_operation, proposal_delete_operation, withdraw_permission_create_operation, withdraw_permission_update_operation, withdraw_permission_claim_operation, withdraw_permission_delete_operation, committee_member_create_operation, committee_member_update_operation, committee_member_update_global_parameters_operation, vesting_balance_create_operation, vesting_balance_withdraw_operation, worker_create_operation, custom_operation, assert_operation, balance_claim_operation, override_transfer_operation, transfer_to_blind_operation, blind_transfer_operation, transfer_from_blind_operation, asset_settle_cancel_operation, asset_claim_fees_operation, fba_distribute_operation, bid_collateral_operation, execute_bid_operation, asset_claim_pool_operation, asset_update_issuer_operation, htlc_create_operation, htlc_redeem_operation, htlc_redeemed_operation, htlc_extend_operation, htlc_refund_operation, custom_authority_create_operation, custom_authority_update_operation, custom_authority_delete_operation, ticket_create_operation, ticket_update_operation, liquidity_pool_create_operation, liquidity_pool_delete_operation, liquidity_pool_deposit_operation, liquidity_pool_withdraw_operation, liquidity_pool_exchange_operation, samet_fund_create_operation, samet_fund_delete_operation, samet_fund_update_operation, samet_fund_borrow_operation, samet_fund_repay_operation, credit_offer_create_operation, credit_offer_delete_operation, credit_offer_update_operation, credit_offer_accept_operation, credit_deal_repay_operation, credit_deal_expired_operation, liquidity_pool_update_operation, credit_deal_update_operation, limit_order_update_operation >
graphene::protocol::predicate_result
A type describing the result of a restriction predicate.
Definition: restriction_predicate.hpp:34
graphene::protocol::predicate_ge
Definition: restriction_predicate.hxx:236
graphene::protocol::void_t
Definition: types.hpp:146
graphene::protocol::predicate_result::success
bool success
Whether or not the operation complied with the restrictions or not.
Definition: restriction_predicate.hpp:36
fc::typelist::concat
typename impl::concat< Lists... >::type concat
Concatenate two or more typelists together.
Definition: typelist.hpp:150
graphene::protocol::get_restriction_pred_list_6
result_type get_restriction_pred_list_6(size_t idx, vector< restriction > rs)
Definition: list_6.cpp:32
graphene::protocol::predicate_le
Definition: restriction_predicate.hxx:228
graphene::protocol::get_restriction_pred_list_5
result_type get_restriction_pred_list_5(size_t idx, vector< restriction > rs)
Definition: list_5.cpp:32
graphene::protocol::predicate_result::reverse_path
predicate_result & reverse_path()
Reverse the order of the rejection path. Returns a reference to this object.
Definition: restriction_predicate.cpp:72
graphene::protocol::restriction_predicate_function
std::function< predicate_result(const operation &)> restriction_predicate_function
A restriction predicate is a function accepting an operation and returning a predicate_result.
Definition: restriction_predicate.hpp:62
graphene::protocol::predicate_has_all
Definition: restriction_predicate.hxx:308
graphene::protocol::get_restriction_pred_list_10
result_type get_restriction_pred_list_10(size_t idx, vector< restriction > rs)
Definition: list_10.cpp:31
graphene::protocol::get_restriction_pred_list_11
result_type get_restriction_pred_list_11(size_t idx, vector< restriction > rs)
Definition: list_11.cpp:31
restriction_predicate.hxx
sliced_lists.hxx
graphene::protocol::predicate_has_none
Definition: restriction_predicate.hxx:341
restriction_predicate.hpp
graphene::protocol::predicate_result::rejection_path
vector< rejection_indicator > rejection_path
Failure indicators, ordered from the outermost restriction to the innermost (the location of the reje...
Definition: restriction_predicate.hpp:49
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
fc::typelist::runtime::dispatch
Return dispatch(list< Types... >, std::size_t index, Callable c)
Index into the typelist for a type T, and invoke the callable with an argument wrapper<T>()
Definition: typelist.hpp:243
graphene::protocol::predicate_eq
Definition: restriction_predicate.hxx:151
FC_THROW_EXCEPTION
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:379
graphene::protocol::predicate_in
Definition: restriction_predicate.hxx:242
graphene::protocol::predicate_compare
Definition: restriction_predicate.hxx:194
graphene
Definition: api.cpp:48
fc::typelist::runtime::for_each
void for_each(list< Types... >, Callable c)
Invoke the provided callable with an argument wrapper<Type>() for each type in the list.
Definition: typelist.hpp:257