BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
db_genesis.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 
41 
42 #include <fc/crypto/digest.hpp>
43 
44 #include <boost/algorithm/string.hpp>
45 
46 namespace graphene { namespace chain {
47 
48 void database::init_genesis(const genesis_state_type& genesis_state)
49 { try {
50  FC_ASSERT( genesis_state.initial_timestamp != time_point_sec(), "Must initialize genesis timestamp." );
51  FC_ASSERT( genesis_state.initial_timestamp.sec_since_epoch() % GRAPHENE_DEFAULT_BLOCK_INTERVAL == 0,
52  "Genesis timestamp must be divisible by GRAPHENE_DEFAULT_BLOCK_INTERVAL." );
53  FC_ASSERT(genesis_state.initial_witness_candidates.size() > 0,
54  "Cannot start a chain with zero witnesses.");
55  FC_ASSERT(genesis_state.initial_active_witnesses <= genesis_state.initial_witness_candidates.size(),
56  "initial_active_witnesses is larger than the number of candidate witnesses.");
57 
58  _undo_db.disable();
59  struct auth_inhibitor {
60  explicit auth_inhibitor(database& db) : db(db), old_flags(db.node_properties().skip_flags)
61  { db.node_properties().skip_flags |= skip_transaction_signatures; }
62  ~auth_inhibitor()
63  { db.node_properties().skip_flags = old_flags; }
64  auth_inhibitor(const auth_inhibitor&) = delete;
65  private:
66  database& db;
67  uint32_t old_flags;
68  };
69  auth_inhibitor inhibitor(*this);
70 
71  transaction_evaluation_state genesis_eval_state(this);
72 
73  _current_block_time = genesis_state.initial_timestamp;
74 
75  // Create blockchain accounts
76  fc::ecc::private_key null_private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")));
77  create<account_balance_object>([](account_balance_object& b) {
78  b.balance = GRAPHENE_MAX_SHARE_SUPPLY;
79  });
80  const account_object& committee_account =
81  create<account_object>( [this](account_object& n) {
82  n.membership_expiration_date = time_point_sec::maximum();
83  n.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
84  n.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
85  n.owner.weight_threshold = 1;
86  n.active.weight_threshold = 1;
87  n.name = "committee-account";
88  n.statistics = create<account_statistics_object>( [&n](account_statistics_object& s){
89  s.owner = n.id;
90  s.name = n.name;
91  s.core_in_balance = GRAPHENE_MAX_SHARE_SUPPLY;
92  }).id;
93  n.creation_block_num = 0;
94  n.creation_time = _current_block_time;
95  });
96  FC_ASSERT(committee_account.get_id() == GRAPHENE_COMMITTEE_ACCOUNT);
97  FC_ASSERT(create<account_object>([this](account_object& a) {
98  a.name = "witness-account";
99  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
100  s.owner = a.id;
101  s.name = a.name;
102  }).id;
103  a.owner.weight_threshold = 1;
104  a.active.weight_threshold = 1;
105  a.registrar = GRAPHENE_WITNESS_ACCOUNT;
106  a.referrer = a.registrar;
107  a.lifetime_referrer = a.registrar;
108  a.membership_expiration_date = time_point_sec::maximum();
109  a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
110  a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
111  a.creation_block_num = 0;
112  a.creation_time = _current_block_time;
113  }).get_id() == GRAPHENE_WITNESS_ACCOUNT);
114  FC_ASSERT(create<account_object>([this](account_object& a) {
115  a.name = "relaxed-committee-account";
116  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
117  s.owner = a.id;
118  s.name = a.name;
119  }).id;
120  a.owner.weight_threshold = 1;
121  a.active.weight_threshold = 1;
123  a.referrer = a.registrar;
124  a.lifetime_referrer = a.registrar;
125  a.membership_expiration_date = time_point_sec::maximum();
126  a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
127  a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
128  a.creation_block_num = 0;
129  a.creation_time = _current_block_time;
130  }).get_id() == GRAPHENE_RELAXED_COMMITTEE_ACCOUNT);
131  // The same data set is assigned to more than one account
132  auto init_account_data_as_null = [this](account_object& a) {
133  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
134  s.owner = a.id;
135  s.name = a.name;
136  }).id;
137  a.owner.weight_threshold = 1;
138  a.active.weight_threshold = 1;
139  a.registrar = GRAPHENE_NULL_ACCOUNT;
140  a.referrer = a.registrar;
141  a.lifetime_referrer = a.registrar;
142  a.membership_expiration_date = time_point_sec::maximum();
143  a.network_fee_percentage = 0;
144  a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT;
145  a.creation_block_num = 0;
146  a.creation_time = _current_block_time;
147  };
148  FC_ASSERT(create<account_object>([&init_account_data_as_null](account_object& a) {
149  a.name = "null-account";
150  init_account_data_as_null(a);
151  }).get_id() == GRAPHENE_NULL_ACCOUNT);
152  FC_ASSERT(create<account_object>([this](account_object& a) {
153  a.name = "temp-account";
154  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
155  s.owner = a.id;
156  s.name = a.name;
157  }).id;
158  a.owner.weight_threshold = 0;
159  a.active.weight_threshold = 0;
160  a.registrar = GRAPHENE_TEMP_ACCOUNT;
161  a.referrer = a.registrar;
162  a.lifetime_referrer = a.registrar;
163  a.membership_expiration_date = time_point_sec::maximum();
164  a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
165  a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
166  a.creation_block_num = 0;
167  a.creation_time = _current_block_time;
168  }).get_id() == GRAPHENE_TEMP_ACCOUNT);
169  FC_ASSERT(create<account_object>([&init_account_data_as_null](account_object& a) {
170  a.name = "proxy-to-self";
171  init_account_data_as_null(a);
172  }).get_id() == GRAPHENE_PROXY_TO_SELF_ACCOUNT);
173 
174  // Create more special accounts and remove them, reserve the IDs
175  while( true )
176  {
177  uint64_t id = get_index<account_object>().get_next_id().instance();
178  if( id >= genesis_state.immutable_parameters.num_special_accounts )
179  break;
180  const account_object& acct = create<account_object>([this,id](account_object& a) {
181  a.name = "special-account-" + std::to_string(id);
182  a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
183  s.owner = a.id;
184  s.name = a.name;
185  }).id;
186  a.owner.weight_threshold = 1;
187  a.active.weight_threshold = 1;
188  a.registrar = account_id_type(id);
189  a.referrer = a.registrar;
190  a.lifetime_referrer = a.registrar;
191  a.membership_expiration_date = time_point_sec::maximum();
192  a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
193  a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
194  a.creation_block_num = 0;
195  a.creation_time = _current_block_time;
196  });
197  FC_ASSERT( acct.get_id() == account_id_type(id) );
198  remove( acct.statistics(*this) );
199  remove( acct );
200  }
201 
202  // Create core asset
203  const asset_dynamic_data_object& core_dyn_asset =
204  create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
205  a.current_supply = GRAPHENE_MAX_SHARE_SUPPLY;
206  });
207  const asset_object& core_asset =
208  create<asset_object>( [&genesis_state,&core_dyn_asset,this]( asset_object& a ) {
209  a.symbol = GRAPHENE_SYMBOL;
210  a.options.max_supply = genesis_state.max_core_supply;
212  a.options.flags = 0;
213  a.options.issuer_permissions = 0;
214  a.issuer = GRAPHENE_NULL_ACCOUNT;
215  a.options.core_exchange_rate.base.amount = 1;
216  a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
217  a.options.core_exchange_rate.quote.amount = 1;
218  a.options.core_exchange_rate.quote.asset_id = asset_id_type(0);
219  a.dynamic_asset_data_id = core_dyn_asset.id;
220  a.creation_block_num = 0;
221  a.creation_time = _current_block_time;
222  });
223  FC_ASSERT( core_dyn_asset.id == asset_dynamic_data_id_type() );
224  FC_ASSERT( asset_id_type(core_asset.id) == asset().asset_id );
225  FC_ASSERT( get_balance(account_id_type(), asset_id_type()) == asset(core_dyn_asset.current_supply) );
226  _p_core_asset_obj = &core_asset;
227  _p_core_dynamic_data_obj = &core_dyn_asset;
228  // Create more special assets and remove them, reserve the IDs
229  while( true )
230  {
231  uint64_t id = get_index<asset_object>().get_next_id().instance();
232  if( id >= genesis_state.immutable_parameters.num_special_assets )
233  break;
234  const asset_dynamic_data_object& dyn_asset =
235  create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
236  a.current_supply = 0;
237  });
238  const asset_object& asset_obj = create<asset_object>( [id,&dyn_asset,this]( asset_object& a ) {
239  a.symbol = "SPECIAL" + std::to_string( id );
240  a.options.max_supply = 0;
242  a.options.flags = 0;
243  a.options.issuer_permissions = 0;
244  a.issuer = GRAPHENE_NULL_ACCOUNT;
245  a.options.core_exchange_rate.base.amount = 1;
246  a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
247  a.options.core_exchange_rate.quote.amount = 1;
248  a.options.core_exchange_rate.quote.asset_id = asset_id_type(0);
249  a.dynamic_asset_data_id = dyn_asset.id;
250  a.creation_block_num = 0;
251  a.creation_time = _current_block_time;
252  });
253  FC_ASSERT( asset_obj.get_id() == asset_id_type(id) );
254  remove( dyn_asset );
255  remove( asset_obj );
256  }
257 
258  chain_id_type chain_id = genesis_state.compute_chain_id();
259 
260  // Create global properties
261  _p_global_prop_obj = & create<global_property_object>([&genesis_state](global_property_object& p) {
262  p.parameters = genesis_state.initial_parameters;
263  // Set fees to zero initially, so that genesis initialization needs not pay them
264  // We'll fix it at the end of the function
265  p.parameters.get_mutable_fees().zero_all_fees();
266 
267  });
268  _p_dyn_global_prop_obj = & create<dynamic_global_property_object>(
269  [&genesis_state](dynamic_global_property_object& p) {
270  p.time = genesis_state.initial_timestamp;
271  p.dynamic_flags = 0;
272  p.witness_budget = 0;
273  p.recent_slots_filled = std::numeric_limits<fc::uint128_t>::max();
274  });
275 
276  FC_ASSERT( (genesis_state.immutable_parameters.min_witness_count & 1) == 1, "min_witness_count must be odd" );
277  FC_ASSERT( (genesis_state.immutable_parameters.min_committee_member_count & 1) == 1,
278  "min_committee_member_count must be odd" );
279 
280  _p_chain_property_obj = & create<chain_property_object>([chain_id,&genesis_state](chain_property_object& p)
281  {
282  p.chain_id = chain_id;
283  p.immutable_parameters = genesis_state.immutable_parameters;
284  } );
285 
286  constexpr uint32_t block_summary_object_count = 0x10000;
287  for (uint32_t i = 0; i <= block_summary_object_count; ++i)
288  {
289  create<block_summary_object>( [](const block_summary_object&) {
290  // Nothing to do
291  } );
292  }
293 
294  // Create initial accounts
295  for( const auto& account : genesis_state.initial_accounts )
296  {
297  account_create_operation cop;
298  cop.name = account.name;
299  cop.registrar = GRAPHENE_TEMP_ACCOUNT;
300  cop.owner = authority(1, account.owner_key, 1);
301  if( account.active_key == public_key_type() )
302  {
303  cop.active = cop.owner;
304  cop.options.memo_key = account.owner_key;
305  }
306  else
307  {
308  cop.active = authority(1, account.active_key, 1);
309  cop.options.memo_key = account.active_key;
310  }
311  account_id_type account_id(apply_operation(genesis_eval_state, cop).get<object_id_type>());
312 
313  if( account.is_lifetime_member )
314  {
315  account_upgrade_operation op;
316  op.account_to_upgrade = account_id;
317  op.upgrade_to_lifetime_member = true;
318  apply_operation(genesis_eval_state, op);
319  }
320  }
321 
322  // Helper function to get account ID by name
323  const auto& accounts_by_name = get_index_type<account_index>().indices().get<by_name>();
324  auto get_account_id = [&accounts_by_name](const string& name) {
325  auto itr = accounts_by_name.find(name);
326  FC_ASSERT(itr != accounts_by_name.end(),
327  "Unable to find account '${acct}'. Did you forget to add a record for it to initial_accounts?",
328  ("acct", name));
329  return itr->get_id();
330  };
331 
332  // Helper function to get asset ID by symbol
333  const auto& assets_by_symbol = get_index_type<asset_index>().indices().get<by_symbol>();
334  const auto get_asset_id = [&assets_by_symbol](const string& symbol) {
335  auto itr = assets_by_symbol.find(symbol);
336  FC_ASSERT(itr != assets_by_symbol.end(),
337  "Unable to find asset '${sym}'. Did you forget to add a record for it to initial_assets?",
338  ("sym", symbol));
339  return itr->get_id();
340  };
341 
342  map<asset_id_type, share_type> total_supplies;
343  map<asset_id_type, share_type> total_debts;
344 
345  // Create initial assets
346  for( const genesis_state_type::initial_asset_type& asst : genesis_state.initial_assets )
347  {
348  asset_id_type new_asset_id { get_index_type<asset_index>().get_next_id() };
349  total_supplies[ new_asset_id ] = 0;
350 
351  asset_dynamic_data_id_type dynamic_data_id;
352  optional<asset_bitasset_data_id_type> bitasset_data_id;
353  if( asst.is_bitasset )
354  {
355  size_t collateral_holder_number = 0;
356  total_debts[ new_asset_id ] = 0;
357  for( const auto& collateral_rec : asst.collateral_records )
358  {
359  account_create_operation cop;
360  cop.name = asst.symbol + "-collateral-holder-" + std::to_string(collateral_holder_number);
361  boost::algorithm::to_lower(cop.name);
362  cop.registrar = GRAPHENE_TEMP_ACCOUNT;
363  cop.owner = authority(1, collateral_rec.owner, 1);
364  cop.active = cop.owner;
365  account_id_type owner_account_id { apply_operation(genesis_eval_state, cop).get<object_id_type>() };
366 
367  modify( owner_account_id(*this).statistics(*this), [&collateral_rec]( account_statistics_object& o ) {
368  o.total_core_in_orders = collateral_rec.collateral;
369  });
370 
371  create<call_order_object>(
372  [&owner_account_id,&collateral_rec,&new_asset_id,&core_asset](call_order_object& c) {
373  c.borrower = owner_account_id;
374  c.collateral = collateral_rec.collateral;
375  c.debt = collateral_rec.debt;
376  c.call_price = price::call_price(chain::asset(c.debt, new_asset_id),
377  chain::asset(c.collateral, core_asset.get_id()),
379  });
380 
381  total_supplies[ asset_id_type(0) ] += collateral_rec.collateral;
382  total_debts[ new_asset_id ] += collateral_rec.debt;
383  ++collateral_holder_number;
384  }
385 
386  bitasset_data_id = create<asset_bitasset_data_object>([&core_asset,new_asset_id](asset_bitasset_data_object& b) {
387  b.options.short_backing_asset = core_asset.id;
388  b.options.minimum_feeds = GRAPHENE_DEFAULT_MINIMUM_FEEDS;
389  b.asset_id = new_asset_id;
390  }).id;
391  }
392 
393  dynamic_data_id = create<asset_dynamic_data_object>([&asst](asset_dynamic_data_object& d) {
394  d.accumulated_fees = asst.accumulated_fees;
395  }).id;
396 
397  total_supplies[ new_asset_id ] += asst.accumulated_fees;
398 
399  create<asset_object>([&asst,&get_account_id,&dynamic_data_id,&bitasset_data_id,this](asset_object& a)
400  {
401  a.symbol = asst.symbol;
402  a.options.description = asst.description;
403  a.precision = asst.precision;
404  string issuer_name = asst.issuer_name;
405  a.issuer = get_account_id(issuer_name);
406  a.options.max_supply = asst.max_supply;
407  a.options.flags = witness_fed_asset;
408  a.options.issuer_permissions = ( asst.is_bitasset ? ASSET_ISSUER_PERMISSION_ENABLE_BITS_MASK
409  : DEFAULT_UIA_ASSET_ISSUER_PERMISSION );
410  a.dynamic_asset_data_id = dynamic_data_id;
411  a.bitasset_data_id = bitasset_data_id;
412  a.creation_block_num = 0;
413  a.creation_time = _current_block_time;
414  });
415  }
416 
417  // Create initial balances
418  share_type total_allocation;
419  for( const auto& handout : genesis_state.initial_balances )
420  {
421  const auto asset_id = get_asset_id(handout.asset_symbol);
422  create<balance_object>([&handout,total_allocation,asset_id](balance_object& b) {
423  b.balance = asset(handout.amount, asset_id);
424  b.owner = handout.owner;
425  });
426 
427  total_supplies[ asset_id ] += handout.amount;
428  }
429 
430  // Create initial vesting balances
431  for( const genesis_state_type::initial_vesting_balance_type& vest : genesis_state.initial_vesting_balances )
432  {
433  const auto asset_id = get_asset_id(vest.asset_symbol);
434  create<balance_object>([&vest,&asset_id](balance_object& b) {
435  b.owner = vest.owner;
436  b.balance = asset(vest.amount, asset_id);
437 
438  linear_vesting_policy policy;
439  policy.begin_timestamp = vest.begin_timestamp;
440  policy.vesting_cliff_seconds = 0;
441  policy.vesting_duration_seconds = vest.vesting_duration_seconds;
442  policy.begin_balance = vest.begin_balance;
443 
444  b.vesting_policy = std::move(policy);
445  });
446 
447  total_supplies[ asset_id ] += vest.amount;
448  }
449 
450  if( total_supplies[ asset_id_type(0) ] > 0 )
451  {
453  }
454  else
455  {
456  total_supplies[ asset_id_type(0) ] = GRAPHENE_MAX_SHARE_SUPPLY;
457  }
458 
459  const auto& idx = get_index_type<asset_index>().indices().get<by_symbol>();
460  auto it = idx.begin();
461  bool has_imbalanced_assets = false;
462 
463  while( it != idx.end() )
464  {
465  if( it->bitasset_data_id.valid() )
466  {
467  auto supply_itr = total_supplies.find( it->get_id() );
468  auto debt_itr = total_debts.find( it->get_id() );
469  FC_ASSERT( supply_itr != total_supplies.end() );
470  FC_ASSERT( debt_itr != total_debts.end() );
471  if( supply_itr->second != debt_itr->second )
472  {
473  has_imbalanced_assets = true;
474  elog( "Genesis for asset ${aname} is not balanced\n"
475  " Debt is ${debt}\n"
476  " Supply is ${supply}\n",
477  ("aname", it->symbol)
478  ("debt", debt_itr->second)
479  ("supply", supply_itr->second)
480  );
481  }
482  }
483  ++it;
484  }
485  FC_ASSERT( !has_imbalanced_assets );
486 
487  // Save tallied supplies
488  for( const auto& item : total_supplies )
489  {
490  const auto& asset_id = item.first;
491  const auto& total_supply = item.second;
492 
493  modify( get(get(asset_id).dynamic_asset_data_id), [&total_supply]( asset_dynamic_data_object& asset_data ) {
494  asset_data.current_supply = total_supply;
495  } );
496  }
497 
498  // Create special witness account and remove it, reserve the id
499  const witness_object& wit = create<witness_object>([](const witness_object&) {
500  // Nothing to do
501  });
502  FC_ASSERT( wit.id == GRAPHENE_NULL_WITNESS );
503  remove(wit);
504 
505  // Create initial witnesses
506  std::for_each( genesis_state.initial_witness_candidates.begin(),
507  genesis_state.initial_witness_candidates.end(),
508  [this,&get_account_id,&genesis_eval_state](const auto& witness) {
509  witness_create_operation op;
510  op.witness_account = get_account_id(witness.owner_name);
511  op.block_signing_key = witness.block_signing_key;
512  this->apply_operation(genesis_eval_state, op);
513  });
514 
515  // Create initial committee members
516  std::for_each( genesis_state.initial_committee_candidates.begin(),
517  genesis_state.initial_committee_candidates.end(),
518  [this,&get_account_id,&genesis_eval_state](const auto& member) {
519  committee_member_create_operation op;
520  op.committee_member_account = get_account_id(member.owner_name);
521  this->apply_operation(genesis_eval_state, op);
522  });
523 
524  // Create initial workers
525  std::for_each( genesis_state.initial_worker_candidates.begin(),
526  genesis_state.initial_worker_candidates.end(),
527  [this,&get_account_id,&genesis_state,&genesis_eval_state](const auto& worker)
528  {
529  worker_create_operation op;
530  op.owner = get_account_id(worker.owner_name);
531  op.work_begin_date = genesis_state.initial_timestamp;
532  op.work_end_date = time_point_sec::maximum();
533  op.daily_pay = worker.daily_pay;
534  op.name = "Genesis-Worker-" + worker.owner_name;
535  op.initializer = vesting_balance_worker_initializer{uint16_t(0)};
536 
537  this->apply_operation(genesis_eval_state, std::move(op));
538  });
539 
540  // Set active witnesses
541  modify(get_global_properties(), [&genesis_state](global_property_object& p) {
542  for( uint32_t i = 1; i <= genesis_state.initial_active_witnesses; ++i )
543  {
544  p.active_witnesses.insert(witness_id_type(i));
545  }
546  });
547 
548  // Enable fees
549  modify(get_global_properties(), [&genesis_state](global_property_object& p) {
550  p.parameters.get_mutable_fees() = genesis_state.initial_parameters.get_current_fees();
551  });
552 
553  // Create witness scheduler
554  _p_witness_schedule_obj = & create<witness_schedule_object>([this]( witness_schedule_object& wso )
555  {
556  for( const witness_id_type& wid : get_global_properties().active_witnesses )
557  wso.current_shuffled_witnesses.push_back( wid );
558  });
559 
560  // Create FBA counters
561  create<fba_accumulator_object>([]( fba_accumulator_object& acc )
562  {
563  FC_ASSERT( acc.id == fba_accumulator_id_type( fba_accumulator_id_transfer_to_blind ) );
564  acc.accumulated_fba_fees = 0;
565 #ifdef GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
566  acc.designated_asset = GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET;
567 #endif
568  });
569 
570  create<fba_accumulator_object>([]( fba_accumulator_object& acc )
571  {
572  FC_ASSERT( acc.id == fba_accumulator_id_type( fba_accumulator_id_blind_transfer ) );
573  acc.accumulated_fba_fees = 0;
574 #ifdef GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
575  acc.designated_asset = GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET;
576 #endif
577  });
578 
579  create<fba_accumulator_object>([]( fba_accumulator_object& acc )
580  {
581  FC_ASSERT( acc.id == fba_accumulator_id_type( fba_accumulator_id_transfer_from_blind ) );
582  acc.accumulated_fba_fees = 0;
583 #ifdef GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
584  acc.designated_asset = GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET;
585 #endif
586  });
587 
588  FC_ASSERT( get_index<fba_accumulator_object>().get_next_id() == fba_accumulator_id_type( fba_accumulator_id_count ) );
589 
590  //debug_dump(); // for debug
591 
592  _undo_db.enable();
594 
595 } }
GRAPHENE_MAX_SHARE_SUPPLY
constexpr int64_t GRAPHENE_MAX_SHARE_SUPPLY(1000000000000000LL)
graphene::chain::database::skip_transaction_signatures
@ skip_transaction_signatures
used by non-witness nodes
Definition: database.hpp:81
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
fba_accumulator_id.hpp
GRAPHENE_RELAXED_COMMITTEE_ACCOUNT
#define GRAPHENE_RELAXED_COMMITTEE_ACCOUNT
Represents the current committee members.
Definition: config.hpp:144
fc::to_lower
std::string to_lower(const std::string &)
Definition: string.cpp:98
fc::to_string
std::string to_string(double)
Definition: string.cpp:73
graphene::chain::database::_current_block_time
fc::time_point_sec _current_block_time
Definition: database.hpp:799
asset_object.hpp
graphene::db::object_database::get
const T & get(const object_id_type &id) const
Definition: object_database.hpp:119
graphene::chain::database::get_balance
asset get_balance(account_id_type owner, asset_id_type asset_id) const
Retrieve a particular account's balance in a given asset.
Definition: db_balance.cpp:35
graphene::protocol::witness_fed_asset
@ witness_fed_asset
the bitasset is to be fed by witnesses
Definition: types.hpp:201
GRAPHENE_PROXY_TO_SELF_ACCOUNT
#define GRAPHENE_PROXY_TO_SELF_ACCOUNT
Represents the canonical account for specifying you will vote directly (as opposed to a proxy)
Definition: config.hpp:150
database.hpp
graphene::db::undo_database::enable
void enable()
Definition: undo_database.cpp:30
graphene::chain::global_property_object::parameters
chain_parameters parameters
Definition: global_property_object.hpp:44
chain_property_object.hpp
GRAPHENE_TEMP_ACCOUNT
#define GRAPHENE_TEMP_ACCOUNT
Represents the canonical account with WILDCARD authority (anybody can access funds in temp account)
Definition: config.hpp:148
graphene::chain::database::adjust_balance
void adjust_balance(account_id_type account, asset delta)
Adjust a particular account's balance in a given asset by a delta.
Definition: db_balance.cpp:54
GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS
#define GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS
Definition: config.hpp:30
fc::time_point_sec::maximum
static time_point_sec maximum()
Definition: time.hpp:86
GRAPHENE_SYMBOL
#define GRAPHENE_SYMBOL
Definition: config.hpp:26
worker_object.hpp
fc::ecc::private_key
an elliptic curve private key.
Definition: elliptic.hpp:89
graphene::protocol::price::call_price
static price call_price(const asset &debt, const asset &collateral, uint16_t collateral_ratio)
Definition: asset.cpp:216
GRAPHENE_NULL_WITNESS
#define GRAPHENE_NULL_WITNESS
Sentinel value used in the scheduler.
Definition: config.hpp:152
GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO
#define GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO
Call when collateral only pays off 175% the debt.
Definition: config.hpp:116
account_object.hpp
digest.hpp
vesting_balance_object.hpp
GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
#define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
Definition: config.hpp:155
graphene::chain::fba_accumulator_id_transfer_to_blind
@ fba_accumulator_id_transfer_to_blind
Definition: fba_accumulator_id.hpp:35
committee_member_object.hpp
GRAPHENE_COMMITTEE_ACCOUNT
#define GRAPHENE_COMMITTEE_ACCOUNT
Definition: config.hpp:140
graphene::protocol::share_type
safe< int64_t > share_type
Definition: types.hpp:309
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
graphene::chain::fba_accumulator_id_blind_transfer
@ fba_accumulator_id_blind_transfer
Definition: fba_accumulator_id.hpp:36
graphene::chain::global_property_object::active_witnesses
flat_set< witness_id_type > active_witnesses
Definition: global_property_object.hpp:49
GRAPHENE_DEFAULT_MINIMUM_FEEDS
#define GRAPHENE_DEFAULT_MINIMUM_FEEDS
Definition: config.hpp:97
GRAPHENE_WITNESS_ACCOUNT
#define GRAPHENE_WITNESS_ACCOUNT
Represents the current witnesses.
Definition: config.hpp:142
graphene::chain::fba_accumulator_id_count
@ fba_accumulator_id_count
Definition: fba_accumulator_id.hpp:38
fc::static_variant::get
X & get()
Definition: static_variant.hpp:236
graphene::chain::database::node_properties
node_property_object & node_properties()
Definition: db_getter.cpp:97
graphene::chain::fba_accumulator_id_transfer_from_blind
@ fba_accumulator_id_transfer_from_blind
Definition: fba_accumulator_id.hpp:37
block_summary_object.hpp
graphene::protocol::chain_parameters::get_mutable_fees
fee_schedule & get_mutable_fees()
Definition: chain_parameters.hpp:51
graphene::db::undo_database::disable
void disable()
Definition: undo_database.cpp:31
GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE
#define GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE
Definition: config.hpp:83
graphene::chain::database::apply_operation
operation_result apply_operation(transaction_evaluation_state &eval_state, const operation &op, bool is_virtual=true)
Definition: db_block.cpp:784
balance_object.hpp
GRAPHENE_NULL_ACCOUNT
#define GRAPHENE_NULL_ACCOUNT
Represents the canonical account with NO authority (nobody can access funds in null account)
Definition: config.hpp:146
graphene::chain::database::get_global_properties
const global_property_object & get_global_properties() const
Definition: db_getter.cpp:47
witness_schedule_object.hpp
market_object.hpp
fba_object.hpp
witness_object.hpp
graphene::db::object_database::remove
void remove(const object &obj)
Definition: object_database.hpp:97
graphene::protocol::chain_id_type
fc::sha256 chain_id_type
Definition: types.hpp:149
fc::ecc::private_key::regenerate
static private_key regenerate(const fc::sha256 &secret)
Definition: elliptic_impl_priv.cpp:52
global_property_object.hpp
graphene::chain::database::database
database()
Definition: db_management.cpp:44
fc::sha256::hash
static sha256 hash(const char *d, uint32_t dlen)
Definition: sha256.cpp:41
GRAPHENE_100_PERCENT
#define GRAPHENE_100_PERCENT
Definition: config.hpp:102
graphene
Definition: api.cpp:48
graphene::db::object_database::modify
void modify(const T &obj, const Lambda &m)
Definition: object_database.hpp:99
fc::typelist::runtime::for_each
void for_each(list< Types... >, Callable c)
Invoke the provided callable with an argument wrapper<Type>() for each type in the list.
Definition: typelist.hpp:257
graphene::db::object_database::_undo_db
undo_database _undo_db
Definition: object_database.hpp:170
elog
#define elog(FORMAT,...)
Definition: logger.hpp:129
GRAPHENE_DEFAULT_BLOCK_INTERVAL
#define GRAPHENE_DEFAULT_BLOCK_INTERVAL
Definition: config.hpp:62