Progress #66: Audit calculate_fee implementations

I've audited all the calculate_fee impls and they all should be
reasonable at this point.

TODO: Set default fee values.
This commit is contained in:
Nathan Hourt 2015-06-23 14:19:34 -04:00
parent a0d2b18959
commit 08cba191c7
8 changed files with 331 additions and 239 deletions

View file

@ -249,8 +249,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
for( const auto& handout : genesis_state.allocation_targets ) for( const auto& handout : genesis_state.allocation_targets )
total_allocation += handout.weight; total_allocation += handout.weight;
fc::time_point start_time = fc::time_point::now();
for( const auto& handout : genesis_state.allocation_targets ) for( const auto& handout : genesis_state.allocation_targets )
{ {
asset amount(handout.weight); asset amount(handout.weight);
@ -298,10 +296,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}); });
} }
} }
// fc::microseconds duration = fc::time_point::now() - start_time;
// ilog("Finished allocating to ${n} accounts in ${t} milliseconds.",
// ("n", genesis_state.allocation_targets.size())("t", duration.count() / 1000));
} }
flat_set<delegate_id_type> init_delegates; flat_set<delegate_id_type> init_delegates;

View file

@ -155,7 +155,8 @@ namespace graphene { namespace chain {
/** defines the assets that this asset may not be traded against in the market, must not overlap whitelist */ /** defines the assets that this asset may not be traded against in the market, must not overlap whitelist */
flat_set<asset_id_type> blacklist_markets; flat_set<asset_id_type> blacklist_markets;
/** data that describes the meaning/purpose of this asset, fee will be charged proportional to /**
* data that describes the meaning/purpose of this asset, fee will be charged proportional to
* size of description. * size of description.
*/ */
string description; string description;

View file

@ -116,17 +116,17 @@ namespace graphene { namespace chain {
*/ */
struct assert_operation struct assert_operation
{ {
asset fee; asset fee;
account_id_type fee_paying_account; account_id_type fee_paying_account;
vector< vector< char > > predicates; vector<vector<char>> predicates;
flat_set<account_id_type> required_auths; flat_set<account_id_type> required_auths;
account_id_type fee_payer()const { return fee_paying_account; } account_id_type fee_payer()const { return fee_paying_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void validate()const; void validate()const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -141,10 +141,10 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return fee_paying_account; } account_id_type fee_payer()const { return fee_paying_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set , flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set , flat_set<account_id_type>&)const;
share_type calculate_fee( const fee_schedule_type& k )const{ return k.key_create_fee; } share_type calculate_fee(const fee_schedule_type& k)const{ return k.key_create_fee; }
void validate()const; void validate()const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -224,6 +224,10 @@ namespace graphene { namespace chain {
/** /**
* @ingroup operations * @ingroup operations
* @brief Update an existing account
*
* This operation is used to update an existing account. It can be used to update the authorities, or adjust the options on the account.
* See @ref account_object::options_type for the options which may be updated.
*/ */
struct account_update_operation struct account_update_operation
{ {
@ -342,7 +346,7 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return witness_account; } account_id_type fee_payer()const { return witness_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); }
}; };
@ -362,7 +366,7 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return to_account; } account_id_type fee_payer()const { return to_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const
{ {
@ -391,7 +395,7 @@ namespace graphene { namespace chain {
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
{ active_auth_set.insert(account_id_type()); } { active_auth_set.insert(account_id_type()); }
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); }
}; };
@ -469,23 +473,21 @@ namespace graphene { namespace chain {
*/ */
struct transfer_operation struct transfer_operation
{ {
/** paid by the from account, may be of any asset for which there is a funded fee pool asset fee;
**/ /// Account to transfer asset from
asset fee;
account_id_type from; account_id_type from;
/// Account to transfer asset to
account_id_type to; account_id_type to;
/** the amount and asset type that will be withdrawn from account "from" and added to account "to" /// The amount of asset to transfer from @ref from to @ref to
* asset amount;
**/
asset amount;
/** user provided data encrypted to the memo key of the "to" account */ /// User provided data encrypted to the memo key of the "to" account
optional<memo_data> memo; optional<memo_data> memo;
account_id_type fee_payer()const { return from; } account_id_type fee_payer()const { return from; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust( fee_payer(), -fee );
@ -523,7 +525,7 @@ namespace graphene { namespace chain {
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee( const fee_schedule_type& k )const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -546,8 +548,8 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return issuer; } account_id_type fee_payer()const { return issuer; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -574,8 +576,8 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return account; } account_id_type fee_payer()const { return account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust( fee_payer(), -fee );
acc.adjust( account, -amount ); acc.adjust( account, -amount );
@ -595,11 +597,11 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return from_account; } account_id_type fee_payer()const { return from_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
acc.adjust( fee_payer(), -amount ); acc.adjust(fee_payer(), -amount);
} }
}; };
@ -635,8 +637,8 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return issuer; } account_id_type fee_payer()const { return issuer; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -663,8 +665,8 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return issuer; } account_id_type fee_payer()const { return issuer; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -695,10 +697,9 @@ namespace graphene { namespace chain {
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
{ active_auth_set.insert(fee_payer()); } { active_auth_set.insert(fee_payer()); }
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const share_type calculate_fee(const fee_schedule_type& k)const;
{ return k.asset_update_fee; } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
{ acc.adjust( fee_payer(), -fee ); }
}; };
/** /**
@ -725,10 +726,10 @@ namespace graphene { namespace chain {
price_feed feed; price_feed feed;
account_id_type fee_payer()const { return publisher; } account_id_type fee_payer()const { return publisher; }
void get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee( const fee_schedule_type& k )const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset() )const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -748,9 +749,9 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return issuer; } account_id_type fee_payer()const { return issuer; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ acc.adjust( fee_payer(), -fee ); acc.adjust(issue_to_account, asset_to_issue); } { acc.adjust(fee_payer(), -fee); acc.adjust(issue_to_account, asset_to_issue); }
}; };
/** /**
@ -768,11 +769,11 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return payer; } account_id_type fee_payer()const { return payer; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
acc.adjust( fee_payer(), -amount_to_burn ); acc.adjust(fee_payer(), -amount_to_burn);
} }
}; };
@ -800,31 +801,29 @@ namespace graphene { namespace chain {
account_id_type seller; account_id_type seller;
asset amount_to_sell; asset amount_to_sell;
asset min_to_receive; asset min_to_receive;
/**
* This order should expire if not filled by expiration
*/
time_point_sec expiration = time_point_sec::maximum();
/** if this flag is set the entire order must be filled or /// The order will be removed from the books if not filled by expiration
* the operation is rejected. /// Upon expiration, all unsold asset will be returned to seller
*/ time_point_sec expiration = time_point_sec::maximum();
bool fill_or_kill = false;
/// If this flag is set the entire order must be filled or the operation is rejected
bool fill_or_kill = false;
pair<asset_id_type,asset_id_type> get_market()const pair<asset_id_type,asset_id_type> get_market()const
{ {
return amount_to_sell.asset_id < min_to_receive.asset_id ? return amount_to_sell.asset_id < min_to_receive.asset_id ?
std::make_pair( amount_to_sell.asset_id, min_to_receive.asset_id ) : std::make_pair(amount_to_sell.asset_id, min_to_receive.asset_id) :
std::make_pair( min_to_receive.asset_id, amount_to_sell.asset_id ); std::make_pair(min_to_receive.asset_id, amount_to_sell.asset_id);
} }
account_id_type fee_payer()const { return seller; } account_id_type fee_payer()const { return seller; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
price get_price()const { return amount_to_sell / min_to_receive; } price get_price()const { return amount_to_sell / min_to_receive; }
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
acc.adjust( seller, -amount_to_sell ); acc.adjust(seller, -amount_to_sell);
} }
}; };
@ -846,12 +845,11 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return fee_paying_account; } account_id_type fee_payer()const { return fee_paying_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
acc.adjust( fee_payer(), result.get<asset>() ); acc.adjust(fee_payer(), result.get<asset>());
} }
}; };
@ -878,12 +876,12 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return funding_account; } account_id_type fee_payer()const { return funding_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
acc.adjust( funding_account, -delta_collateral ); acc.adjust(funding_account, -delta_collateral);
acc.adjust( funding_account, delta_debt ); acc.adjust(funding_account, delta_debt);
} }
}; };
@ -943,9 +941,9 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return fee_paying_account; } account_id_type fee_payer()const { return fee_paying_account; }
void get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const; void get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const { return 0; } share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -981,8 +979,8 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return fee_paying_account; } account_id_type fee_payer()const { return fee_paying_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& owner_auth_set)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& owner_auth_set)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const { return 0; } share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -1006,8 +1004,9 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return fee_paying_account; } account_id_type fee_payer()const { return fee_paying_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& owner_auth_set)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& owner_auth_set)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const { return 0; } share_type calculate_fee(const fee_schedule_type& k)const
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } { return k.proposal_delete_fee; }
void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
///@} ///@}
@ -1037,10 +1036,12 @@ namespace graphene { namespace chain {
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
{ active_auth_set.insert(fee_payer()); } { active_auth_set.insert(fee_payer()); }
void validate()const { FC_ASSERT( !"virtual operation" ); } void validate()const { FC_ASSERT( !"virtual operation" ); }
share_type calculate_fee( const fee_schedule_type& k )const { return share_type(); } share_type calculate_fee(const fee_schedule_type& k)const
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { // This is a virtual operation; there is no fee
// acc.adjust( fee_payer(), -fee ); fee never actually entered the account, this is a virtual operation { return 0; }
acc.adjust( account_id, receives );
void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const {
acc.adjust(account_id, receives);
} }
}; };
@ -1082,8 +1083,8 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return withdraw_from_account; } account_id_type fee_payer()const { return withdraw_from_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -1118,8 +1119,8 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return withdraw_from_account; } account_id_type fee_payer()const { return withdraw_from_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); } void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); }
}; };
/** /**
@ -1153,12 +1154,12 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return withdraw_to_account; } account_id_type fee_payer()const { return withdraw_to_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
acc.adjust( withdraw_to_account, amount_to_withdraw ); acc.adjust(withdraw_to_account, amount_to_withdraw);
acc.adjust( withdraw_from_account, -amount_to_withdraw ); acc.adjust(withdraw_from_account, -amount_to_withdraw);
} }
}; };
@ -1183,10 +1184,10 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return withdraw_from_account; } account_id_type fee_payer()const { return withdraw_from_account; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
} }
}; };
@ -1198,16 +1199,15 @@ namespace graphene { namespace chain {
uint32_t vesting_seconds = 0; uint32_t vesting_seconds = 0;
}; };
struct ccd_vesting_policy_initializer struct cdd_vesting_policy_initializer
{ {
/** while coindays may accrue over time, none may be claimed before the start_claim time */ /** while coindays may accrue over time, none may be claimed before the start_claim time */
fc::time_point_sec start_claim; fc::time_point_sec start_claim;
uint32_t vesting_seconds = 0; uint32_t vesting_seconds = 0;
ccd_vesting_policy_initializer( uint32_t vest_sec = 0, fc::time_point_sec sc = fc::time_point_sec() ):start_claim(sc),vesting_seconds(vest_sec){} cdd_vesting_policy_initializer( uint32_t vest_sec = 0, fc::time_point_sec sc = fc::time_point_sec() ):start_claim(sc),vesting_seconds(vest_sec){}
}; };
typedef fc::static_variant< linear_vesting_policy_initializer, ccd_vesting_policy_initializer > vesting_policy_initializer; typedef fc::static_variant<linear_vesting_policy_initializer, cdd_vesting_policy_initializer> vesting_policy_initializer;
/** /**
* @brief Create a vesting balance. * @brief Create a vesting balance.
@ -1229,19 +1229,19 @@ namespace graphene { namespace chain {
struct vesting_balance_create_operation struct vesting_balance_create_operation
{ {
asset fee; asset fee;
account_id_type creator; ///< Who provides funds initially account_id_type creator; ///< Who provides funds initially
account_id_type owner; ///< Who is able to withdraw the balance account_id_type owner; ///< Who is able to withdraw the balance
asset amount; asset amount;
vesting_policy_initializer policy; vesting_policy_initializer policy;
account_id_type fee_payer()const { return creator; } account_id_type fee_payer()const { return creator; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
acc.adjust( creator, -amount ); acc.adjust(creator, -amount);
} }
}; };
@ -1259,17 +1259,17 @@ namespace graphene { namespace chain {
{ {
asset fee; asset fee;
vesting_balance_id_type vesting_balance; vesting_balance_id_type vesting_balance;
account_id_type owner; ///< Must be vesting_balance.owner account_id_type owner; ///< Must be vesting_balance.owner
asset amount; asset amount;
account_id_type fee_payer()const { return owner; } account_id_type fee_payer()const { return owner; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
acc.adjust( owner, amount ); acc.adjust(owner, amount);
} }
}; };
@ -1315,10 +1315,10 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return owner; } account_id_type fee_payer()const { return owner; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
} }
}; };
@ -1342,10 +1342,10 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return payer; } account_id_type fee_payer()const { return payer; }
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const; void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
void validate()const; void validate()const;
share_type calculate_fee( const fee_schedule_type& k )const; share_type calculate_fee(const fee_schedule_type& k)const;
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const
{ {
acc.adjust( fee_payer(), -fee ); acc.adjust(fee_payer(), -fee);
} }
}; };
@ -1628,5 +1628,5 @@ FC_REFLECT_TYPENAME( graphene::chain::operation )
FC_REFLECT_TYPENAME( graphene::chain::operation_result ) FC_REFLECT_TYPENAME( graphene::chain::operation_result )
FC_REFLECT_TYPENAME( fc::flat_set<graphene::chain::vote_id_type> ) FC_REFLECT_TYPENAME( fc::flat_set<graphene::chain::vote_id_type> )
FC_REFLECT(graphene::chain::linear_vesting_policy_initializer, (start_claim)(begin_date)(vesting_seconds) ) FC_REFLECT(graphene::chain::linear_vesting_policy_initializer, (start_claim)(begin_date)(vesting_seconds) )
FC_REFLECT(graphene::chain::ccd_vesting_policy_initializer, (start_claim)(vesting_seconds) ) FC_REFLECT(graphene::chain::cdd_vesting_policy_initializer, (start_claim)(vesting_seconds) )
FC_REFLECT_TYPENAME( graphene::chain::vesting_policy_initializer ) FC_REFLECT_TYPENAME( graphene::chain::vesting_policy_initializer )

View file

@ -18,7 +18,6 @@
#pragma once #pragma once
#include <fc/container/flat_fwd.hpp> #include <fc/container/flat_fwd.hpp>
#include <fc/io/varint.hpp> #include <fc/io/varint.hpp>
#include <fc/io/raw_fwd.hpp>
#include <fc/io/enum_type.hpp> #include <fc/io/enum_type.hpp>
#include <fc/crypto/sha224.hpp> #include <fc/crypto/sha224.hpp>
#include <fc/crypto/elliptic.hpp> #include <fc/crypto/elliptic.hpp>
@ -28,6 +27,7 @@
#include <fc/safe.hpp> #include <fc/safe.hpp>
#include <fc/container/flat.hpp> #include <fc/container/flat.hpp>
#include <fc/string.hpp> #include <fc/string.hpp>
#include <fc/io/raw.hpp>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <deque> #include <deque>
@ -337,45 +337,77 @@ namespace graphene { namespace chain {
fee_schedule_type() fee_schedule_type()
{ {
memset( (char*)this, 0, sizeof(*this) ); memset((char*)this, 0, sizeof(*this));
}
/// The number of bytes to charge a data fee for
const static int BYTES_PER_DATA_FEE = 1024;
template <class... Ts>
uint32_t total_data_fee(Ts... ts)const {
return data_size(ts...) / BYTES_PER_DATA_FEE * data_fee;
} }
uint32_t key_create_fee; ///< the cost to register a public key with the blockchain uint32_t key_create_fee; ///< the cost to register a public key with the blockchain
uint32_t account_create_fee; ///< the cost to register the cheapest non-free account uint32_t account_create_fee; ///< the cost to register the cheapest non-free account
uint32_t account_len8_fee; uint32_t account_update_fee; ///< the cost to update an existing account
uint32_t account_transfer_fee; ///< the cost to transfer an account to a new owner
uint32_t account_len8up_fee;
uint32_t account_len7_fee; uint32_t account_len7_fee;
uint32_t account_len6_fee; uint32_t account_len6_fee;
uint32_t account_len5_fee; uint32_t account_len5_fee;
uint32_t account_len4_fee; uint32_t account_len4_fee;
uint32_t account_len3_fee; uint32_t account_len3_fee;
uint32_t account_len2_fee; uint32_t account_len2_fee;
uint32_t account_premium_fee; ///< accounts with premium names; i.e. @ref is_cheap_name returns false uint32_t asset_len3_fee;
uint32_t asset_len4_fee;
uint32_t asset_len5_fee;
uint32_t asset_len6_fee;
uint32_t asset_len7up_fee;
uint32_t account_whitelist_fee; ///< the fee to whitelist an account uint32_t account_whitelist_fee; ///< the fee to whitelist an account
uint32_t delegate_create_fee; ///< fixed fee for registering as a delegate; used to discourage frivioulous delegates uint32_t delegate_create_fee; ///< fixed fee for registering as a delegate; used to discourage frivolous delegates
uint32_t witness_withdraw_pay_fee; ///< fee for withdrawing witness pay uint32_t witness_withdraw_pay_fee; ///< fee for withdrawing witness pay
uint32_t transfer_fee; ///< fee for transferring some asset uint32_t transfer_fee; ///< fee for transferring some asset
uint32_t limit_order_fee; ///< fee for placing a limit order in the markets uint32_t limit_order_create_fee; ///< fee for placing a limit order in the markets
uint32_t limit_order_cancel_fee; ///< fee for canceling a limit order
uint32_t call_order_fee; ///< fee for placing a call order in the markets uint32_t call_order_fee; ///< fee for placing a call order in the markets
uint32_t publish_feed_fee; ///< fee for publishing a price feed uint32_t publish_feed_fee; ///< fee for publishing a price feed
uint32_t asset_create_fee; ///< the cost to register the cheapest asset uint32_t asset_create_fee; ///< the cost to register the cheapest asset
uint32_t asset_update_fee; ///< the cost to modify a registered asset uint32_t asset_update_fee; ///< the cost to modify a registered asset
uint32_t asset_issue_fee; ///< the cost to modify a registered asset uint32_t asset_issue_fee; ///< the cost to modify a registered asset
uint32_t asset_burn_fee; ///< the cost to burn an asset
uint32_t asset_fund_fee_pool_fee; ///< the cost to add funds to an asset's fee pool uint32_t asset_fund_fee_pool_fee; ///< the cost to add funds to an asset's fee pool
uint32_t asset_settle_fee; ///< the cost to trigger a forced settlement of a market-issued asset uint32_t asset_settle_fee; ///< the cost to trigger a forced settlement of a market-issued asset
uint32_t market_fee; ///< a percentage charged on market orders uint32_t market_fee; ///< a percentage charged on market orders
uint32_t transaction_fee; ///< a base price for every transaction uint32_t transaction_fee; ///< a base price for every transaction
uint32_t data_fee; ///< a price per 1024 bytes of user data uint32_t data_fee; ///< a price per BYTES_PER_DATA_FEE bytes of user data
uint32_t signature_fee; ///< a surcharge on transactions with more than 2 signatures. uint32_t signature_fee; ///< a surcharge on transactions with more than 2 signatures.
uint32_t global_parameters_update_fee; ///< the cost to update the global parameters uint32_t global_parameters_update_fee; ///< the cost to update the global parameters
uint32_t membership_annual_fee; ///< the annual cost of a membership subscription uint32_t membership_annual_fee; ///< the annual cost of a membership subscription
uint32_t membership_lifetime_fee; ///< the cost to upgrade to a lifetime member uint32_t membership_lifetime_fee; ///< the cost to upgrade to a lifetime member
uint32_t withdraw_permission_update_fee; ///< the cost to create/update a withdraw permission uint32_t withdraw_permission_create_fee; ///< the cost to create a withdraw permission
uint32_t withdraw_permission_update_fee; ///< the cost to update a withdraw permission
uint32_t withdraw_permission_claim_fee; ///< the cost to withdraw from a withdraw permission
uint32_t withdraw_permission_delete_fee; ///< the cost to delete a withdraw permission
uint32_t vesting_balance_create_fee; uint32_t vesting_balance_create_fee;
uint32_t vesting_balance_withdraw_fee; uint32_t vesting_balance_withdraw_fee;
uint32_t global_settle_fee; uint32_t global_settle_fee;
uint32_t worker_create_fee; ///< the cost to create a new worker uint32_t worker_create_fee; ///< the cost to create a new worker
uint32_t worker_delete_fee; ///< the cost to delete a worker uint32_t worker_delete_fee; ///< the cost to delete a worker
uint32_t assert_op_fee; ///< fee per assert operation uint32_t assert_op_fee; ///< fee per assert operation
uint32_t proposal_create_fee; ///< fee for creating a proposed transaction
uint32_t proposal_update_fee; ///< fee for adding or removing approval of a proposed transaction
uint32_t proposal_delete_fee; ///< fee for deleting a proposed transaction
uint32_t custom_operation_fee; ///< fee for a custom operation
protected:
size_t data_size()const {
return 0;
}
template <class T, class... Ts>
size_t data_size(T t, Ts... ts)const {
return fc::raw::pack_size(t) + data_size(ts...);
}
}; };
@ -515,43 +547,57 @@ FC_REFLECT_ENUM( graphene::chain::meta_info_object_type, (meta_account_object_ty
FC_REFLECT( graphene::chain::fee_schedule_type, FC_REFLECT( graphene::chain::fee_schedule_type,
(key_create_fee) (key_create_fee)
(account_create_fee) (account_create_fee)
(account_len8_fee) (account_update_fee)
(account_len7_fee) (account_transfer_fee)
(account_len6_fee) (account_len8up_fee)
(account_len5_fee) (account_len7_fee)
(account_len4_fee) (account_len6_fee)
(account_len3_fee) (account_len5_fee)
(account_len2_fee) (account_len4_fee)
(account_premium_fee) (account_len3_fee)
(account_whitelist_fee) (account_len2_fee)
(delegate_create_fee) (asset_len3_fee)
(witness_withdraw_pay_fee) (asset_len4_fee)
(transfer_fee) (asset_len5_fee)
(limit_order_fee) (asset_len6_fee)
(call_order_fee) (asset_len7up_fee)
(publish_feed_fee) (account_whitelist_fee)
(asset_create_fee) (delegate_create_fee)
(asset_update_fee) (witness_withdraw_pay_fee)
(asset_issue_fee) (transfer_fee)
(asset_fund_fee_pool_fee) (limit_order_create_fee)
(asset_settle_fee) (limit_order_cancel_fee)
(market_fee) (call_order_fee)
(transaction_fee) (publish_feed_fee)
(data_fee) (asset_create_fee)
(signature_fee) (asset_update_fee)
(global_parameters_update_fee) (asset_issue_fee)
(membership_annual_fee) (asset_burn_fee)
(membership_lifetime_fee) (asset_fund_fee_pool_fee)
(withdraw_permission_update_fee) (asset_settle_fee)
(vesting_balance_create_fee) (market_fee)
(vesting_balance_withdraw_fee) (transaction_fee)
(global_settle_fee) (data_fee)
(worker_create_fee) (signature_fee)
(worker_delete_fee) (global_parameters_update_fee)
(assert_op_fee) (membership_annual_fee)
) (membership_lifetime_fee)
(withdraw_permission_create_fee)
(withdraw_permission_update_fee)
(withdraw_permission_claim_fee)
(withdraw_permission_delete_fee)
(vesting_balance_create_fee)
(vesting_balance_withdraw_fee)
(global_settle_fee)
(worker_create_fee)
(worker_delete_fee)
(assert_op_fee)
(proposal_create_fee)
(proposal_update_fee)
(proposal_delete_fee)
)
FC_REFLECT( graphene::chain::chain_parameters, FC_REFLECT( graphene::chain::chain_parameters,
(current_fees) (current_fees)

View file

@ -112,12 +112,13 @@ share_type account_create_operation::calculate_fee( const fee_schedule_type& sch
auto core_fee_required = schedule.account_create_fee; auto core_fee_required = schedule.account_create_fee;
uint32_t s = name.size(); uint32_t s = name.size();
if( is_cheap_name( name ) ) s = 63; if( is_cheap_name(name) )
s = 63;
FC_ASSERT( s >= 2 ); FC_ASSERT( s >= 2 );
if( s >= 8 && s < 63 ) if( s >= 8 && s < 63 )
core_fee_required = schedule.account_len8_fee; core_fee_required = schedule.account_len8up_fee;
else if( s == 7 ) else if( s == 7 )
core_fee_required = schedule.account_len7_fee; core_fee_required = schedule.account_len7_fee;
else if( s == 6 ) else if( s == 6 )
@ -131,19 +132,25 @@ share_type account_create_operation::calculate_fee( const fee_schedule_type& sch
else if( s == 2 ) else if( s == 2 )
core_fee_required = schedule.account_len2_fee; core_fee_required = schedule.account_len2_fee;
// Authorities and vote lists can be arbitrarily large, so charge a data fee for big ones
core_fee_required += schedule.total_data_fee(active, owner, options.votes);
return core_fee_required; return core_fee_required;
} }
share_type account_update_operation::calculate_fee( const fee_schedule_type& schedule )const share_type account_update_operation::calculate_fee( const fee_schedule_type& schedule )const
{ {
return schedule.account_create_fee; auto core_fee_required = schedule.account_update_fee + schedule.total_data_fee(owner, active);
if( new_options )
core_fee_required += schedule.total_data_fee(new_options->votes);
return core_fee_required;
} }
void account_update_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, void account_update_operation::get_required_auth(flat_set<account_id_type>& active_auth_set,
flat_set<account_id_type>& owner_auth_set) const flat_set<account_id_type>& owner_auth_set) const
{ {
if( owner || active ) if( owner || active )
owner_auth_set.insert( account ); owner_auth_set.insert(account);
else else
active_auth_set.insert( account ); active_auth_set.insert(account);
} }
void account_update_operation::validate()const void account_update_operation::validate()const
@ -156,14 +163,25 @@ void account_update_operation::validate()const
new_options->validate(); new_options->validate();
} }
share_type asset_create_operation::calculate_fee( const fee_schedule_type& schedule )const share_type asset_create_operation::calculate_fee(const fee_schedule_type& schedule)const
{ {
auto core_fee_required = schedule.asset_create_fee; auto core_fee_required = schedule.asset_create_fee;
uint32_t s = symbol.size(); switch(symbol.size()) {
while( s <= 6 ) { core_fee_required *= 30; ++s; } case 3: core_fee_required += schedule.asset_len3_fee;
break;
case 4: core_fee_required += schedule.asset_len4_fee;
break;
case 5: core_fee_required += schedule.asset_len5_fee;
break;
case 6: core_fee_required += schedule.asset_len6_fee;
break;
default: core_fee_required += schedule.asset_len7up_fee;
}
// common_options contains several lists and a string. Charge fees for its size
core_fee_required += schedule.total_data_fee(common_options);
core_fee_required += ((fc::raw::pack_size(*this)*schedule.data_fee)/1024);
return core_fee_required; return core_fee_required;
} }
@ -171,9 +189,7 @@ share_type transfer_operation::calculate_fee( const fee_schedule_type& schedule
{ {
share_type core_fee_required = schedule.transfer_fee; share_type core_fee_required = schedule.transfer_fee;
if( memo ) if( memo )
{ core_fee_required += schedule.total_data_fee(memo->message);
core_fee_required += share_type((memo->message.size() * schedule.data_fee)/1024);
}
return core_fee_required; return core_fee_required;
} }
@ -249,7 +265,7 @@ void asset_create_operation::get_required_auth(flat_set<account_id_type>& active
void asset_create_operation::validate()const void asset_create_operation::validate()const
{ {
FC_ASSERT( fee.amount >= 0 ); FC_ASSERT( fee.amount >= 0 );
FC_ASSERT( is_valid_symbol( symbol ) ); FC_ASSERT( is_valid_symbol(symbol) );
common_options.validate(); common_options.validate();
if( common_options.issuer_permissions & (disable_force_settle|global_settle) ) if( common_options.issuer_permissions & (disable_force_settle|global_settle) )
FC_ASSERT( bitasset_options.valid() ); FC_ASSERT( bitasset_options.valid() );
@ -288,9 +304,9 @@ void asset_update_operation::validate()const
FC_ASSERT(dummy.asset_id == asset_id_type()); FC_ASSERT(dummy.asset_id == asset_id_type());
} }
share_type asset_update_operation::calculate_fee( const fee_schedule_type& k )const share_type asset_update_operation::calculate_fee(const fee_schedule_type& k)const
{ {
return k.asset_update_fee + ((fc::raw::pack_size(*this)*k.data_fee)/1024); return k.asset_update_fee + k.total_data_fee(new_options);
} }
void asset_burn_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const void asset_burn_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const
@ -305,9 +321,9 @@ void asset_burn_operation::validate()const
FC_ASSERT( amount_to_burn.amount.value > 0 ); FC_ASSERT( amount_to_burn.amount.value > 0 );
} }
share_type asset_burn_operation::calculate_fee( const fee_schedule_type& k )const share_type asset_burn_operation::calculate_fee(const fee_schedule_type& k)const
{ {
return k.asset_issue_fee; return k.asset_burn_fee;
} }
void asset_issue_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const void asset_issue_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const
@ -330,7 +346,7 @@ share_type asset_issue_operation::calculate_fee( const fee_schedule_type& k )con
share_type delegate_create_operation::calculate_fee( const fee_schedule_type& k )const share_type delegate_create_operation::calculate_fee( const fee_schedule_type& k )const
{ {
return k.delegate_create_fee ; return k.delegate_create_fee + k.total_data_fee(url);
} }
void delegate_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const void delegate_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const
@ -376,7 +392,7 @@ void limit_order_create_operation::validate()const
share_type limit_order_create_operation::calculate_fee(const fee_schedule_type& k) const share_type limit_order_create_operation::calculate_fee(const fee_schedule_type& k) const
{ {
return k.limit_order_fee; return k.limit_order_create_fee;
} }
void limit_order_cancel_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const void limit_order_cancel_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const
@ -391,10 +407,9 @@ void limit_order_cancel_operation::validate()const
share_type limit_order_cancel_operation::calculate_fee(const fee_schedule_type& k) const share_type limit_order_cancel_operation::calculate_fee(const fee_schedule_type& k) const
{ {
return k.limit_order_fee; return k.limit_order_create_fee;
} }
void call_order_update_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const void call_order_update_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const
{ {
active_auth_set.insert(funding_account); active_auth_set.insert(funding_account);
@ -433,6 +448,11 @@ void proposal_create_operation::validate() const
for( const auto& op : proposed_ops ) op.validate(); for( const auto& op : proposed_ops ) op.validate();
} }
share_type proposal_create_operation::calculate_fee(const fee_schedule_type& k) const
{
return k.proposal_create_fee + k.total_data_fee(proposed_ops);
}
void proposal_update_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, void proposal_update_operation::get_required_auth(flat_set<account_id_type>& active_auth_set,
flat_set<account_id_type>& owner_auth_set) const flat_set<account_id_type>& owner_auth_set) const
{ {
@ -470,13 +490,23 @@ void proposal_update_operation::validate() const
} }
} }
share_type proposal_update_operation::calculate_fee(const fee_schedule_type& k) const
{
return k.proposal_create_fee + k.total_data_fee(active_approvals_to_add,
active_approvals_to_remove,
owner_approvals_to_add,
owner_approvals_to_remove,
key_approvals_to_add,
key_approvals_to_remove);
}
void proposal_delete_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, void proposal_delete_operation::get_required_auth(flat_set<account_id_type>& active_auth_set,
flat_set<account_id_type>& owner_auth_set) const flat_set<account_id_type>& owner_auth_set) const
{ {
if( using_owner_authority ) if( using_owner_authority )
owner_auth_set.insert(fee_paying_account); owner_auth_set.insert(fee_paying_account);
else else
active_auth_set.insert(fee_paying_account); active_auth_set.insert(fee_paying_account);
} }
void account_transfer_operation::validate()const void account_transfer_operation::validate()const
@ -491,7 +521,7 @@ void account_transfer_operation::get_required_auth(flat_set<account_id_type>& ac
share_type account_transfer_operation::calculate_fee( const fee_schedule_type& k )const share_type account_transfer_operation::calculate_fee( const fee_schedule_type& k )const
{ {
return k.transfer_fee; return k.account_transfer_fee;
} }
@ -545,7 +575,7 @@ void witness_create_operation::validate() const
share_type witness_create_operation::calculate_fee(const fee_schedule_type& k) const share_type witness_create_operation::calculate_fee(const fee_schedule_type& k) const
{ {
return k.delegate_create_fee; return k.delegate_create_fee + k.total_data_fee(url);
} }
void withdraw_permission_update_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const void withdraw_permission_update_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
@ -579,11 +609,11 @@ void withdraw_permission_claim_operation::validate()const
FC_ASSERT( fee.amount >= 0 ); FC_ASSERT( fee.amount >= 0 );
} }
share_type withdraw_permission_claim_operation::calculate_fee( const fee_schedule_type& schedule )const share_type withdraw_permission_claim_operation::calculate_fee(const fee_schedule_type& k)const
{ {
share_type core_fee_required = schedule.transfer_fee; share_type core_fee_required = k.withdraw_permission_claim_fee;
if( memo ) if( memo )
core_fee_required += share_type((memo->message.size() * schedule.data_fee)/1024); core_fee_required += k.total_data_fee(memo->message);
return core_fee_required; return core_fee_required;
} }
@ -600,7 +630,7 @@ void withdraw_permission_delete_operation::validate() const
share_type withdraw_permission_delete_operation::calculate_fee(const fee_schedule_type& k) const share_type withdraw_permission_delete_operation::calculate_fee(const fee_schedule_type& k) const
{ {
return k.withdraw_permission_update_fee; return k.withdraw_permission_delete_fee;
} }
void withdraw_permission_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const void withdraw_permission_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const
@ -620,7 +650,7 @@ void withdraw_permission_create_operation::validate() const
share_type withdraw_permission_create_operation::calculate_fee(const fee_schedule_type& k) const share_type withdraw_permission_create_operation::calculate_fee(const fee_schedule_type& k) const
{ {
return k.withdraw_permission_update_fee; return k.withdraw_permission_create_fee;
} }
@ -636,7 +666,7 @@ void asset_global_settle_operation::validate()const
FC_ASSERT( asset_to_settle == settle_price.base.asset_id ); FC_ASSERT( asset_to_settle == settle_price.base.asset_id );
} }
share_type asset_global_settle_operation::calculate_fee( const fee_schedule_type& k )const share_type asset_global_settle_operation::calculate_fee(const fee_schedule_type& k)const
{ {
return k.global_settle_fee; return k.global_settle_fee;
} }
@ -684,15 +714,21 @@ void asset_update_feed_producers_operation::validate() const
FC_ASSERT( fee.amount >= 0 ); FC_ASSERT( fee.amount >= 0 );
} }
void vesting_balance_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const share_type asset_update_feed_producers_operation::calculate_fee(const fee_schedule_type &k) const
{ {
// owner's authorization isn't needed since this is effectively a transfer of value TO the owner return k.asset_update_fee + k.total_data_fee(new_feed_producers);
active_auth_set.insert( creator );
} }
share_type vesting_balance_create_operation::calculate_fee( const fee_schedule_type& k )const void vesting_balance_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
{ {
return k.vesting_balance_create_fee; // owner's authorization isn't needed since this is effectively a transfer of value TO the owner
active_auth_set.insert(creator);
}
share_type vesting_balance_create_operation::calculate_fee(const fee_schedule_type& k)const
{
// We don't want to have custom inspection for each policy type; instead, charge a data fee for big ones
return k.vesting_balance_create_fee + k.total_data_fee(policy);
} }
void vesting_balance_create_operation::validate()const void vesting_balance_create_operation::validate()const
@ -703,7 +739,7 @@ void vesting_balance_create_operation::validate()const
void vesting_balance_withdraw_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const void vesting_balance_withdraw_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
{ {
active_auth_set.insert( owner ); active_auth_set.insert(owner);
} }
void vesting_balance_withdraw_operation::validate()const void vesting_balance_withdraw_operation::validate()const
@ -712,7 +748,7 @@ void vesting_balance_withdraw_operation::validate()const
FC_ASSERT( amount.amount > 0 ); FC_ASSERT( amount.amount > 0 );
} }
share_type vesting_balance_withdraw_operation::calculate_fee( const fee_schedule_type& k )const share_type vesting_balance_withdraw_operation::calculate_fee(const fee_schedule_type& k)const
{ {
return k.vesting_balance_withdraw_fee; return k.vesting_balance_withdraw_fee;
} }
@ -764,9 +800,9 @@ void custom_operation::validate()const
{ {
FC_ASSERT( fee.amount > 0 ); FC_ASSERT( fee.amount > 0 );
} }
share_type custom_operation::calculate_fee( const fee_schedule_type& k )const share_type custom_operation::calculate_fee(const fee_schedule_type& k)const
{ {
return (data.size() * k.data_fee)/1024; return k.custom_operation_fee + k.total_data_fee(required_auths, data);
} }
void worker_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const void worker_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const
@ -786,7 +822,8 @@ void worker_create_operation::validate() const
share_type worker_create_operation::calculate_fee(const fee_schedule_type& k) const share_type worker_create_operation::calculate_fee(const fee_schedule_type& k) const
{ {
return k.worker_create_fee; // Charge data fees for excessively long name, URL, or large initializers
return k.worker_create_fee + k.total_data_fee(name, url, initializer);
} }
string memo_message::serialize() const string memo_message::serialize() const
@ -853,11 +890,12 @@ void assert_operation::get_required_auth(flat_set<account_id_type>& active_auth_
} }
/** /**
* The fee for assert operations is proportional to their size * The fee for assert operations is proportional to their size,
* but cheaper than a data fee because they require no storage
*/ */
share_type assert_operation::calculate_fee( const fee_schedule_type& k )const share_type assert_operation::calculate_fee(const fee_schedule_type& k)const
{ {
return (k.assert_op_fee * fc::raw::pack_size(*this)) / 1024; return std::max(size_t(1), fc::raw::pack_size(*this) / 1024) * k.assert_op_fee;
} }
} } // namespace graphene::chain } } // namespace graphene::chain

View file

@ -61,7 +61,7 @@ struct init_policy_visitor
p = policy; p = policy;
} }
void operator()( const ccd_vesting_policy_initializer& i )const void operator()( const cdd_vesting_policy_initializer& i )const
{ {
cdd_vesting_policy policy; cdd_vesting_policy policy;
policy.vesting_seconds = i.vesting_seconds; policy.vesting_seconds = i.vesting_seconds;

View file

@ -238,4 +238,17 @@ BOOST_AUTO_TEST_CASE( witness_rng_test_bits )
} FC_LOG_AND_RETHROW() } FC_LOG_AND_RETHROW()
} }
BOOST_AUTO_TEST_CASE( data_fees )
{
fee_schedule_type fs;
fs.data_fee = 10;
int x = 1489520937;
BOOST_CHECK_EQUAL(fs.total_data_fee(), 0);
BOOST_CHECK_EQUAL(fs.total_data_fee(fs), 0);
BOOST_CHECK_EQUAL(fs.total_data_fee(fs.key_create_fee), 0);
BOOST_CHECK_EQUAL(fs.total_data_fee(x, fs, authority()), 0);
auto keys = vector<private_key_type>(100, private_key_type::generate());
BOOST_CHECK_EQUAL(fs.total_data_fee(keys, x), (fc::raw::pack_size(keys) + fc::raw::pack_size(x)) / 1024 * 10);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View file

@ -1388,7 +1388,7 @@ BOOST_AUTO_TEST_CASE( vesting_balance_create_test )
INVOKE( create_uia ); INVOKE( create_uia );
const asset_object& core = asset_id_type()(db); const asset_object& core = asset_id_type()(db);
const asset_object& test_asset = get_asset( "TEST" ); const asset_object& test_asset = get_asset("TEST");
vesting_balance_create_operation op; vesting_balance_create_operation op;
op.fee = core.amount( 0 ); op.fee = core.amount( 0 );
@ -1396,36 +1396,36 @@ BOOST_AUTO_TEST_CASE( vesting_balance_create_test )
op.owner = account_id_type(); op.owner = account_id_type();
op.amount = test_asset.amount( 100 ); op.amount = test_asset.amount( 100 );
//op.vesting_seconds = 60*60*24; //op.vesting_seconds = 60*60*24;
op.policy = ccd_vesting_policy_initializer{ 60*60*24 }; op.policy = cdd_vesting_policy_initializer{ 60*60*24 };
// Fee must be non-negative // Fee must be non-negative
REQUIRE_OP_VALIDATION_SUCCESS( op, fee, core.amount( 1 ) ); REQUIRE_OP_VALIDATION_SUCCESS( op, fee, core.amount(1) );
REQUIRE_OP_VALIDATION_SUCCESS( op, fee, core.amount( 0 ) ); REQUIRE_OP_VALIDATION_SUCCESS( op, fee, core.amount(0) );
REQUIRE_OP_VALIDATION_FAILURE( op, fee, core.amount( -1 ) ); REQUIRE_OP_VALIDATION_FAILURE( op, fee, core.amount(-1) );
// Amount must be positive // Amount must be positive
REQUIRE_OP_VALIDATION_SUCCESS( op, amount, core.amount( 1 ) ); REQUIRE_OP_VALIDATION_SUCCESS( op, amount, core.amount(1) );
REQUIRE_OP_VALIDATION_FAILURE( op, amount, core.amount( 0 ) ); REQUIRE_OP_VALIDATION_FAILURE( op, amount, core.amount(0) );
REQUIRE_OP_VALIDATION_FAILURE( op, amount, core.amount( -1 ) ); REQUIRE_OP_VALIDATION_FAILURE( op, amount, core.amount(-1) );
// Setup world state we will need to test actual evaluation // Setup world state we will need to test actual evaluation
const account_object& alice_account = create_account( "alice" ); const account_object& alice_account = create_account("alice");
const account_object& bob_account = create_account( "bob" ); const account_object& bob_account = create_account("bob");
transfer( genesis_account(db), alice_account, core.amount( 100000 ) ); transfer(genesis_account(db), alice_account, core.amount(100000));
op.creator = alice_account.get_id(); op.creator = alice_account.get_id();
op.owner = alice_account.get_id(); op.owner = alice_account.get_id();
account_id_type nobody = account_id_type( 1234 ); account_id_type nobody = account_id_type(1234);
trx.operations.push_back( op ); trx.operations.push_back(op);
// Invalid account_id's // Invalid account_id's
REQUIRE_THROW_WITH_VALUE( op, creator, nobody ); REQUIRE_THROW_WITH_VALUE( op, creator, nobody );
REQUIRE_THROW_WITH_VALUE( op, owner, nobody ); REQUIRE_THROW_WITH_VALUE( op, owner, nobody );
// Insufficient funds // Insufficient funds
REQUIRE_THROW_WITH_VALUE( op, amount, core.amount( 999999999 ) ); REQUIRE_THROW_WITH_VALUE( op, amount, core.amount(999999999) );
// Alice can fund a bond to herself or to Bob // Alice can fund a bond to herself or to Bob
op.amount = core.amount( 1000 ); op.amount = core.amount( 1000 );
REQUIRE_OP_EVALUATION_SUCCESS( op, owner, alice_account.get_id() ); REQUIRE_OP_EVALUATION_SUCCESS( op, owner, alice_account.get_id() );
@ -1485,7 +1485,7 @@ BOOST_AUTO_TEST_CASE( vesting_balance_withdraw_test )
create_op.creator = creator; create_op.creator = creator;
create_op.owner = owner; create_op.owner = owner;
create_op.amount = amount; create_op.amount = amount;
create_op.policy = ccd_vesting_policy_initializer( vesting_seconds ); create_op.policy = cdd_vesting_policy_initializer(vesting_seconds);
tx.operations.push_back( create_op ); tx.operations.push_back( create_op );
processed_transaction ptx = PUSH_TX( db, tx, ~0 ); processed_transaction ptx = PUSH_TX( db, tx, ~0 );