34 namespace graphene {
namespace protocol {
60 FC_ASSERT(
operations.size() > 0,
"A transaction must have at least one operation", (
"trx",*
this) );
104 flat_set<account_id_type>& owner,
105 vector<authority>& other,
106 bool ignore_custom_operation_required_auths )
const 110 for(
const auto& account : owner )
111 active.erase( account );
124 auto itr = provided_signatures.find(k);
125 if( itr == provided_signatures.end() )
127 auto pk = available_keys.find(k);
128 if( pk != available_keys.end() )
129 return provided_signatures[k] =
true;
132 return itr->second =
true;
139 if( !available_address_sigs ) {
140 available_address_sigs = std::map<address,public_key_type>();
141 provided_address_sigs = std::map<address,public_key_type>();
142 for(
auto& item : available_keys ) {
147 (*available_address_sigs)[
address(item) ] = item;
149 for(
auto& item : provided_signatures ) {
154 (*provided_address_sigs)[
address(item.first) ] = item.first;
157 auto itr = provided_address_sigs->find(a);
158 if( itr == provided_address_sigs->end() )
160 auto aitr = available_address_sigs->find(a);
161 if( aitr != available_address_sigs->end() ) {
162 auto pk = available_keys.find(aitr->second);
163 if( pk != available_keys.end() )
164 return provided_signatures[aitr->second] =
true;
168 return provided_signatures[itr->second] =
true;
173 if( approved_by.find(
id) != approved_by.end() )
return true;
174 return check_authority( get_active(
id) ) || ( allow_non_immediate_owner && check_authority( get_owner(
id) ) );
183 if( au ==
nullptr )
return false;
186 uint32_t total_weight = 0;
188 if( signed_by( k.first ) )
190 total_weight += k.second;
196 if( signed_by( k.first ) )
198 total_weight += k.second;
205 if( approved_by.find(a.first) == approved_by.end() )
207 if( depth == max_recursion )
209 if( check_authority( get_active( a.first ), depth+1 )
210 || ( allow_non_immediate_owner && check_authority( get_owner( a.first ), depth+1 ) ) )
212 approved_by.insert( a.first );
213 total_weight += a.second;
220 total_weight += a.second;
230 vector<public_key_type> remove_sigs;
231 for(
const auto& sig : provided_signatures )
232 if( !sig.second ) remove_sigs.push_back( sig.first );
234 for(
auto& sig : remove_sigs )
235 provided_signatures.erase(sig);
237 return remove_sigs.size() != 0;
241 const std::function<
const authority*(account_id_type)>& active,
242 const std::function<
const authority*(account_id_type)>& owner,
245 const flat_set<public_key_type>& keys = empty_keyset )
246 : get_active(active),
248 allow_non_immediate_owner(allow_owner),
249 max_recursion(max_recursion_depth),
252 for(
const auto& key : sigs )
253 provided_signatures[ key ] =
false;
257 const std::function<const authority*(account_id_type)>&
get_active;
258 const std::function<const authority*(account_id_type)>&
get_owner;
269 void verify_authority(
const vector<operation>& ops,
const flat_set<public_key_type>& sigs,
270 const std::function<
const authority*(account_id_type)>& get_active,
271 const std::function<
const authority*(account_id_type)>& get_owner,
273 bool allow_non_immediate_owner,
274 bool ignore_custom_operation_required_auths,
275 uint32_t max_recursion_depth,
276 bool allow_committee,
277 const flat_set<account_id_type>& active_aprovals,
278 const flat_set<account_id_type>& owner_approvals )
282 flat_set<account_id_type> required_active;
283 flat_set<account_id_type> required_owner;
284 vector<authority> other;
286 sign_state s( sigs, get_active, get_owner, allow_non_immediate_owner, max_recursion_depth );
287 for(
auto&
id : active_aprovals )
289 for(
auto&
id : owner_approvals )
292 auto approved_by_custom_authority = [&s, &rejected_custom_auths, get_custom = std::move(get_custom)](
293 account_id_type account,
295 auto viable_custom_auths = get_custom( account, op, &rejected_custom_auths );
296 for(
const auto& auth : viable_custom_auths )
301 for(
const auto& op : ops ) {
302 flat_set<account_id_type> operation_required_active;
304 ignore_custom_operation_required_auths );
306 auto itr = operation_required_active.begin();
307 while ( itr != operation_required_active.end() ) {
308 if ( approved_by_custom_authority( *itr, op ) )
309 itr = operation_required_active.erase( itr );
314 required_active.insert( operation_required_active.begin(), operation_required_active.end() );
317 if( !allow_committee )
319 invalid_committee_approval,
"Committee account may only propose transactions" );
321 for(
const auto& auth : other )
327 for(
auto id : required_owner )
331 tx_missing_owner_auth,
"Missing Owner Authority ${id}", (
"id",
id)(
"auth",*get_owner(
id)) );
334 for(
auto id : required_active )
338 tx_missing_active_auth,
"Missing Active Authority ${id}",
339 (
"id",
id)(
"auth",*get_active(
id))(
"owner",*get_owner(
id)) );
345 "Unnecessary signature(s) detected" 353 flat_set<public_key_type> result;
359 "Duplicate Signature detected" );
367 const flat_set<public_key_type>& available_keys,
368 const std::function<
const authority*(account_id_type)>& get_active,
369 const std::function<
const authority*(account_id_type)>& get_owner,
370 bool allow_non_immediate_owner,
371 bool ignore_custom_operation_required_authorities,
372 uint32_t max_recursion_depth )
const 374 flat_set<account_id_type> required_active;
375 flat_set<account_id_type> required_owner;
376 vector<authority> other;
380 sign_state s( signature_keys, get_active, get_owner, allow_non_immediate_owner, max_recursion_depth, available_keys );
382 for(
const auto& auth : other )
384 for(
auto& owner : required_owner )
386 for(
auto& active : required_active )
391 set<public_key_type> result;
394 if( available_keys.find( provided_sig.first ) != available_keys.end()
395 && signature_keys.find( provided_sig.first ) == signature_keys.end() )
396 result.insert( provided_sig.first );
403 const flat_set<public_key_type>& available_keys,
404 const std::function<
const authority*(account_id_type)>& get_active,
405 const std::function<
const authority*(account_id_type)>& get_owner,
407 bool allow_non_immediate_owner,
408 bool ignore_custom_operation_required_auths,
409 uint32_t max_recursion )
const 412 allow_non_immediate_owner,
413 ignore_custom_operation_required_auths, max_recursion );
414 flat_set< public_key_type > result( s.begin(), s.end() );
422 allow_non_immediate_owner,ignore_custom_operation_required_auths,
426 catch(
const tx_missing_owner_auth& e ) {}
427 catch(
const tx_missing_active_auth& e ) {}
428 catch(
const tx_missing_other_auth& e ) {}
431 return set<public_key_type>( result.begin(), result.end() );
465 const std::function<
const authority*(account_id_type)>& get_active,
466 const std::function<
const authority*(account_id_type)>& get_owner,
468 bool allow_non_immediate_owner,
469 bool ignore_custom_operation_required_auths,
470 uint32_t max_recursion )
const 473 get_custom, allow_non_immediate_owner,
474 ignore_custom_operation_required_auths, max_recursion );
virtual const transaction_id_type & id() const
digest_type sig_digest(const chain_id_type &chain_id) const
boost::endian::little_uint32_buf_t _hash[5]
const flat_set< public_key_type > empty_keyset
#define GRAPHENE_TEMP_ACCOUNT
Represents the canonical account with WILDCARD authority (anybody can access funds in temp account) ...
bool remove_unused_signatures()
fc::time_point_sec expiration
void verify_authority(const chain_id_type &chain_id, const std::function< const authority *(account_id_type)> &get_active, const std::function< const authority *(account_id_type)> &get_owner, const custom_authority_lookup &get_custom, bool allow_non_immediate_owner, bool ignore_custom_operation_required_auths, uint32_t max_recursion=GRAPHENE_MAX_SIG_CHECK_DEPTH) const
Identifies a weighted set of keys and accounts that must approve operations.
void pack(Stream &s, const flat_set< T, A... > &value, uint32_t _max_depth)
map< custom_authority_id_type, rejected_predicate > rejected_predicate_map
vector< operation > operations
bool check_authority(account_id_type id)
void verify_authority(const vector< operation > &ops, const flat_set< public_key_type > &sigs, const std::function< const authority *(account_id_type)> &get_active, const std::function< const authority *(account_id_type)> &get_owner, const custom_authority_lookup &get_custom, bool allow_non_immediate_owner, bool ignore_custom_operation_required_auths, uint32_t max_recursion=GRAPHENE_MAX_SIG_CHECK_DEPTH, bool allow_committee=false, const flat_set< account_id_type > &active_approvals=flat_set< account_id_type >(), const flat_set< account_id_type > &owner_approvals=flat_set< account_id_type >())
std::function< vector< authority >(account_id_type, const operation &, rejected_predicate_map *)> custom_authority_lookup
flat_map< address, weight_type > address_auths
transaction_id_type _tx_id_buffer
digest_type merkle_digest() const
flat_set< public_key_type > _signees
virtual void validate() const override
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 >
set< public_key_type > get_required_signatures(const chain_id_type &chain_id, const flat_set< public_key_type > &available_keys, const std::function< const authority *(account_id_type)> &get_active, const std::function< const authority *(account_id_type)> &get_owner, bool allow_non_immediate_owner, bool ignore_custom_operation_required_authorities, uint32_t max_recursion=GRAPHENE_MAX_SIG_CHECK_DEPTH) const
bool signed_by(const address &a)
groups operations that should be applied atomically
void set_reference_block(const block_id_type &reference_block)
const uint32_t max_recursion
compact_signature sign_compact(const fc::sha256 &digest, bool require_canonical=true) const
provides stack-based nullable value similar to boost::optional
flat_map< public_key_type, weight_type > key_auths
bool check_authority(const authority *au, uint32_t depth=0)
size_t pack_size(const T &v)
void set_expiration(fc::time_point_sec expiration_time)
const bool allow_non_immediate_owner
void operation_validate(const operation &op)
uint32_t ref_block_prefix
contains only the public point of an elliptic curve key.
flat_map< account_id_type, weight_type > account_auths
virtual const flat_set< public_key_type > & get_signature_keys(const chain_id_type &chain_id) const
Extract public keys from signatures with given chain ID.
#define GRAPHENE_COMMITTEE_ACCOUNT
#define FC_CAPTURE_AND_RETHROW(...)
#define GRAPHENE_MAX_SIG_CHECK_DEPTH
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
set< public_key_type > minimize_required_signatures(const chain_id_type &chain_id, const flat_set< public_key_type > &available_keys, const std::function< const authority *(account_id_type)> &get_active, const std::function< const authority *(account_id_type)> &get_owner, const custom_authority_lookup &get_custom, bool allow_non_immediate_owner, bool ignore_custom_operation_required_auths, uint32_t max_recursion=GRAPHENE_MAX_SIG_CHECK_DEPTH) const
adds a signature to a transaction
digest_type digest() const
Calculate the digest for a transaction.
void get_required_authorities(flat_set< account_id_type > &active, flat_set< account_id_type > &owner, vector< authority > &other, bool ignore_custom_operation_required_auths) const
#define GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION(type)
bool signed_by(const public_key_type &k)
optional< map< address, public_key_type > > available_address_sigs
virtual uint64_t get_packed_size() const
const flat_set< public_key_type > & available_keys
virtual const flat_set< public_key_type > & get_signature_keys(const chain_id_type &chain_id) const override
Extract public keys from signatures with given chain ID.
virtual uint64_t get_packed_size() const override
virtual const transaction_id_type & id() const override
sign_state(const flat_set< public_key_type > &sigs, const std::function< const authority *(account_id_type)> &active, const std::function< const authority *(account_id_type)> &owner, bool allow_owner, uint32_t max_recursion_depth=GRAPHENE_MAX_SIG_CHECK_DEPTH, const flat_set< public_key_type > &keys=empty_keyset)
uint32_t weight_threshold
virtual void validate() const
flat_set< account_id_type > approved_by
#define GRAPHENE_ASSERT(expr, exc_type, FORMAT,...)
a 160 bit hash of a public key
an elliptic curve private key.
const signature_type & sign(const private_key_type &key, const chain_id_type &chain_id)
captures the result of evaluating the operations contained in the transaction
void operation_get_required_authorities(const operation &op, flat_set< account_id_type > &active, flat_set< account_id_type > &owner, vector< authority > &other, bool ignore_custom_operation_required_auths)
optional< map< address, public_key_type > > provided_address_sigs
vector< signature_type > signatures
const std::function< const authority *(account_id_type)> & get_active
const std::function< const authority *(account_id_type)> & get_owner
flat_map< public_key_type, bool > provided_signatures