BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface software
db_init.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
27 
52 
70 
71 #include <fc/crypto/digest.hpp>
72 
73 #include <boost/algorithm/string.hpp>
74 
75 namespace graphene { namespace chain {
76 
77 // C++ requires that static class variables declared and initialized
78 // in headers must also have a definition in a single source file,
79 // else linker errors will occur [1].
80 //
81 // The purpose of this source file is to collect such definitions in
82 // a single place.
83 //
84 // [1] http://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char
85 
86 const uint8_t account_object::space_id;
87 const uint8_t account_object::type_id;
88 
89 const uint8_t asset_object::space_id;
90 const uint8_t asset_object::type_id;
91 
92 const uint8_t block_summary_object::space_id;
93 const uint8_t block_summary_object::type_id;
94 
95 const uint8_t call_order_object::space_id;
96 const uint8_t call_order_object::type_id;
97 
100 
103 
105 const uint8_t global_property_object::type_id;
106 
107 const uint8_t limit_order_object::space_id;
108 const uint8_t limit_order_object::type_id;
109 
112 
113 const uint8_t proposal_object::space_id;
114 const uint8_t proposal_object::type_id;
115 
118 
120 const uint8_t vesting_balance_object::type_id;
121 
124 
125 const uint8_t witness_object::space_id;
126 const uint8_t witness_object::type_id;
127 
128 const uint8_t worker_object::space_id;
129 const uint8_t worker_object::type_id;
130 
131 const uint8_t htlc_object::space_id;
132 const uint8_t htlc_object::type_id;
133 
136 
137 const uint8_t ticket_object::space_id;
138 const uint8_t ticket_object::type_id;
139 
141 {
142  _operation_evaluators.resize(255);
143  register_evaluator<account_create_evaluator>();
144  register_evaluator<account_update_evaluator>();
145  register_evaluator<account_upgrade_evaluator>();
146  register_evaluator<account_whitelist_evaluator>();
147  register_evaluator<committee_member_create_evaluator>();
148  register_evaluator<committee_member_update_evaluator>();
149  register_evaluator<committee_member_update_global_parameters_evaluator>();
150  register_evaluator<custom_evaluator>();
151  register_evaluator<asset_create_evaluator>();
152  register_evaluator<asset_issue_evaluator>();
153  register_evaluator<asset_reserve_evaluator>();
154  register_evaluator<asset_update_evaluator>();
155  register_evaluator<asset_update_bitasset_evaluator>();
156  register_evaluator<asset_update_feed_producers_evaluator>();
157  register_evaluator<asset_settle_evaluator>();
158  register_evaluator<asset_global_settle_evaluator>();
159  register_evaluator<assert_evaluator>();
160  register_evaluator<limit_order_create_evaluator>();
161  register_evaluator<limit_order_cancel_evaluator>();
162  register_evaluator<call_order_update_evaluator>();
163  register_evaluator<bid_collateral_evaluator>();
164  register_evaluator<transfer_evaluator>();
165  register_evaluator<override_transfer_evaluator>();
166  register_evaluator<asset_fund_fee_pool_evaluator>();
167  register_evaluator<asset_publish_feeds_evaluator>();
168  register_evaluator<proposal_create_evaluator>();
169  register_evaluator<proposal_update_evaluator>();
170  register_evaluator<proposal_delete_evaluator>();
171  register_evaluator<vesting_balance_create_evaluator>();
172  register_evaluator<vesting_balance_withdraw_evaluator>();
173  register_evaluator<witness_create_evaluator>();
174  register_evaluator<witness_update_evaluator>();
175  register_evaluator<withdraw_permission_create_evaluator>();
176  register_evaluator<withdraw_permission_claim_evaluator>();
177  register_evaluator<withdraw_permission_update_evaluator>();
178  register_evaluator<withdraw_permission_delete_evaluator>();
179  register_evaluator<worker_create_evaluator>();
180  register_evaluator<balance_claim_evaluator>();
181  register_evaluator<transfer_to_blind_evaluator>();
182  register_evaluator<transfer_from_blind_evaluator>();
183  register_evaluator<blind_transfer_evaluator>();
184  register_evaluator<asset_claim_fees_evaluator>();
185  register_evaluator<asset_update_issuer_evaluator>();
186  register_evaluator<asset_claim_pool_evaluator>();
187  register_evaluator<htlc_create_evaluator>();
188  register_evaluator<htlc_redeem_evaluator>();
189  register_evaluator<htlc_extend_evaluator>();
190  register_evaluator<custom_authority_create_evaluator>();
191  register_evaluator<custom_authority_update_evaluator>();
192  register_evaluator<custom_authority_delete_evaluator>();
193  register_evaluator<ticket_create_evaluator>();
194  register_evaluator<ticket_update_evaluator>();
195 }
196 
198 {
199  reset_indexes();
201 
202  //Protocol object indexes
203  add_index< primary_index<asset_index, 13> >(); // 8192 assets per chunk
204  add_index< primary_index<force_settlement_index> >();
205 
206  add_index< primary_index<account_index, 20> >(); // ~1 million accounts per chunk
207  add_index< primary_index<committee_member_index, 8> >(); // 256 members per chunk
208  add_index< primary_index<witness_index, 10> >(); // 1024 witnesses per chunk
209  add_index< primary_index<limit_order_index > >();
210  add_index< primary_index<call_order_index > >();
211  add_index< primary_index<proposal_index > >();
212  add_index< primary_index<withdraw_permission_index > >();
213  add_index< primary_index<vesting_balance_index> >();
214  add_index< primary_index<worker_index> >();
215  add_index< primary_index<balance_index> >();
216  add_index< primary_index<blinded_balance_index> >();
217  add_index< primary_index< htlc_index> >();
218  add_index< primary_index< custom_authority_index> >();
219  add_index< primary_index<ticket_index> >();
220 
221  //Implementation object indexes
222  add_index< primary_index<transaction_index > >();
223 
224  auto bal_idx = add_index< primary_index<account_balance_index > >();
225  bal_idx->add_secondary_index<balances_by_account_index>();
226 
227  add_index< primary_index<asset_bitasset_data_index, 13 > >(); // 8192
228  add_index< primary_index<simple_index<global_property_object >> >();
229  add_index< primary_index<simple_index<dynamic_global_property_object >> >();
230  add_index< primary_index<account_stats_index, 20 > >(); // 1 Mi
231  add_index< primary_index<simple_index<asset_dynamic_data_object >> >();
232  add_index< primary_index<simple_index<block_summary_object >> >();
233  add_index< primary_index<simple_index<chain_property_object > > >();
234  add_index< primary_index<simple_index<witness_schedule_object > > >();
235  add_index< primary_index<simple_index<budget_record_object > > >();
236  add_index< primary_index< special_authority_index > >();
237  add_index< primary_index< buyback_index > >();
238  add_index< primary_index<collateral_bid_index > >();
239  add_index< primary_index< simple_index< fba_accumulator_object > > >();
240 }
241 
242 void database::init_genesis(const genesis_state_type& genesis_state)
243 { try {
244  FC_ASSERT( genesis_state.initial_timestamp != time_point_sec(), "Must initialize genesis timestamp." );
246  "Genesis timestamp must be divisible by GRAPHENE_DEFAULT_BLOCK_INTERVAL." );
247  FC_ASSERT(genesis_state.initial_witness_candidates.size() > 0,
248  "Cannot start a chain with zero witnesses.");
249  FC_ASSERT(genesis_state.initial_active_witnesses <= genesis_state.initial_witness_candidates.size(),
250  "initial_active_witnesses is larger than the number of candidate witnesses.");
251 
252  _undo_db.disable();
253  struct auth_inhibitor {
254  auth_inhibitor(database& db) : db(db), old_flags(db.node_properties().skip_flags)
256  ~auth_inhibitor()
257  { db.node_properties().skip_flags = old_flags; }
258  private:
259  database& db;
260  uint32_t old_flags;
261  } inhibitor(*this);
262 
263  transaction_evaluation_state genesis_eval_state(this);
264 
265  // Create blockchain accounts
266  fc::ecc::private_key null_private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")));
267  create<account_balance_object>([](account_balance_object& b) {
268  b.balance = GRAPHENE_MAX_SHARE_SUPPLY;
269  });
270  const account_object& committee_account =
271  create<account_object>( [&](account_object& n) {
272  n.membership_expiration_date = time_point_sec::maximum();
273  n.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
274  n.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
275  n.owner.weight_threshold = 1;
276  n.active.weight_threshold = 1;
277  n.name = "committee-account";
278  n.statistics = create<account_statistics_object>( [&n](account_statistics_object& s){
279  s.owner = n.id;
280  s.name = n.name;
281  s.core_in_balance = GRAPHENE_MAX_SHARE_SUPPLY;
282  }).id;
283  });
284  FC_ASSERT(committee_account.get_id() == GRAPHENE_COMMITTEE_ACCOUNT);
285  FC_ASSERT(create<account_object>([this](account_object& a) {
286  a.name = "witness-account";
287  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
288  s.owner = a.id;
289  s.name = a.name;
290  }).id;
291  a.owner.weight_threshold = 1;
292  a.active.weight_threshold = 1;
297  }).get_id() == GRAPHENE_WITNESS_ACCOUNT);
298  FC_ASSERT(create<account_object>([this](account_object& a) {
299  a.name = "relaxed-committee-account";
300  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
301  s.owner = a.id;
302  s.name = a.name;
303  }).id;
304  a.owner.weight_threshold = 1;
305  a.active.weight_threshold = 1;
310  }).get_id() == GRAPHENE_RELAXED_COMMITTEE_ACCOUNT);
311  FC_ASSERT(create<account_object>([this](account_object& a) {
312  a.name = "null-account";
313  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
314  s.owner = a.id;
315  s.name = a.name;
316  }).id;
317  a.owner.weight_threshold = 1;
318  a.active.weight_threshold = 1;
323  }).get_id() == GRAPHENE_NULL_ACCOUNT);
324  FC_ASSERT(create<account_object>([this](account_object& a) {
325  a.name = "temp-account";
326  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
327  s.owner = a.id;
328  s.name = a.name;
329  }).id;
330  a.owner.weight_threshold = 0;
331  a.active.weight_threshold = 0;
336  }).get_id() == GRAPHENE_TEMP_ACCOUNT);
337  FC_ASSERT(create<account_object>([this](account_object& a) {
338  a.name = "proxy-to-self";
339  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
340  s.owner = a.id;
341  s.name = a.name;
342  }).id;
343  a.owner.weight_threshold = 1;
344  a.active.weight_threshold = 1;
349  }).get_id() == GRAPHENE_PROXY_TO_SELF_ACCOUNT);
350 
351  // Create more special accounts
352  while( true )
353  {
354  uint64_t id = get_index<account_object>().get_next_id().instance();
355  if( id >= genesis_state.immutable_parameters.num_special_accounts )
356  break;
357  const account_object& acct = create<account_object>([this,id](account_object& a) {
358  a.name = "special-account-" + std::to_string(id);
359  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
360  s.owner = a.id;
361  s.name = a.name;
362  }).id;
363  a.owner.weight_threshold = 1;
364  a.active.weight_threshold = 1;
365  a.registrar = a.lifetime_referrer = a.referrer = account_id_type(id);
369  });
370  FC_ASSERT( acct.get_id() == account_id_type(id) );
371  remove( acct );
372  }
373 
374  // Create core asset
375  const asset_dynamic_data_object& dyn_asset =
376  create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
377  a.current_supply = GRAPHENE_MAX_SHARE_SUPPLY;
378  });
379  const asset_object& core_asset =
380  create<asset_object>( [&genesis_state,&dyn_asset]( asset_object& a ) {
381  a.symbol = GRAPHENE_SYMBOL;
382  a.options.max_supply = genesis_state.max_core_supply;
384  a.options.flags = 0;
385  a.options.issuer_permissions = 0;
386  a.issuer = GRAPHENE_NULL_ACCOUNT;
387  a.options.core_exchange_rate.base.amount = 1;
388  a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
389  a.options.core_exchange_rate.quote.amount = 1;
390  a.options.core_exchange_rate.quote.asset_id = asset_id_type(0);
391  a.dynamic_asset_data_id = dyn_asset.id;
392  });
393  FC_ASSERT( dyn_asset.id == asset_dynamic_data_id_type() );
394  FC_ASSERT( asset_id_type(core_asset.id) == asset().asset_id );
395  FC_ASSERT( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) );
396  _p_core_asset_obj = &core_asset;
397  _p_core_dynamic_data_obj = &dyn_asset;
398  // Create more special assets
399  while( true )
400  {
401  uint64_t id = get_index<asset_object>().get_next_id().instance();
402  if( id >= genesis_state.immutable_parameters.num_special_assets )
403  break;
404  const asset_dynamic_data_object& dyn_asset =
405  create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
406  a.current_supply = 0;
407  });
408  const asset_object& asset_obj = create<asset_object>( [id,&dyn_asset]( asset_object& a ) {
409  a.symbol = "SPECIAL" + std::to_string( id );
410  a.options.max_supply = 0;
412  a.options.flags = 0;
413  a.options.issuer_permissions = 0;
414  a.issuer = GRAPHENE_NULL_ACCOUNT;
415  a.options.core_exchange_rate.base.amount = 1;
416  a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
417  a.options.core_exchange_rate.quote.amount = 1;
418  a.options.core_exchange_rate.quote.asset_id = asset_id_type(0);
419  a.dynamic_asset_data_id = dyn_asset.id;
420  });
421  FC_ASSERT( asset_obj.get_id() == asset_id_type(id) );
422  remove( asset_obj );
423  }
424 
425  chain_id_type chain_id = genesis_state.compute_chain_id();
426 
427  // Create global properties
428  _p_global_prop_obj = & create<global_property_object>([&genesis_state](global_property_object& p) {
429  p.parameters = genesis_state.initial_parameters;
430  // Set fees to zero initially, so that genesis initialization needs not pay them
431  // We'll fix it at the end of the function
432  p.parameters.get_mutable_fees().zero_all_fees();
433 
434  });
435  _p_dyn_global_prop_obj = & create<dynamic_global_property_object>([&genesis_state](dynamic_global_property_object& p) {
436  p.time = genesis_state.initial_timestamp;
437  p.dynamic_flags = 0;
438  p.witness_budget = 0;
439  p.recent_slots_filled = std::numeric_limits<fc::uint128_t>::max();
440  });
441 
442  FC_ASSERT( (genesis_state.immutable_parameters.min_witness_count & 1) == 1, "min_witness_count must be odd" );
443  FC_ASSERT( (genesis_state.immutable_parameters.min_committee_member_count & 1) == 1, "min_committee_member_count must be odd" );
444 
445  _p_chain_property_obj = & create<chain_property_object>([chain_id,&genesis_state](chain_property_object& p)
446  {
447  p.chain_id = chain_id;
448  p.immutable_parameters = genesis_state.immutable_parameters;
449  } );
450  for (uint32_t i = 0; i <= 0x10000; i++)
451  create<block_summary_object>( [&]( block_summary_object&) {});
452 
453  // Create initial accounts
454  for( const auto& account : genesis_state.initial_accounts )
455  {
457  cop.name = account.name;
459  cop.owner = authority(1, account.owner_key, 1);
460  if( account.active_key == public_key_type() )
461  {
462  cop.active = cop.owner;
463  cop.options.memo_key = account.owner_key;
464  }
465  else
466  {
467  cop.active = authority(1, account.active_key, 1);
468  cop.options.memo_key = account.active_key;
469  }
470  account_id_type account_id(apply_operation(genesis_eval_state, cop).get<object_id_type>());
471 
472  if( account.is_lifetime_member )
473  {
475  op.account_to_upgrade = account_id;
476  op.upgrade_to_lifetime_member = true;
477  apply_operation(genesis_eval_state, op);
478  }
479  }
480 
481  // Helper function to get account ID by name
482  const auto& accounts_by_name = get_index_type<account_index>().indices().get<by_name>();
483  auto get_account_id = [&accounts_by_name](const string& name) {
484  auto itr = accounts_by_name.find(name);
485  FC_ASSERT(itr != accounts_by_name.end(),
486  "Unable to find account '${acct}'. Did you forget to add a record for it to initial_accounts?",
487  ("acct", name));
488  return itr->get_id();
489  };
490 
491  // Helper function to get asset ID by symbol
492  const auto& assets_by_symbol = get_index_type<asset_index>().indices().get<by_symbol>();
493  const auto get_asset_id = [&assets_by_symbol](const string& symbol) {
494  auto itr = assets_by_symbol.find(symbol);
495  FC_ASSERT(itr != assets_by_symbol.end(),
496  "Unable to find asset '${sym}'. Did you forget to add a record for it to initial_assets?",
497  ("sym", symbol));
498  return itr->get_id();
499  };
500 
501  map<asset_id_type, share_type> total_supplies;
502  map<asset_id_type, share_type> total_debts;
503 
504  // Create initial assets
505  for( const genesis_state_type::initial_asset_type& asset : genesis_state.initial_assets )
506  {
507  asset_id_type new_asset_id = get_index_type<asset_index>().get_next_id();
508  total_supplies[ new_asset_id ] = 0;
509 
510  asset_dynamic_data_id_type dynamic_data_id;
511  optional<asset_bitasset_data_id_type> bitasset_data_id;
512  if( asset.is_bitasset )
513  {
514  int collateral_holder_number = 0;
515  total_debts[ new_asset_id ] = 0;
516  for( const auto& collateral_rec : asset.collateral_records )
517  {
519  cop.name = asset.symbol + "-collateral-holder-" + std::to_string(collateral_holder_number);
522  cop.owner = authority(1, collateral_rec.owner, 1);
523  cop.active = cop.owner;
524  account_id_type owner_account_id = apply_operation(genesis_eval_state, cop).get<object_id_type>();
525 
526  modify( owner_account_id(*this).statistics(*this), [&collateral_rec]( account_statistics_object& o ) {
527  o.total_core_in_orders = collateral_rec.collateral;
528  });
529 
530  create<call_order_object>([&](call_order_object& c) {
531  c.borrower = owner_account_id;
532  c.collateral = collateral_rec.collateral;
533  c.debt = collateral_rec.debt;
534  c.call_price = price::call_price(chain::asset(c.debt, new_asset_id),
535  chain::asset(c.collateral, core_asset.id),
537  });
538 
539  total_supplies[ asset_id_type(0) ] += collateral_rec.collateral;
540  total_debts[ new_asset_id ] += collateral_rec.debt;
541  ++collateral_holder_number;
542  }
543 
544  bitasset_data_id = create<asset_bitasset_data_object>([&core_asset,new_asset_id](asset_bitasset_data_object& b) {
545  b.options.short_backing_asset = core_asset.id;
546  b.options.minimum_feeds = GRAPHENE_DEFAULT_MINIMUM_FEEDS;
547  b.asset_id = new_asset_id;
548  }).id;
549  }
550 
551  dynamic_data_id = create<asset_dynamic_data_object>([&asset](asset_dynamic_data_object& d) {
552  d.accumulated_fees = asset.accumulated_fees;
553  }).id;
554 
555  total_supplies[ new_asset_id ] += asset.accumulated_fees;
556 
557  create<asset_object>([&](asset_object& a) {
558  a.symbol = asset.symbol;
559  a.options.description = asset.description;
560  a.precision = asset.precision;
561  string issuer_name = asset.issuer_name;
562  a.issuer = get_account_id(issuer_name);
563  a.options.max_supply = asset.max_supply;
564  a.options.flags = witness_fed_asset;
567  a.dynamic_asset_data_id = dynamic_data_id;
568  a.bitasset_data_id = bitasset_data_id;
569  });
570  }
571 
572  // Create initial balances
573  share_type total_allocation;
574  for( const auto& handout : genesis_state.initial_balances )
575  {
576  const auto asset_id = get_asset_id(handout.asset_symbol);
577  create<balance_object>([&handout,total_allocation,asset_id](balance_object& b) {
578  b.balance = asset(handout.amount, asset_id);
579  b.owner = handout.owner;
580  });
581 
582  total_supplies[ asset_id ] += handout.amount;
583  }
584 
585  // Create initial vesting balances
586  for( const genesis_state_type::initial_vesting_balance_type& vest : genesis_state.initial_vesting_balances )
587  {
588  const auto asset_id = get_asset_id(vest.asset_symbol);
589  create<balance_object>([&](balance_object& b) {
590  b.owner = vest.owner;
591  b.balance = asset(vest.amount, asset_id);
592 
593  linear_vesting_policy policy;
594  policy.begin_timestamp = vest.begin_timestamp;
595  policy.vesting_cliff_seconds = 0;
597  policy.begin_balance = vest.begin_balance;
598 
599  b.vesting_policy = std::move(policy);
600  });
601 
602  total_supplies[ asset_id ] += vest.amount;
603  }
604 
605  if( total_supplies[ asset_id_type(0) ] > 0 )
606  {
608  }
609  else
610  {
611  total_supplies[ asset_id_type(0) ] = GRAPHENE_MAX_SHARE_SUPPLY;
612  }
613 
614  const auto& idx = get_index_type<asset_index>().indices().get<by_symbol>();
615  auto it = idx.begin();
616  bool has_imbalanced_assets = false;
617 
618  while( it != idx.end() )
619  {
620  if( it->bitasset_data_id.valid() )
621  {
622  auto supply_itr = total_supplies.find( it->id );
623  auto debt_itr = total_debts.find( it->id );
624  FC_ASSERT( supply_itr != total_supplies.end() );
625  FC_ASSERT( debt_itr != total_debts.end() );
626  if( supply_itr->second != debt_itr->second )
627  {
628  has_imbalanced_assets = true;
629  elog( "Genesis for asset ${aname} is not balanced\n"
630  " Debt is ${debt}\n"
631  " Supply is ${supply}\n",
632  ("aname", it->symbol)
633  ("debt", debt_itr->second)
634  ("supply", supply_itr->second)
635  );
636  }
637  }
638  ++it;
639  }
640  FC_ASSERT( !has_imbalanced_assets );
641 
642  // Save tallied supplies
643  for( const auto& item : total_supplies )
644  {
645  const auto asset_id = item.first;
646  const auto total_supply = item.second;
647 
648  modify( get( asset_id ), [ & ]( asset_object& asset ) {
649  modify( get( asset.dynamic_asset_data_id ), [ & ]( asset_dynamic_data_object& asset_data ) {
650  asset_data.current_supply = total_supply;
651  } );
652  } );
653  }
654 
655  // Create special witness account
656  const witness_object& wit = create<witness_object>([&](witness_object& w) {});
657  FC_ASSERT( wit.id == GRAPHENE_NULL_WITNESS );
658  remove(wit);
659 
660  // Create initial witnesses
661  std::for_each(genesis_state.initial_witness_candidates.begin(), genesis_state.initial_witness_candidates.end(),
664  op.witness_account = get_account_id(witness.owner_name);
665  op.block_signing_key = witness.block_signing_key;
666  apply_operation(genesis_eval_state, op);
667  });
668 
669  // Create initial committee members
670  std::for_each(genesis_state.initial_committee_candidates.begin(), genesis_state.initial_committee_candidates.end(),
673  op.committee_member_account = get_account_id(member.owner_name);
674  apply_operation(genesis_eval_state, op);
675  });
676 
677  // Create initial workers
678  std::for_each(genesis_state.initial_worker_candidates.begin(), genesis_state.initial_worker_candidates.end(),
680  {
682  op.owner = get_account_id(worker.owner_name);
683  op.work_begin_date = genesis_state.initial_timestamp;
685  op.daily_pay = worker.daily_pay;
686  op.name = "Genesis-Worker-" + worker.owner_name;
688 
689  apply_operation(genesis_eval_state, std::move(op));
690  });
691 
692  // Set active witnesses
693  modify(get_global_properties(), [&genesis_state](global_property_object& p) {
694  for( uint32_t i = 1; i <= genesis_state.initial_active_witnesses; ++i )
695  {
696  p.active_witnesses.insert(witness_id_type(i));
697  }
698  });
699 
700  // Enable fees
701  modify(get_global_properties(), [&genesis_state](global_property_object& p) {
702  p.parameters.get_mutable_fees() = genesis_state.initial_parameters.get_current_fees();
703  });
704 
705  // Create witness scheduler
706  _p_witness_schedule_obj = & create<witness_schedule_object>([this]( witness_schedule_object& wso )
707  {
708  for( const witness_id_type& wid : get_global_properties().active_witnesses )
709  wso.current_shuffled_witnesses.push_back( wid );
710  });
711 
712  // Create FBA counters
713  create<fba_accumulator_object>([&]( fba_accumulator_object& acc )
714  {
715  FC_ASSERT( acc.id == fba_accumulator_id_type( fba_accumulator_id_transfer_to_blind ) );
716  acc.accumulated_fba_fees = 0;
717 #ifdef GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
718  acc.designated_asset = GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET;
719 #endif
720  });
721 
722  create<fba_accumulator_object>([&]( fba_accumulator_object& acc )
723  {
724  FC_ASSERT( acc.id == fba_accumulator_id_type( fba_accumulator_id_blind_transfer ) );
725  acc.accumulated_fba_fees = 0;
726 #ifdef GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
727  acc.designated_asset = GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET;
728 #endif
729  });
730 
731  create<fba_accumulator_object>([&]( fba_accumulator_object& acc )
732  {
733  FC_ASSERT( acc.id == fba_accumulator_id_type( fba_accumulator_id_transfer_from_blind ) );
734  acc.accumulated_fba_fees = 0;
735 #ifdef GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
736  acc.designated_asset = GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET;
737 #endif
738  });
739 
740  FC_ASSERT( get_index<fba_accumulator_object>().get_next_id() == fba_accumulator_id_type( fba_accumulator_id_count ) );
741 
742  //debug_dump();
743 
744  _undo_db.enable();
746 
747 } }
static const uint8_t type_id
Tracks the balance of a single account/asset pairThis object is indexed on owner and asset_type so th...
Create a committee_member object, as a bid to hold a committee_member seat on the network...
account_id_type registrar
This account pays the fee. Must be a lifetime member.
Definition: account.hpp:100
static const uint8_t space_id
fc::time_point_sec begin_timestamp
This is the time at which funds begin vesting.
#define GRAPHENE_TEMP_ACCOUNT
Represents the canonical account with WILDCARD authority (anybody can access funds in temp account) ...
Definition: config.hpp:133
static const uint8_t type_id
Definition: htlc_object.hpp:44
void modify(const T &obj, const Lambda &m)
uint32_t vesting_duration_seconds
Duration of the vesting period, in seconds. Must be greater than 0 and greater than vesting_cliff_sec...
bool upgrade_to_lifetime_member
If true, the account will be upgraded to a lifetime member; otherwise, it will add a year to the subs...
Definition: account.hpp:245
#define GRAPHENE_MIN_UNDO_HISTORY
Definition: config.hpp:28
void adjust_balance(account_id_type account, asset delta)
Adjust a particular account&#39;s balance in a given asset by a delta.
Definition: db_balance.cpp:54
Identifies a weighted set of keys and accounts that must approve operations.
Definition: authority.hpp:34
require the issuer to be one party to every transfer
Definition: types.hpp:143
std::string to_lower(const std::string &)
Definition: string.cpp:98
immutable_chain_parameters immutable_parameters
Manage an account&#39;s membership statusThis operation is used to upgrade an account to a member...
Definition: account.hpp:234
static const uint8_t space_id
uint32_t vesting_cliff_seconds
No amount may be withdrawn before this many seconds of the vesting period have elapsed.
contains properties that only apply to bitassets (market issued assets)
void init_genesis(const genesis_state_type &genesis_state=genesis_state_type())
Definition: db_init.cpp:242
uint32_t sec_since_epoch() const
Definition: time.hpp:90
This class represents an account on the object graphAccounts are the primary unit of authority on the...
Maintains global state information (committee_member list, current fees)This is an implementation det...
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
Definition: api.cpp:56
#define elog(FORMAT,...)
Definition: logger.hpp:129
static const uint8_t type_id
#define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
Definition: config.hpp:140
Create a witness object, as a bid to hold a witness position on the network.Accounts which wish to be...
Definition: witness.hpp:37
account_id_type account_to_upgrade
The account to upgrade; must not already be a lifetime member.
Definition: account.hpp:243
#define GRAPHENE_PROXY_TO_SELF_ACCOUNT
Represents the canonical account for specifying you will vote directly (as opposed to a proxy) ...
Definition: config.hpp:135
tracks debt and call price information
asset get_balance(account_id_type owner, asset_id_type asset_id) const
Retrieve a particular account&#39;s balance in a given asset.
Definition: db_balance.cpp:35
This secondary index will allow fast access to the balance objects that belonging to an account...
#define GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO
Call when collateral only pays off 175% the debt.
Definition: config.hpp:116
uint16_t network_fee_percentage
Percentage of fee which should go to network.
#define GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE
Definition: config.hpp:83
vector< initial_witness_type > initial_witness_candidates
const global_property_object & get_global_properties() const
Definition: db_getter.cpp:44
#define GRAPHENE_MAX_SHARE_SUPPLY
Definition: config.hpp:38
static sha256 hash(const char *d, uint32_t dlen)
Definition: sha256.cpp:41
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
void set_max_size(size_t new_max_size)
account_id_type committee_member_account
The account which owns the committee_member. This account pays the fee for this operation.
operation_result apply_operation(transaction_evaluation_state &eval_state, const operation &op)
Definition: db_block.cpp:754
static const uint8_t space_id
static time_point_sec maximum()
Definition: time.hpp:86
object_id_type id
Definition: object.hpp:73
uint16_t lifetime_referrer_fee_percentage
Percentage of fee which should go to lifetime referrer.
account_id_type get_id() const
#define GRAPHENE_100_PERCENT
Definition: config.hpp:102
#define GRAPHENE_COMMITTEE_ACCOUNT
Definition: config.hpp:125
#define GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS
Definition: config.hpp:30
account_id_type lifetime_referrer
The lifetime member at the top of the referral tree. Receives a percentage of referral rewards...
static const uint8_t space_id
Definition: htlc_object.hpp:43
asset_dynamic_data_id_type dynamic_asset_data_id
Current supply, fee pool, and collected fees are stored in a separate object as they change frequentl...
share_type begin_balance
The total amount of asset to vest.
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:478
worker_initializer initializer
This should be set to the initializer appropriate for the type of worker to be created.
Definition: worker.hpp:90
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
string name
The account&#39;s name. This name must be unique among all account names on the graph. May not be empty.
tracks the asset information that changes frequentlyBecause the asset_object is very large it doesn&#39;t...
static private_key regenerate(const fc::sha256 &secret)
#define GRAPHENE_NULL_ACCOUNT
Represents the canonical account with NO authority (nobody can access funds in null account) ...
Definition: config.hpp:131
market trades in this asset may be charged
Definition: types.hpp:140
accounts must be whitelisted in order to hold or transact this asset
Definition: types.hpp:141
static const uint8_t type_id
account_id_type witness_account
The account which owns the witness. This account pays the fee for this operation. ...
Definition: witness.hpp:43
#define GRAPHENE_RELAXED_COMMITTEE_ACCOUNT
Represents the current committee members.
Definition: config.hpp:129
tracks the parameters of an assetAll assets have a globally unique symbol name that controls how they...
#define GRAPHENE_NULL_WITNESS
Sentinel value used in the scheduler.
Definition: config.hpp:137
std::string to_string(double)
Definition: string.cpp:73
void initialize_indexes()
Reset the object graph in-memory.
Definition: db_init.cpp:197
the bitasset is to be fed by witnesses
Definition: types.hpp:147
allow the bitasset owner to force a global settling, permission only
Definition: types.hpp:145
vector< initial_collateral_position > collateral_records
node_property_object & node_properties()
Definition: db_getter.cpp:94
account_statistics_id_type statistics
tracks minimal information about past blocks to implement TaPOSWhen attempting to calculate the valid...
issuer may transfer asset back to himself
Definition: types.hpp:142
Maintains global state information (committee_member list, current fees)This is an implementation det...
account_id_type registrar
The account that paid the fee to register this account. Receives a percentage of referral rewards...
#define GRAPHENE_SYMBOL
Definition: config.hpp:26
an elliptic curve private key.
Definition: elliptic.hpp:89
#define GRAPHENE_DEFAULT_BLOCK_INTERVAL
Definition: config.hpp:62
void for_each(T &&t, const account_object &a, seq< Is... >)
Definition: database.hpp:700
static price call_price(const asset &debt, const asset &collateral, uint16_t collateral_ratio)
Definition: asset.cpp:212
account_id_type referrer
The account credited as referring this account. Receives a percentage of referral rewards...
Create a new worker object.
Definition: worker.hpp:78
Linear vesting balance with cliff.
disallow the asset to be used with confidential transactions
Definition: types.hpp:146
#define GRAPHENE_DEFAULT_MINIMUM_FEEDS
Definition: config.hpp:97
#define GRAPHENE_WITNESS_ACCOUNT
Represents the current witnesses.
Definition: config.hpp:127