44 #include <boost/algorithm/string.hpp>
46 namespace graphene {
namespace chain {
48 void database::init_genesis(
const genesis_state_type& genesis_state)
50 FC_ASSERT( genesis_state.initial_timestamp != time_point_sec(),
"Must initialize genesis timestamp." );
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.");
59 struct auth_inhibitor {
63 { db.node_properties().skip_flags = old_flags; }
64 auth_inhibitor(
const auth_inhibitor&) =
delete;
69 auth_inhibitor inhibitor(*
this);
71 transaction_evaluation_state genesis_eval_state(
this);
77 create<account_balance_object>([](account_balance_object& b) {
80 const account_object& committee_account =
81 create<account_object>( [
this](account_object& n) {
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){
93 n.creation_block_num = 0;
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){
103 a.owner.weight_threshold = 1;
104 a.active.weight_threshold = 1;
106 a.referrer = a.registrar;
107 a.lifetime_referrer = a.registrar;
111 a.creation_block_num = 0;
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){
120 a.owner.weight_threshold = 1;
121 a.active.weight_threshold = 1;
123 a.referrer = a.registrar;
124 a.lifetime_referrer = a.registrar;
128 a.creation_block_num = 0;
132 auto init_account_data_as_null = [
this](account_object& a) {
133 a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
137 a.owner.weight_threshold = 1;
138 a.active.weight_threshold = 1;
140 a.referrer = a.registrar;
141 a.lifetime_referrer = a.registrar;
143 a.network_fee_percentage = 0;
145 a.creation_block_num = 0;
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);
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){
158 a.owner.weight_threshold = 0;
159 a.active.weight_threshold = 0;
161 a.referrer = a.registrar;
162 a.lifetime_referrer = a.registrar;
166 a.creation_block_num = 0;
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);
177 uint64_t
id = get_index<account_object>().get_next_id().instance();
178 if(
id >= genesis_state.immutable_parameters.num_special_accounts )
180 const account_object& acct = create<account_object>([
this,
id](account_object& a) {
182 a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
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;
194 a.creation_block_num = 0;
197 FC_ASSERT( acct.get_id() == account_id_type(
id) );
198 remove( acct.statistics(*
this) );
203 const asset_dynamic_data_object& core_dyn_asset =
204 create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
207 const asset_object& core_asset =
208 create<asset_object>( [&genesis_state,&core_dyn_asset,
this]( asset_object& a ) {
210 a.options.max_supply = genesis_state.max_core_supply;
213 a.options.issuer_permissions = 0;
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;
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;
231 uint64_t
id = get_index<asset_object>().get_next_id().instance();
232 if(
id >= genesis_state.immutable_parameters.num_special_assets )
234 const asset_dynamic_data_object& dyn_asset =
235 create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
236 a.current_supply = 0;
238 const asset_object& asset_obj = create<asset_object>( [
id,&dyn_asset,
this]( asset_object& a ) {
240 a.options.max_supply = 0;
243 a.options.issuer_permissions = 0;
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;
253 FC_ASSERT( asset_obj.get_id() == asset_id_type(
id) );
261 _p_global_prop_obj = & create<global_property_object>([&genesis_state](global_property_object& p) {
262 p.parameters = genesis_state.initial_parameters;
265 p.parameters.get_mutable_fees().zero_all_fees();
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;
272 p.witness_budget = 0;
273 p.recent_slots_filled = std::numeric_limits<fc::uint128_t>::max();
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" );
280 _p_chain_property_obj = & create<chain_property_object>([chain_id,&genesis_state](chain_property_object& p)
282 p.chain_id = chain_id;
283 p.immutable_parameters = genesis_state.immutable_parameters;
286 constexpr uint32_t block_summary_object_count = 0x10000;
287 for (uint32_t i = 0; i <= block_summary_object_count; ++i)
289 create<block_summary_object>( [](
const block_summary_object&) {
295 for(
const auto& account : genesis_state.initial_accounts )
297 account_create_operation cop;
298 cop.name = account.name;
300 cop.owner = authority(1, account.owner_key, 1);
301 if( account.active_key == public_key_type() )
303 cop.active = cop.owner;
304 cop.options.memo_key = account.owner_key;
308 cop.active = authority(1, account.active_key, 1);
309 cop.options.memo_key = account.active_key;
311 account_id_type account_id(
apply_operation(genesis_eval_state, cop).get<object_id_type>());
313 if( account.is_lifetime_member )
315 account_upgrade_operation op;
316 op.account_to_upgrade = account_id;
317 op.upgrade_to_lifetime_member =
true;
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);
327 "Unable to find account '${acct}'. Did you forget to add a record for it to initial_accounts?",
329 return itr->get_id();
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);
337 "Unable to find asset '${sym}'. Did you forget to add a record for it to initial_assets?",
339 return itr->get_id();
342 map<asset_id_type, share_type> total_supplies;
343 map<asset_id_type, share_type> total_debts;
346 for(
const genesis_state_type::initial_asset_type& asst : genesis_state.initial_assets )
348 asset_id_type new_asset_id { get_index_type<asset_index>().get_next_id() };
349 total_supplies[ new_asset_id ] = 0;
351 asset_dynamic_data_id_type dynamic_data_id;
352 optional<asset_bitasset_data_id_type> bitasset_data_id;
353 if( asst.is_bitasset )
355 size_t collateral_holder_number = 0;
356 total_debts[ new_asset_id ] = 0;
357 for(
const auto& collateral_rec : asst.collateral_records )
359 account_create_operation cop;
360 cop.name = asst.symbol +
"-collateral-holder-" +
std::to_string(collateral_holder_number);
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>() };
367 modify( owner_account_id(*this).statistics(*
this), [&collateral_rec]( account_statistics_object& o ) {
368 o.total_core_in_orders = collateral_rec.collateral;
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;
377 chain::asset(c.collateral, core_asset.get_id()),
381 total_supplies[ asset_id_type(0) ] += collateral_rec.collateral;
382 total_debts[ new_asset_id ] += collateral_rec.debt;
383 ++collateral_holder_number;
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;
389 b.asset_id = new_asset_id;
393 dynamic_data_id = create<asset_dynamic_data_object>([&asst](asset_dynamic_data_object& d) {
394 d.accumulated_fees = asst.accumulated_fees;
397 total_supplies[ new_asset_id ] += asst.accumulated_fees;
399 create<asset_object>([&asst,&get_account_id,&dynamic_data_id,&bitasset_data_id,
this](asset_object& a)
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;
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;
419 for(
const auto& handout : genesis_state.initial_balances )
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;
427 total_supplies[ asset_id ] += handout.amount;
431 for(
const genesis_state_type::initial_vesting_balance_type& vest : genesis_state.initial_vesting_balances )
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);
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;
444 b.vesting_policy = std::move(policy);
447 total_supplies[ asset_id ] += vest.amount;
450 if( total_supplies[ asset_id_type(0) ] > 0 )
459 const auto& idx = get_index_type<asset_index>().indices().get<by_symbol>();
460 auto it = idx.begin();
461 bool has_imbalanced_assets =
false;
463 while( it != idx.end() )
465 if( it->bitasset_data_id.valid() )
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 )
473 has_imbalanced_assets =
true;
474 elog(
"Genesis for asset ${aname} is not balanced\n"
476 " Supply is ${supply}\n",
477 (
"aname", it->symbol)
478 (
"debt", debt_itr->second)
479 (
"supply", supply_itr->second)
488 for(
const auto& item : total_supplies )
490 const auto& asset_id = item.first;
491 const auto& total_supply = item.second;
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;
499 const witness_object& wit = create<witness_object>([](
const witness_object&) {
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);
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);
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)
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)};
537 this->apply_operation(genesis_eval_state, std::move(op));
542 for( uint32_t i = 1; i <= genesis_state.initial_active_witnesses; ++i )
554 _p_witness_schedule_obj = & create<witness_schedule_object>([
this]( witness_schedule_object& wso )
557 wso.current_shuffled_witnesses.push_back( wid );
561 create<fba_accumulator_object>([]( fba_accumulator_object& acc )
564 acc.accumulated_fba_fees = 0;
565 #ifdef GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
570 create<fba_accumulator_object>([]( fba_accumulator_object& acc )
573 acc.accumulated_fba_fees = 0;
574 #ifdef GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET
579 create<fba_accumulator_object>([]( fba_accumulator_object& acc )
582 acc.accumulated_fba_fees = 0;
583 #ifdef GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET