BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
custom_authority_evaluator.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 
31 
32 namespace graphene { namespace chain {
33 
35 { try {
36  const database& d = db();
37  auto now = d.head_block_time();
38  FC_ASSERT(HARDFORK_BSIP_40_PASSED(now), "Custom active authorities are not yet enabled");
39 
40  op.account(d);
41 
42  const auto& config = d.get_global_properties().parameters.extensions.value.custom_authority_options;
43  FC_ASSERT(config.valid(), "Cannot use custom authorities yet: global configuration not set");
44  FC_ASSERT(op.valid_to > now, "Custom authority expiration must be in the future");
45  FC_ASSERT((op.valid_to - now).to_seconds() <= config->max_custom_authority_lifetime_seconds,
46  "Custom authority lifetime exceeds maximum limit");
47 
48  bool operation_forked_in = hardfork_visitor(now).visit((operation::tag_type)op.operation_type.value);
49  FC_ASSERT(operation_forked_in, "Cannot create custom authority for operation which is not valid yet");
50 
51  auto restriction_count = restriction::restriction_count(op.restrictions);
52  FC_ASSERT(restriction_count <= config->max_custom_authority_restrictions,
53  "Custom authority has more than the maximum number of restrictions");
54 
55  for (const auto& account_weight_pair : op.auth.account_auths)
56  account_weight_pair.first(d);
57 
58  const auto& index = d.get_index_type<custom_authority_index>().indices().get<by_account_custom>();
59  auto range = index.equal_range(op.account);
60  FC_ASSERT(std::distance(range.first, range.second) < config->max_custom_authorities_per_account,
61  "Cannot create custom authority: account already has maximum number");
62  range = index.equal_range(boost::make_tuple(op.account, op.operation_type));
63  FC_ASSERT(std::distance(range.first, range.second) < config->max_custom_authorities_per_account_op,
64  "Cannot create custom authority: account already has maximum number for this operation type");
65 
66  return void_result();
67 } FC_CAPTURE_AND_RETHROW((op)) }
68 
70 { try {
71  database& d = db();
72 
73  return d.create<custom_authority_object>([&op] (custom_authority_object& obj) mutable {
74  obj.account = op.account;
75  obj.enabled = op.enabled;
76  obj.valid_from = op.valid_from;
77  obj.valid_to = op.valid_to;
78  obj.operation_type = op.operation_type;
79  obj.auth = op.auth;
80  std::for_each(op.restrictions.begin(), op.restrictions.end(), [&obj](const restriction& r) mutable {
81  obj.restrictions.insert(std::make_pair(obj.restriction_counter++, r));
82  });
83  }).id;
84 } FC_CAPTURE_AND_RETHROW((op)) }
85 
87 { try {
88  const database& d = db();
89  auto now = d.head_block_time();
91  FC_ASSERT(old_object->account == op.account, "Cannot update a different account's custom authority");
92 
93  if (op.new_enabled)
95  "Custom authority update specifies an enabled flag, but flag is not changed");
96 
97  const auto& config = d.get_global_properties().parameters.extensions.value.custom_authority_options;
98  auto valid_from = old_object->valid_from;
99  auto valid_to = old_object->valid_to;
100  if (op.new_valid_from) {
102  "Custom authority update specifies a new valid from date, but date is not changed");
103  valid_from = *op.new_valid_from;
104  }
105  if (op.new_valid_to) {
107  "Custom authority update specifies a new valid to date, but date is not changed");
108  FC_ASSERT(*op.new_valid_to > now, "Custom authority expiration must be in the future");
109  FC_ASSERT((*op.new_valid_to - now).to_seconds() <= config->max_custom_authority_lifetime_seconds,
110  "Custom authority lifetime exceeds maximum limit");
111  valid_to = *op.new_valid_to;
112  }
113  FC_ASSERT(valid_from < valid_to, "Custom authority validity begin date must be before expiration date");
114 
115  if (op.new_auth) {
117  "Custom authority update specifies a new authentication authority, but authority is not changed");
118  for (const auto& account_weight_pair : op.new_auth->account_auths)
119  account_weight_pair.first(d);
120  }
121 
122  std::for_each(op.restrictions_to_remove.begin(), op.restrictions_to_remove.end(), [this](uint16_t id) {
123  FC_ASSERT(old_object->restrictions.count(id) == 1, "Cannot remove restriction ID ${I}: ID not found",
124  ("I", id));
125  });
126  if (!op.restrictions_to_add.empty()) {
127  // Sanity check
128  if (!old_object->restrictions.empty())
130  "LOGIC ERROR: Restriction counter overlaps restrictions. Please report this error.");
132  "Unable to add restrictions: causes wraparound of restriction IDs");
133  }
134 
135  // Add up the restriction counts for all old restrictions not being removed, and all new ones
136  size_t restriction_count = 0;
137  for (const auto& restriction_pair : old_object->restrictions)
138  if (op.restrictions_to_remove.count(restriction_pair.first) == 0)
139  restriction_count += restriction_pair.second.restriction_count();
140  restriction_count += restriction::restriction_count(op.restrictions_to_add);
141  // Check restriction count against limit
142  FC_ASSERT(restriction_count <= config->max_custom_authority_restrictions,
143  "Cannot update custom authority: updated authority would exceed the maximum number of restrictions");
144 
146  return void_result();
147 } FC_CAPTURE_AND_RETHROW((op)) }
148 
150 { try {
151  database& d = db();
152 
153  d.modify(*old_object, [&op](custom_authority_object& obj) {
154  if (op.new_enabled) obj.enabled = *op.new_enabled;
155  if (op.new_valid_from) obj.valid_from = *op.new_valid_from;
156  if (op.new_valid_to) obj.valid_to = *op.new_valid_to;
157  if (op.new_auth) obj.auth = *op.new_auth;
158 
159  std::for_each(op.restrictions_to_remove.begin(), op.restrictions_to_remove.end(), [&obj](auto id) mutable {
160  obj.restrictions.erase(id);
161  });
162  std::for_each(op.restrictions_to_add.begin(), op.restrictions_to_add.end(), [&obj](const auto& r) mutable {
163  obj.restrictions.insert(std::make_pair(obj.restriction_counter++, r));
164  });
165 
166  // Clear the predicate cache
167  obj.clear_predicate_cache();
168  });
169 
170  return void_result();
171 } FC_CAPTURE_AND_RETHROW((op)) }
172 
174 { try {
175  const database& d = db();
176 
178  FC_ASSERT(old_object->account == op.account, "Cannot delete a different account's custom authority");
179 
180  return void_result();
181 } FC_CAPTURE_AND_RETHROW((op)) }
182 
184 { try {
185  database& d = db();
186 
187  d.remove(*old_object);
188 
189  return void_result();
190 } FC_CAPTURE_AND_RETHROW((op)) }
191 
192 } } // graphene::chain
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
graphene::protocol::custom_authority_create_operation::valid_to
time_point_sec valid_to
Expiration date for custom authority.
Definition: custom_authority.hpp:51
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 >::tag_type
int64_t tag_type
Definition: static_variant.hpp:46
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::chain::custom_authority_delete_evaluator::do_apply
void_result do_apply(const operation_type &op)
Definition: custom_authority_evaluator.cpp:183
graphene::chain::database
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
graphene::protocol::custom_authority_create_operation::account
account_id_type account
Account which is setting the custom authority; also pays the fee.
Definition: custom_authority.hpp:45
graphene::chain::custom_authority_object::clear_predicate_cache
void clear_predicate_cache()
Clear the cache of the predicate function.
Definition: custom_authority_object.hpp:78
graphene::chain::database::head_block_time
time_point_sec head_block_time() const
Definition: db_getter.cpp:67
graphene::chain::custom_authority_delete_evaluator::do_evaluate
void_result do_evaluate(const operation_type &op)
Definition: custom_authority_evaluator.cpp:173
graphene::chain::custom_authority_update_evaluator::do_evaluate
void_result do_evaluate(const operation_type &op)
Definition: custom_authority_evaluator.cpp:86
database.hpp
graphene::protocol::restriction
Definition: restriction.hpp:33
graphene::protocol::custom_authority_create_operation::operation_type
unsigned_int operation_type
Tag of the operation this custom authority can authorize.
Definition: custom_authority.hpp:53
graphene::protocol::custom_authority_create_operation
Create a new custom authority.
Definition: custom_authority.hpp:36
graphene::protocol::custom_authority_update_operation::new_enabled
optional< bool > new_enabled
Change to whether the custom authority is enabled or not.
Definition: custom_authority.hpp:83
graphene::chain::global_property_object::parameters
chain_parameters parameters
Definition: global_property_object.hpp:44
custom_authority_object.hpp
graphene::chain::custom_authority_create_evaluator::do_evaluate
void_result do_evaluate(const operation_type &op)
Definition: custom_authority_evaluator.cpp:34
custom_authority_evaluator.hpp
graphene::db::object_database::create
const T & create(F &&constructor)
Definition: object_database.hpp:63
graphene::protocol::custom_authority_update_operation::new_valid_to
optional< time_point_sec > new_valid_to
Change to the custom authority expiration date.
Definition: custom_authority.hpp:87
graphene::chain::custom_authority_object
Tracks account custom authorities.
Definition: custom_authority_object.hpp:39
graphene::protocol::custom_authority_update_operation::restrictions_to_remove
flat_set< uint16_t > restrictions_to_remove
Set of IDs of restrictions to remove.
Definition: custom_authority.hpp:91
graphene::chain::custom_authority_object::account
account_id_type account
Definition: custom_authority_object.hpp:47
graphene::protocol::custom_authority_create_operation::auth
authority auth
Authentication requirements for the custom authority.
Definition: custom_authority.hpp:55
graphene::protocol::authority::account_auths
flat_map< account_id_type, weight_type > account_auths
Definition: authority.hpp:120
graphene::chain::custom_authority_object::enabled
bool enabled
Definition: custom_authority_object.hpp:48
graphene::protocol::custom_authority_create_operation::valid_from
time_point_sec valid_from
Date when custom authority becomes active.
Definition: custom_authority.hpp:49
graphene::protocol::custom_authority_delete_operation
Delete a custom authority.
Definition: custom_authority.hpp:107
graphene::chain::custom_authority_object::operation_type
unsigned_int operation_type
Definition: custom_authority_object.hpp:51
graphene::chain::custom_authority_update_evaluator::do_apply
void_result do_apply(const operation_type &op)
Definition: custom_authority_evaluator.cpp:149
graphene::protocol::custom_authority_update_operation::restrictions_to_add
vector< restriction > restrictions_to_add
Vector of new restrictions.
Definition: custom_authority.hpp:93
graphene::chain::custom_authority_delete_evaluator::old_object
const custom_authority_object * old_object
Definition: custom_authority_evaluator.hpp:53
graphene::chain::custom_authority_object::valid_from
time_point_sec valid_from
Definition: custom_authority_object.hpp:49
graphene::protocol::restriction::restriction_count
size_t restriction_count() const
Definition: restriction.cpp:39
graphene::db::index::get
const object & get(object_id_type id) const
Definition: index.hpp:110
graphene::protocol::chain_parameters::extensions
extension< ext > extensions
Definition: chain_parameters.hpp:90
account_object.hpp
graphene::protocol::custom_authority_update_operation::new_auth
optional< authority > new_auth
Change to the authentication for the custom authority.
Definition: custom_authority.hpp:89
graphene::protocol::custom_authority_create_operation::restrictions
vector< restriction > restrictions
Restrictions on operations this custom authority can authenticate.
Definition: custom_authority.hpp:57
graphene::protocol::custom_authority_update_operation
Update a custom authority.
Definition: custom_authority.hpp:70
graphene::chain::custom_authority_object::restriction_counter
uint16_t restriction_counter
Definition: custom_authority_object.hpp:54
graphene::chain::generic_evaluator::db
database & db() const
Definition: evaluator.cpp:39
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
fc::unsigned_int::value
uint64_t value
Definition: varint.hpp:17
graphene::db::object_id_type
Definition: object_id.hpp:30
graphene::chain::custom_authority_object::restrictions
flat_map< uint16_t, restriction > restrictions
Definition: custom_authority_object.hpp:53
graphene::protocol::custom_authority_create_operation::enabled
bool enabled
Whether the custom authority is enabled or not.
Definition: custom_authority.hpp:47
graphene::chain::hardfork_visitor
The hardfork_visitor struct checks whether a given operation type has been hardforked in or not.
Definition: hardfork_visitor.hpp:44
graphene::db::generic_index
Definition: generic_index.hpp:43
graphene::chain::database::get_global_properties
const global_property_object & get_global_properties() const
Definition: db_getter.cpp:47
graphene::protocol::custom_authority_update_operation::account
account_id_type account
Account which owns the custom authority to update; also pays the fee.
Definition: custom_authority.hpp:79
graphene::protocol::custom_authority_update_operation::authority_to_update
custom_authority_id_type authority_to_update
ID of the custom authority to update.
Definition: custom_authority.hpp:81
graphene::protocol::custom_authority_delete_operation::account
account_id_type account
Account which owns the custom authority to update; also pays the fee.
Definition: custom_authority.hpp:113
graphene::protocol::custom_authority_update_operation::new_valid_from
optional< time_point_sec > new_valid_from
Change to the custom authority begin date.
Definition: custom_authority.hpp:85
graphene::protocol::void_result
Definition: base.hpp:86
graphene::db::object_database::remove
void remove(const object &obj)
Definition: object_database.hpp:97
graphene::db::object_database::get_index_type
const IndexType & get_index_type() const
Definition: object_database.hpp:77
graphene::chain::custom_authority_update_evaluator::old_object
const custom_authority_object * old_object
Definition: custom_authority_evaluator.hpp:44
graphene::chain::custom_authority_object::auth
authority auth
Definition: custom_authority_object.hpp:52
graphene::db::index
abstract base class for accessing objects indexed in various ways.
Definition: index.hpp:70
graphene::protocol::custom_authority_delete_operation::authority_to_delete
custom_authority_id_type authority_to_delete
ID of the custom authority to delete.
Definition: custom_authority.hpp:115
graphene::chain::custom_authority_object::valid_to
time_point_sec valid_to
Definition: custom_authority_object.hpp:50
hardfork_visitor.hpp
graphene
Definition: api.cpp:48
exceptions.hpp
graphene::chain::custom_authority_create_evaluator::do_apply
object_id_type do_apply(const operation_type &op)
Definition: custom_authority_evaluator.cpp:69
graphene::db::object_database::modify
void modify(const T &obj, const Lambda &m)
Definition: object_database.hpp:99
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