resource_count.cpp 16 KB
Newer Older
1

Bartek Wrona's avatar
Bartek Wrona committed
2 3
#include <hive/plugins/rc/resource_count.hpp>
#include <hive/plugins/rc/resource_sizes.hpp>
4

Bartek Wrona's avatar
Bartek Wrona committed
5
#include <hive/protocol/operations.hpp>
6

Bartek Wrona's avatar
Bartek Wrona committed
7
namespace hive { namespace plugins { namespace rc {
8

Bartek Wrona's avatar
Bartek Wrona committed
9
using namespace hive::protocol;
10 11 12

struct count_operation_visitor
{
Bartek Wrona's avatar
Bartek Wrona committed
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
  typedef void result_type;

  mutable int32_t market_op_count = 0;
  mutable int32_t new_account_op_count = 0;
  mutable int64_t state_bytes_count = 0;
  mutable int64_t execution_time_count = 0;

  const state_object_size_info& _w;
  const operation_exec_info& _e;

  count_operation_visitor( const state_object_size_info& w, const operation_exec_info& e ) : _w(w), _e(e) {}

  int64_t get_authority_byte_count( const authority& auth )const
  {
    return _w.authority_base_size
        + _w.authority_account_member_size * auth.account_auths.size()
        + _w.authority_key_member_size * auth.key_auths.size();
  }

  void operator()( const account_create_operation& op )const
  {
    state_bytes_count +=
        _w.account_object_base_size
      + _w.account_authority_object_base_size
      + get_authority_byte_count( op.owner )
      + get_authority_byte_count( op.active )
      + get_authority_byte_count( op.posting );
    execution_time_count += _e.account_create_operation_exec_time;
  }

  void operator()( const account_create_with_delegation_operation& op )const
  {
    state_bytes_count +=
        _w.account_object_base_size
      + _w.account_authority_object_base_size
      + get_authority_byte_count( op.owner )
      + get_authority_byte_count( op.active )
      + get_authority_byte_count( op.posting )
      + _w.vesting_delegation_object_base_size;
    execution_time_count += _e.account_create_with_delegation_operation_exec_time;
  }

  void operator()( const account_witness_vote_operation& op )const
  {
    state_bytes_count += _w.witness_vote_object_base_size;
    execution_time_count += _e.account_witness_vote_operation_exec_time;
  }

  void operator()( const comment_operation& op )const
  {
    state_bytes_count +=
        _w.comment_object_base_size
      + _w.comment_object_permlink_char_size * op.permlink.size()
      + _w.comment_object_parent_permlink_char_size * op.parent_permlink.size();
    execution_time_count += _e.comment_operation_exec_time;
  }

  void operator()( const comment_payout_beneficiaries& bens )const
  {
    state_bytes_count += _w.comment_object_beneficiaries_member_size * bens.beneficiaries.size();
  }

  void operator()( const comment_options_operation& op )const
  {
    for( const comment_options_extension& e : op.extensions )
    {
      e.visit( *this );
    }
    execution_time_count += _e.comment_options_operation_exec_time;
  }

  void operator()( const convert_operation& op ) const
  {
    state_bytes_count += _w.convert_request_object_base_size;
    execution_time_count += _e.convert_operation_exec_time;
  }

  void operator()( const create_claimed_account_operation& op )const
  {
    state_bytes_count +=
        _w.account_object_base_size
      + _w.account_authority_object_base_size
      + get_authority_byte_count( op.owner )
      + get_authority_byte_count( op.active )
      + get_authority_byte_count( op.posting );
    execution_time_count += _e.create_claimed_account_operation_exec_time;
  }

  void operator()( const decline_voting_rights_operation& op )const
  {
    state_bytes_count += _w.decline_voting_rights_request_object_base_size;
    execution_time_count += _e.decline_voting_rights_operation_exec_time;
  }

  void operator()( const delegate_vesting_shares_operation& op )const
  {
    state_bytes_count += std::max(
      _w.vesting_delegation_object_base_size,
      _w.vesting_delegation_expiration_object_base_size
      );
    execution_time_count += _e.delegate_vesting_shares_operation_exec_time;
  }

  void operator()( const escrow_transfer_operation& op )const
  {
    state_bytes_count += _w.escrow_object_base_size;
    execution_time_count += _e.escrow_transfer_operation_exec_time;
  }

  void operator()( const limit_order_create_operation& op )const
  {
    state_bytes_count += op.fill_or_kill ? 0 : _w.limit_order_object_base_size;
    execution_time_count += _e.limit_order_create_operation_exec_time;
    market_op_count++;
  }

  void operator()( const limit_order_create2_operation& op )const
  {
    state_bytes_count += op.fill_or_kill ? 0 : _w.limit_order_object_base_size;
    execution_time_count += _e.limit_order_create2_operation_exec_time;
    market_op_count++;
  }

  void operator()( const request_account_recovery_operation& op )const
  {
    state_bytes_count += _w.account_recovery_request_object_base_size;
    execution_time_count += _e.request_account_recovery_operation_exec_time;
  }

  void operator()( const set_withdraw_vesting_route_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    state_bytes_count += _w.withdraw_vesting_route_object_base_size;
    execution_time_count += _e.set_withdraw_vesting_route_operation_exec_time;
  }

  void operator()( const vote_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    state_bytes_count += _w.comment_vote_object_base_size;
    execution_time_count += _e.vote_operation_exec_time;
  }

  void operator()( const witness_update_operation& op )const
  {
    state_bytes_count +=
        _w.witness_object_base_size
      + _w.witness_object_url_char_size * op.url.size();
    execution_time_count += _e.witness_update_operation_exec_time;
  }

  void operator()( const transfer_operation& )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.transfer_operation_exec_time;
    market_op_count++;
  }

  void operator()( const transfer_to_vesting_operation& )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.transfer_to_vesting_operation_exec_time;
    market_op_count++;
  }

  void operator()( const transfer_to_savings_operation& )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.transfer_to_savings_operation_exec_time;
  }

  void operator()( const transfer_from_savings_operation& )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    state_bytes_count += _w.savings_withdraw_object_byte_size;
    execution_time_count += _e.transfer_from_savings_operation_exec_time;
  }

  void operator()( const claim_reward_balance_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.claim_reward_balance_operation_exec_time;
  }

  void operator()( const withdraw_vesting_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.withdraw_vesting_operation_exec_time;
  }

  void operator()( const account_update_operation& )const
  {
    execution_time_count += _e.account_update_operation_exec_time;
  }

  void operator()( const account_update2_operation& )const
  {
    execution_time_count += _e.account_update2_operation_exec_time;
  }

  void operator()( const account_witness_proxy_operation& )const
  {
    execution_time_count += _e.account_witness_proxy_operation_exec_time;
  }

  void operator()( const cancel_transfer_from_savings_operation& )const
  {
    execution_time_count += _e.cancel_transfer_from_savings_operation_exec_time;
  }

  void operator()( const change_recovery_account_operation& )const
  {
    execution_time_count += _e.change_recovery_account_operation_exec_time;
  }

  void operator()( const claim_account_operation& o )const
  {
    execution_time_count += _e.claim_account_operation_exec_time;

    if( o.fee.amount == 0 )
    {
      new_account_op_count++;
    }
  }

  void operator()( const custom_operation& )const
  {
    execution_time_count += _e.custom_operation_exec_time;
  }

  void operator()( const custom_json_operation& o )const
  {
    auto exec_time = _e.custom_operation_exec_time;

    if( o.id == "follow" )
    {
      exec_time *= EXEC_FOLLOW_CUSTOM_OP_SCALE;
    }

    execution_time_count += exec_time;
  }

  void operator()( const custom_binary_operation& o )const
  {
    auto exec_time = _e.custom_operation_exec_time;

    if( o.id == "follow" )
    {
      exec_time *= EXEC_FOLLOW_CUSTOM_OP_SCALE;
    }

    execution_time_count += exec_time;
  }

  void operator()( const delete_comment_operation& )const
  {
    execution_time_count += _e.delete_comment_operation_exec_time;
  }

  void operator()( const escrow_approve_operation& )const
  {
    execution_time_count += _e.escrow_approve_operation_exec_time;
  }

  void operator()( const escrow_dispute_operation& )const
  {
    execution_time_count += _e.escrow_dispute_operation_exec_time;
  }

  void operator()( const escrow_release_operation& )const
  {
    execution_time_count += _e.escrow_release_operation_exec_time;
  }

  void operator()( const feed_publish_operation& )const
  {
    execution_time_count += _e.feed_publish_operation_exec_time;
  }

  void operator()( const limit_order_cancel_operation& )const
  {
    execution_time_count += _e.limit_order_cancel_operation_exec_time;
  }

  void operator()( const witness_set_properties_operation& )const
  {
    execution_time_count += _e.witness_set_properties_operation_exec_time;
  }

#ifdef HIVE_ENABLE_SMT
  void operator()( const claim_reward_balance2_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.claim_reward_balance2_operation_exec_time;
  }

  void operator()( const smt_setup_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.smt_setup_operation_exec_time;
  }

  void operator()( const smt_setup_emissions_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.smt_setup_emissions_operation_exec_time;
  }

  void operator()( const smt_set_setup_parameters_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.smt_set_setup_parameters_operation_exec_time;
  }

  void operator()( const smt_set_runtime_parameters_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.smt_set_runtime_parameters_operation_exec_time;
  }

  void operator()( const smt_create_operation& op )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.smt_create_operation_exec_time;
  }

  void operator()( const allowed_vote_assets& )const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
  }

  void operator()( const smt_contribute_operation& op ) const
  {
    FC_TODO( "Change RC state bytes computation to take SMT's into account" )
    execution_time_count += _e.smt_contribute_operation_exec_time;
  }
349 350
#endif

Bartek Wrona's avatar
Bartek Wrona committed
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
  void operator()( const create_proposal_operation& op ) const
  {
    state_bytes_count += _w.proposal_object_base_size;
    state_bytes_count += sizeof( op.subject );
    state_bytes_count += sizeof( op.permlink );
    execution_time_count += _e.create_proposal_operation_exec_time;
  }

  void operator()( const update_proposal_operation& op ) const
  {
    state_bytes_count += _w.proposal_object_base_size;
    state_bytes_count += sizeof( op.subject );
    state_bytes_count += sizeof( op.permlink );
    execution_time_count += _e.update_proposal_operation_exec_time;
  }

  void operator()( const update_proposal_votes_operation& op ) const
  {
    state_bytes_count += _w.proposal_vote_object_base_size;
    state_bytes_count += _w.proposal_vote_object_member_size * op.proposal_ids.size();
    execution_time_count += _e.update_proposal_votes_operation_exec_time;
  }

  void operator()(const remove_proposal_operation&) const
  {
    execution_time_count += _e.remove_proposal_operation_exec_time;
  }

  void operator()( const recover_account_operation& ) const {}
  void operator()( const pow_operation& ) const {}
  void operator()( const pow2_operation& ) const {}
  void operator()( const report_over_production_operation& ) const {}
  void operator()( const reset_account_operation& ) const {}
  void operator()( const set_reset_account_operation& ) const {}

  // Virtual Ops
  void operator()( const fill_convert_request_operation& ) const {}
  void operator()( const author_reward_operation& ) const {}
  void operator()( const curation_reward_operation& ) const {}
  void operator()( const comment_reward_operation& ) const {}
  void operator()( const liquidity_reward_operation& ) const {}
  void operator()( const interest_operation& ) const {}
  void operator()( const fill_vesting_withdraw_operation& ) const {}
  void operator()( const fill_order_operation& ) const {}
  void operator()( const shutdown_witness_operation& ) const {}
  void operator()( const fill_transfer_from_savings_operation& ) const {}
  void operator()( const hardfork_operation& ) const {}
  void operator()( const comment_payout_update_operation& ) const {}
  void operator()(const effective_comment_vote_operation&) const {}
400
  void operator()(const ineffective_delete_comment_operation&) const {}
Bartek Wrona's avatar
Bartek Wrona committed
401 402 403 404 405 406 407 408 409 410 411 412
  void operator()( const return_vesting_delegation_operation& ) const {}
  void operator()( const comment_benefactor_reward_operation& ) const {}
  void operator()( const producer_reward_operation& ) const {}
  void operator()( const clear_null_account_balance_operation& ) const {}
  void operator()( const consolidate_treasury_balance_operation& ) const {}
  void operator()( const delayed_voting_operation& ) const {}
  void operator()( const proposal_pay_operation& ) const {}
  void operator()( const sps_fund_operation& ) const {}
  void operator()( const hardfork_hive_operation& ) const {}
  void operator()( const hardfork_hive_restore_operation& ) const {}

  // Optional Actions
Michael Vandeberg's avatar
Michael Vandeberg committed
413
#ifdef IS_TEST_NET
Bartek Wrona's avatar
Bartek Wrona committed
414
  void operator()( const example_optional_action& ) const {}
Michael Vandeberg's avatar
Michael Vandeberg committed
415
#endif
416

417

Bartek Wrona's avatar
Bartek Wrona committed
418 419 420 421 422 423
  // TODO:
  // Should following ops be market ops?
  // withdraw_vesting, convert, set_withdraw_vesting_route, limit_order_create2
  // escrow_transfer, escrow_dispute, escrow_release, escrow_approve,
  // transfer_to_savings, transfer_from_savings, cancel_transfer_from_savings,
  // claim_reward_balance, delegate_vesting_shares, any SMT operations
424 425
};

426 427
typedef count_operation_visitor count_optional_action_visitor;

428
void count_resources(
Bartek Wrona's avatar
Bartek Wrona committed
429 430
  const signed_transaction& tx,
  count_resources_result& result )
431
{
Bartek Wrona's avatar
Bartek Wrona committed
432 433 434 435
  static const state_object_size_info size_info;
  static const operation_exec_info exec_info;
  const int64_t tx_size = int64_t( fc::raw::pack_size( tx ) );
  count_operation_visitor vtor( size_info, exec_info );
436

Bartek Wrona's avatar
Bartek Wrona committed
437
  result.resource_count[ resource_history_bytes ] += tx_size;
438

Bartek Wrona's avatar
Bartek Wrona committed
439 440 441 442
  for( const operation& op : tx.operations )
  {
    op.visit( vtor );
  }
443

Bartek Wrona's avatar
Bartek Wrona committed
444
  result.resource_count[ resource_new_accounts ] += vtor.new_account_op_count;
445

Bartek Wrona's avatar
Bartek Wrona committed
446 447
  if( vtor.market_op_count > 0 )
    result.resource_count[ resource_market_bytes ] += tx_size;
448

Bartek Wrona's avatar
Bartek Wrona committed
449 450 451 452
  result.resource_count[ resource_state_bytes ] +=
      size_info.transaction_object_base_size
    + size_info.transaction_object_byte_size * tx_size
    + vtor.state_bytes_count;
453

Bartek Wrona's avatar
Bartek Wrona committed
454
  result.resource_count[ resource_execution_time ] += vtor.execution_time_count;
455 456
}

457
void count_resources(
Bartek Wrona's avatar
Bartek Wrona committed
458 459
  const optional_automated_action& action,
  count_resources_result& result )
460
{
Bartek Wrona's avatar
Bartek Wrona committed
461 462 463 464
  static const state_object_size_info size_info;
  static const operation_exec_info exec_info;
  const int64_t action_size = int64_t( fc::raw::pack_size( action ) );
  count_optional_action_visitor vtor( size_info, exec_info );
465

Bartek Wrona's avatar
Bartek Wrona committed
466
  result.resource_count[ resource_history_bytes ] += action_size;
467

Bartek Wrona's avatar
Bartek Wrona committed
468
  action.visit( vtor );
469

Bartek Wrona's avatar
Bartek Wrona committed
470 471
  // Not expecting actions to create accounts, but better to add it for completeness
  result.resource_count[ resource_new_accounts ] += vtor.new_account_op_count;
472

Bartek Wrona's avatar
Bartek Wrona committed
473
  result.resource_count[ resource_state_bytes ] += vtor.state_bytes_count;
474

Bartek Wrona's avatar
Bartek Wrona committed
475
  result.resource_count[ resource_execution_time ] += vtor.execution_time_count;
476 477
}

Bartek Wrona's avatar
Bartek Wrona committed
478
} } } // hive::plugins::rc