BitShares-Core  5.0.0
BitShares blockchain implementation and command-line interface 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_predicate_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_predicate_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_predicate_list_3(typelist::index_of<operation_list_3::list, Op>(), std::move(rs));
41  if (typelist::contains<operation_list_4::list, Op>())
42  return get_restriction_predicate_list_4(typelist::index_of<operation_list_4::list, Op>(), std::move(rs));
43  if (typelist::contains<operation_list_5::list, Op>())
44  return get_restriction_predicate_list_5(typelist::index_of<operation_list_5::list, Op>(), std::move(rs));
45  if (typelist::contains<operation_list_6::list, Op>())
46  return get_restriction_predicate_list_6(typelist::index_of<operation_list_6::list, Op>(), std::move(rs));
47  if (typelist::contains<operation_list_7::list, Op>())
48  return get_restriction_predicate_list_7(typelist::index_of<operation_list_7::list, Op>(), std::move(rs));
49  if (typelist::contains<operation_list_8::list, Op>())
50  return get_restriction_predicate_list_8(typelist::index_of<operation_list_8::list, Op>(), std::move(rs));
51  if (typelist::contains<operation_list_9::list, Op>())
52  return get_restriction_predicate_list_9(typelist::index_of<operation_list_9::list, Op>(), std::move(rs));
53  if (typelist::contains<operation_list_10::list, Op>())
54  return get_restriction_predicate_list_10(typelist::index_of<operation_list_10::list, Op>(), std::move(rs));
55  if (typelist::contains<operation_list_11::list, Op>())
56  return get_restriction_predicate_list_11(typelist::index_of<operation_list_11::list, Op>(), std::move(rs));
57  if (typelist::contains<operation_list_12::list, Op>())
58  return get_restriction_predicate_list_12(typelist::index_of<operation_list_12::list, Op>(), std::move(rs));
59  if (typelist::contains<virtual_operations_list::list, Op>())
60  FC_THROW_EXCEPTION( fc::assert_exception, "Virtual operations not allowed!" );
61 
62  // Compile time check that we'll never get to the exception below
63  static_assert(typelist::contains<typelist::concat<operation_list_1::list, operation_list_2::list,
70  Op>(), "");
71  FC_THROW_EXCEPTION(fc::assert_exception,
72  "LOGIC ERROR: Operation type not handled by custom authorities implementation. "
73  "Please report this error.");
74  });
75 
76  // Wrap function in a layer that, if the function returns an error, reverses the order of the rejection path. This
77  // is because the order the path is created in, from the top of the call stack to the bottom, is counterintuitive.
78  return [f=std::move(f)](const operation& op) { return f(op).reverse_path(); };
79 }
80 
82  if (success == true)
83  return *this;
84  auto reverse_subpaths = [](rejection_indicator& indicator) {
85  if (indicator.is_type<vector<predicate_result>>()) {
86  auto& results = indicator.get<vector<predicate_result>>();
87  for (predicate_result& result : results) result.reverse_path();
88  }
89  };
90  std::reverse(rejection_path.begin(), rejection_path.end());
91  std::for_each(rejection_path.begin(), rejection_path.end(), reverse_subpaths);
92  return *this;
93 }
94 
95 // These are some compile-time tests of the metafunctions and predicate type analysis. They are turned off to make
96 // building faster; they only need to be enabled when making changes in restriction_predicate.hxx
97 #if false
98 static_assert(!is_container<int>, "");
99 static_assert(is_container<vector<int>>, "");
100 static_assert(is_container<flat_set<int>>, "");
101 static_assert(is_container<string>, "");
102 static_assert(is_flat_set<flat_set<int>>, "");
103 static_assert(!is_flat_set<vector<int>>, "");
104 
105 static_assert(predicate_eq<int, int64_t>()(10, 20) == false, "");
106 static_assert(predicate_eq<int, int64_t>()(10, 5) == false, "");
107 static_assert(predicate_eq<int, int64_t>()(10, 10) == true, "");
108 
109 static_assert(predicate_eq<void_t, void_t>::valid == false, "");
110 static_assert(predicate_eq<int, void_t>::valid == false, "");
111 static_assert(predicate_eq<void_t, int64_t>::valid == false, "");
112 static_assert(predicate_eq<int, int64_t>::valid == true, "");
113 static_assert(predicate_eq<long, int64_t>::valid == true, "");
114 static_assert(predicate_eq<vector<bool>, int64_t>::valid == true, "");
115 static_assert(predicate_eq<flat_set<char>, int64_t>::valid == true, "");
116 static_assert(predicate_eq<short, int64_t>::valid == true, "");
117 static_assert(predicate_eq<bool, int64_t>::valid == false, "");
118 static_assert(predicate_eq<int, bool>::valid == false, "");
119 static_assert(predicate_eq<fc::optional<int>, int64_t>::valid == true, "");
120 static_assert(predicate_eq<fc::optional<long>, int64_t>::valid == true, "");
121 static_assert(predicate_eq<fc::optional<long>, void_t>::valid == true, "");
122 static_assert(predicate_eq<flat_set<bool>, flat_set<bool>>::valid == true, "");
123 static_assert(predicate_eq<flat_set<bool>, string>::valid == false, "");
124 static_assert(predicate_eq<string, string>::valid == true, "");
125 static_assert(predicate_ne<int, void_t>::valid == false, "");
126 static_assert(predicate_ne<void_t, int64_t>::valid == false, "");
127 static_assert(predicate_ne<int, int64_t>::valid == true, "");
128 static_assert(predicate_ne<long, int64_t>::valid == true, "");
129 static_assert(predicate_ne<vector<bool>, int64_t>::valid == true, "");
130 static_assert(predicate_ne<flat_set<char>, int64_t>::valid == true, "");
131 static_assert(predicate_ne<short, int64_t>::valid == true, "");
132 static_assert(predicate_ne<bool, int64_t>::valid == false, "");
133 static_assert(predicate_ne<int, bool>::valid == false, "");
134 static_assert(predicate_ne<fc::optional<int>, int64_t>::valid == true, "");
135 static_assert(predicate_ne<fc::optional<long>, int64_t>::valid == true, "");
136 static_assert(predicate_ne<fc::optional<long>, void_t>::valid == true, "");
137 static_assert(predicate_ne<string, string>::valid == true, "");
138 
139 static_assert(predicate_compare<int, int64_t>()(20, 10) == 1, "");
140 static_assert(predicate_compare<int, int64_t>()(5, 10) == -1, "");
141 static_assert(predicate_compare<int, int64_t>()(10, 10) == 0, "");
142 static_assert(predicate_lt<int, int64_t>()(20, 10) == false, "");
143 static_assert(predicate_lt<int, int64_t>()(5, 10) == true, "");
144 static_assert(predicate_lt<int, int64_t>()(10, 10) == false, "");
145 static_assert(predicate_le<int, int64_t>()(20, 10) == false, "");
146 static_assert(predicate_le<int, int64_t>()(5, 10) == true, "");
147 static_assert(predicate_le<int, int64_t>()(10, 10) == true, "");
148 static_assert(predicate_gt<int, int64_t>()(20, 10) == true, "");
149 static_assert(predicate_gt<int, int64_t>()(5, 10) == false, "");
150 static_assert(predicate_gt<int, int64_t>()(10, 10) == false, "");
151 static_assert(predicate_ge<int, int64_t>()(20, 10) == true, "");
152 static_assert(predicate_ge<int, int64_t>()(5, 10) == false, "");
153 static_assert(predicate_ge<int, int64_t>()(10, 10) == true, "");
154 
155 static_assert(predicate_compare<int, int64_t>::valid == true, "");
156 static_assert(predicate_compare<short, int64_t>::valid == true, "");
157 static_assert(predicate_compare<string, string>::valid == true, "");
158 static_assert(predicate_compare<vector<int>, int64_t>::valid == false, "");
159 static_assert(predicate_compare<fc::optional<int>, int64_t>::valid == true, "");
160 static_assert(predicate_compare<fc::optional<short>, int64_t>::valid == true, "");
161 static_assert(predicate_compare<fc::optional<string>, string>::valid == true, "");
162 static_assert(predicate_lt<int, int64_t>::valid == true, "");
163 static_assert(predicate_lt<short, int64_t>::valid == true, "");
164 static_assert(predicate_lt<string, string>::valid == true, "");
165 static_assert(predicate_lt<vector<int>, int64_t>::valid == false, "");
166 static_assert(predicate_lt<fc::optional<int>, int64_t>::valid == true, "");
167 static_assert(predicate_lt<fc::optional<short>, int64_t>::valid == true, "");
168 static_assert(predicate_lt<fc::optional<string>, string>::valid == true, "");
169 
170 static_assert(predicate_in<string, string>::valid == false, "");
171 static_assert(predicate_in<int, flat_set<string>>::valid == false, "");
172 static_assert(predicate_in<string, flat_set<string>>::valid == true, "");
173 static_assert(predicate_in<flat_set<string>, flat_set<string>>::valid == false, "");
174 static_assert(predicate_in<fc::optional<string>, flat_set<string>>::valid == true, "");
175 static_assert(predicate_not_in<string, string>::valid == false, "");
176 static_assert(predicate_not_in<int, flat_set<string>>::valid == false, "");
177 static_assert(predicate_not_in<string, flat_set<string>>::valid == true, "");
178 static_assert(predicate_not_in<flat_set<string>, flat_set<string>>::valid == false, "");
179 static_assert(predicate_not_in<fc::optional<string>, flat_set<string>>::valid == true, "");
180 
181 static_assert(predicate_has_all<string, string>::valid == false, "");
182 static_assert(predicate_has_all<int, flat_set<string>>::valid == false, "");
183 static_assert(predicate_has_all<string, flat_set<string>>::valid == false, "");
184 static_assert(predicate_has_all<flat_set<string>, flat_set<string>>::valid == true, "");
185 static_assert(predicate_has_all<fc::optional<string>, flat_set<string>>::valid == false, "");
186 static_assert(predicate_has_all<fc::optional<flat_set<string>>, flat_set<string>>::valid == true, "");
187 static_assert(predicate_has_none<string, string>::valid == false, "");
188 static_assert(predicate_has_none<int, flat_set<string>>::valid == false, "");
189 static_assert(predicate_has_none<string, flat_set<string>>::valid == false, "");
190 static_assert(predicate_has_none<flat_set<string>, flat_set<string>>::valid == true, "");
191 static_assert(predicate_has_none<fc::optional<string>, flat_set<string>>::valid == false, "");
192 static_assert(predicate_has_none<fc::optional<flat_set<string>>, flat_set<string>>::valid == true, "");
193 
194 #endif
195 
196 } } // namespace graphene::protocol
Definition: api.cpp:56
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
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 >
predicate_result & reverse_path()
Reverse the order of the rejection path. Returns a reference to this object.
result_type get_restriction_predicate_list_1(size_t idx, vector< restriction > rs)
Definition: list_1.cpp:31
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
vector< rejection_indicator > rejection_path
Failure indicators, ordered from the outermost restriction to the innermost (the location of the reje...
A type describing the result of a restriction predicate.
result_type get_restriction_predicate_list_5(size_t idx, vector< restriction > rs)
Definition: list_5.cpp:32
std::function< predicate_result(const operation &)> restriction_predicate_function
A restriction predicate is a function accepting an operation and returning a predicate_result.
result_type get_restriction_predicate_list_9(size_t idx, vector< restriction > rs)
Definition: list_9.cpp:32
result_type get_restriction_predicate_list_8(size_t idx, vector< restriction > rs)
Definition: list_8.cpp:32
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:378
result_type get_restriction_predicate_list_3(size_t idx, vector< restriction > rs)
Definition: list_3.cpp:32
The actual list type.
Definition: typelist.hpp:17
result_type get_restriction_predicate_list_6(size_t idx, vector< restriction > rs)
Definition: list_6.cpp:32
result_type get_restriction_predicate_list_7(size_t idx, vector< restriction > rs)
Definition: list_7.cpp:32
result_type get_restriction_predicate_list_2(size_t idx, vector< restriction > rs)
Definition: list_2.cpp:32
typename impl::concat< Lists... >::type concat
Concatenate two or more typelists together.
Definition: typelist.hpp:150
result_type get_restriction_predicate_list_4(size_t idx, vector< restriction > rs)
Definition: list_4.cpp:32
result_type get_restriction_predicate_list_11(size_t idx, vector< restriction > rs)
Definition: list_11.cpp:31
bool success
Whether or not the operation complied with the restrictions or not.
result_type get_restriction_predicate_list_10(size_t idx, vector< restriction > rs)
Definition: list_10.cpp:31
void for_each(T &&t, const account_object &a, seq< Is... >)
Definition: database.hpp:701
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
result_type get_restriction_predicate_list_12(size_t idx, vector< restriction > rs)
Definition: list_12.cpp:31