diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index 13a62f20..281fa8bf 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -149,9 +149,10 @@ namespace detail { fc::create_directories(_data_dir / "blockchain/dblock"); auto nathan_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); - genesis_allocation initial_allocation = {{graphene::chain::public_key_type(nathan_key.get_public_key()), 1}}; + genesis_state_type initial_state; + initial_state.allocation_targets.emplace_back("nathan", address(public_key_type(nathan_key.get_public_key())), 1); if( _options->count("genesis-json") ) - initial_allocation = fc::json::from_file(_options->at("genesis-json").as()).as(); + initial_state = fc::json::from_file(_options->at("genesis-json").as()).as(); else dlog("Allocating all stake to ${key}", ("key", utilities::key_to_wif(nathan_key))); @@ -161,12 +162,12 @@ namespace detail { if( _options->count("replay-blockchain") ) { ilog("Replaying blockchain on user request."); - _chain_db->reindex(_data_dir/"blockchain", initial_allocation); + _chain_db->reindex(_data_dir/"blockchain", initial_state); } else if( clean ) - _chain_db->open(_data_dir / "blockchain", initial_allocation); + _chain_db->open(_data_dir / "blockchain", initial_state); else { wlog("Detected unclean shutdown. Replaying blockchain..."); - _chain_db->reindex(_data_dir / "blockchain", initial_allocation); + _chain_db->reindex(_data_dir / "blockchain", initial_state); } reset_p2p_node(_data_dir); diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 95530b79..7f4d3b90 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -127,7 +127,7 @@ void database::initialize_indexes() add_index< primary_index< simple_index< witness_schedule_object > > >(); } -void database::init_genesis(const genesis_allocation& initial_allocation) +void database::init_genesis(const genesis_state_type& genesis_state) { try { _undo_db.disable(); @@ -222,7 +222,7 @@ void database::init_genesis(const genesis_allocation& initial_allocation) for( const witness_id_type& wit : init_witnesses ) p.active_witnesses.insert( wit ); p.next_available_vote_id = delegates_and_witnesses * 2; - p.chain_id = fc::digest(initial_allocation); + p.chain_id = fc::digest(genesis_state); }); (void)properties; @@ -253,11 +253,11 @@ void database::init_genesis(const genesis_allocation& initial_allocation) assert( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) ); (void)core_asset; - if( !initial_allocation.empty() ) + if( !genesis_state.allocation_targets.empty() ) { share_type total_allocation = 0; - for( const auto& handout : initial_allocation ) - total_allocation += handout.second; + for( const auto& handout : genesis_state.allocation_targets ) + total_allocation += handout.weight; auto mangle_to_name = [](const fc::static_variant& key) { string addr = string(key.which() == std::decay::type::tag
::value? key.get
() @@ -276,22 +276,22 @@ void database::init_genesis(const genesis_allocation& initial_allocation) fc::time_point start_time = fc::time_point::now(); - for( const auto& handout : initial_allocation ) + for( const auto& handout : genesis_state.allocation_targets ) { - asset amount(handout.second); + asset amount(handout.weight); amount.amount = ((fc::uint128(amount.amount.value) * GRAPHENE_INITIAL_SUPPLY)/total_allocation.value).to_uint64(); if( amount.amount == 0 ) { - wlog("Skipping zero allocation to ${k}", ("k", handout.first)); + wlog("Skipping zero allocation to ${k}", ("k", handout.name)); continue; } signed_transaction trx; - trx.operations.emplace_back(key_create_operation({asset(), genesis_account.id, handout.first})); + trx.operations.emplace_back(key_create_operation({asset(), genesis_account.id, handout.addr})); relative_key_id_type key_id(0); authority account_authority(1, key_id, 1); account_create_operation cop; - cop.name = mangle_to_name(handout.first); + cop.name = handout.name; cop.registrar = account_id_type(1); cop.active = account_authority; cop.owner = account_authority; @@ -325,7 +325,7 @@ void database::init_genesis(const genesis_allocation& initial_allocation) fc::microseconds duration = fc::time_point::now() - start_time; ilog("Finished allocating to ${n} accounts in ${t} milliseconds.", - ("n", initial_allocation.size())("t", duration.count() / 1000)); + ("n", genesis_state.allocation_targets.size())("t", duration.count() / 1000)); } _undo_db.enable(); diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp index 5ab3c837..56d09dc5 100644 --- a/libraries/chain/db_management.cpp +++ b/libraries/chain/db_management.cpp @@ -33,7 +33,7 @@ database::~database(){ _pending_block_session->commit(); } -void database::open( const fc::path& data_dir, const genesis_allocation& initial_allocation ) +void database::open( const fc::path& data_dir, const genesis_state_type& initial_allocation ) { try { ilog("Open database in ${d}", ("d", data_dir)); object_database::open( data_dir ); @@ -55,7 +55,7 @@ void database::open( const fc::path& data_dir, const genesis_allocation& initial } FC_CAPTURE_AND_RETHROW( (data_dir) ) } -void database::reindex(fc::path data_dir, const genesis_allocation& initial_allocation) +void database::reindex(fc::path data_dir, const genesis_state_type& initial_allocation) { try { wipe(data_dir, false); open(data_dir, initial_allocation); diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 58e7827b..b1b170af 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -38,7 +38,30 @@ namespace graphene { namespace chain { using graphene::db::abstract_object; using graphene::db::object; - typedef vector, share_type >> genesis_allocation; + struct genesis_state_type { + struct allocation_target_type { + allocation_target_type(const string& name = string(), const address& addr = address(), share_type weight = share_type()) + : name(name), addr(addr), weight(weight){} + string name; + address addr; + share_type weight; + }; + struct initial_witness_type { + /// Must correspond to one of the allocation targets. + string owner_name; + public_key_type block_signing_key; + secret_hash_type initial_secret; + }; + struct initial_committee_member_type { + /// Must correspond to one of the allocation targets. + string owner_name; + }; + + chain_parameters initial_parameters; + vector allocation_targets; + vector initial_witnesses; + vector initial_committee; + }; /** * @class database @@ -67,14 +90,14 @@ namespace graphene { namespace chain { skip_merkle_check = 0x200 ///< used while reindexing }; - void open(const fc::path& data_dir, const genesis_allocation& initial_allocation = genesis_allocation()); + void open(const fc::path& data_dir, const genesis_state_type& initial_allocation = genesis_state_type()); /** * @brief Rebuild object graph from block history and open detabase * * This method may be called after or instead of @ref database::open, and will rebuild the object graph by * replaying blockchain history. When this method exits successfully, the database will be open. */ - void reindex(fc::path data_dir, const genesis_allocation& initial_allocation = genesis_allocation()); + void reindex(fc::path data_dir, const genesis_state_type& initial_allocation = genesis_state_type()); /** * @brief wipe Delete database from disk, and potentially the raw chain as well. @@ -205,7 +228,7 @@ namespace graphene { namespace chain { void initialize_evaluators(); /// Reset the object graph in-memory void initialize_indexes(); - void init_genesis(const genesis_allocation& initial_allocation = genesis_allocation()); + void init_genesis(const genesis_state_type& genesis_state = genesis_state_type()); template void register_evaluator() @@ -423,3 +446,8 @@ namespace graphene { namespace chain { } } } + +FC_REFLECT(graphene::chain::genesis_state_type::allocation_target_type, (name)(addr)(weight)) +FC_REFLECT(graphene::chain::genesis_state_type::initial_witness_type, (owner_name)(block_signing_key)(initial_secret)) +FC_REFLECT(graphene::chain::genesis_state_type::initial_committee_member_type, (owner_name)) +FC_REFLECT(graphene::chain::genesis_state_type, (initial_parameters)(allocation_targets)(initial_witnesses)(initial_committee)) diff --git a/tests/app/main.cpp b/tests/app/main.cpp index 36278486..d7630550 100644 --- a/tests/app/main.cpp +++ b/tests/app/main.cpp @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE( two_node_network ) fc::temp_directory app_dir; fc::temp_directory app2_dir; fc::temp_file genesis_json; - fc::json::save_to_file(genesis_allocation(), genesis_json.path()); + fc::json::save_to_file(genesis_state_type(), genesis_json.path()); fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP ); diff --git a/tests/benchmarks/genesis_allocation.cpp b/tests/benchmarks/genesis_allocation.cpp index febc5709..a9d73f1f 100644 --- a/tests/benchmarks/genesis_allocation.cpp +++ b/tests/benchmarks/genesis_allocation.cpp @@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE( operation_sanity_check ) BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench ) { try { - genesis_allocation allocation; + genesis_state_type genesis_state; #ifdef NDEBUG ilog("Running in release mode."); @@ -57,14 +57,15 @@ BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench ) #endif for( int i = 0; i < account_count; ++i ) - allocation.emplace_back(public_key_type(fc::ecc::private_key::regenerate(fc::digest(i)).get_public_key()), - GRAPHENE_INITIAL_SUPPLY / account_count); + genesis_state.allocation_targets.emplace_back("target"+fc::to_string(i), + public_key_type(fc::ecc::private_key::regenerate(fc::digest(i)).get_public_key()), + GRAPHENE_INITIAL_SUPPLY / account_count); fc::temp_directory data_dir(fc::current_path()); { database db; - db.open(data_dir.path(), allocation); + db.open(data_dir.path(), genesis_state); for( int i = 11; i < account_count + 11; ++i) BOOST_CHECK(db.get_balance(account_id_type(i), asset_id_type()).amount == GRAPHENE_INITIAL_SUPPLY / account_count); @@ -110,7 +111,7 @@ BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench ) auto start_time = fc::time_point::now(); wlog( "about to start reindex..." ); - db.reindex(data_dir.path(), allocation); + db.reindex(data_dir.path(), genesis_state); ilog("Replayed database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000)); for( int i = 0; i < blocks_to_produce; ++i ) diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 958b30d2..169fb2f7 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -116,7 +116,7 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks ) auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) ); { database db; - db.open(data_dir.path(), genesis_allocation() ); + db.open(data_dir.path(), genesis_state_type() ); b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key ); for( uint32_t i = 1; i < 200; ++i ) @@ -161,7 +161,7 @@ BOOST_AUTO_TEST_CASE( undo_block ) fc::temp_directory data_dir; { database db; - db.open(data_dir.path(), genesis_allocation() ); + db.open(data_dir.path(), genesis_state_type() ); fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP ); auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) ); @@ -204,15 +204,15 @@ BOOST_AUTO_TEST_CASE( fork_blocks ) fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP ); database db1; - db1.open( data_dir1.path(), genesis_allocation() ); + db1.open(data_dir1.path(), genesis_state_type()); database db2; - db2.open( data_dir2.path(), genesis_allocation() ); + db2.open(data_dir2.path(), genesis_state_type()); auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) ); for( uint32_t i = 0; i < 10; ++i ) { now += db1.block_interval(); - auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key ); + auto b = db1.generate_block(now, db1.get_scheduled_witness(1).first, delegate_priv_key); try { db2.push_block(b); } FC_CAPTURE_AND_RETHROW( ("db2") ); @@ -220,13 +220,13 @@ BOOST_AUTO_TEST_CASE( fork_blocks ) for( uint32_t i = 10; i < 13; ++i ) { now += db1.block_interval(); - auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key ); + auto b = db1.generate_block(now, db1.get_scheduled_witness(1).first, delegate_priv_key); } string db1_tip = db1.head_block_id().str(); for( uint32_t i = 13; i < 16; ++i ) { now += db2.block_interval(); - auto b = db2.generate_block( now, db2.get_scheduled_witness( db2.get_slot_at_time( now ) ).first, delegate_priv_key ); + auto b = db2.generate_block(now, db2.get_scheduled_witness(db2.get_slot_at_time(now)).first, delegate_priv_key); // notify both databases of the new block. // only db2 should switch to the new fork, db1 should not db1.push_block(b); @@ -241,7 +241,7 @@ BOOST_AUTO_TEST_CASE( fork_blocks ) BOOST_CHECK_EQUAL(db2.head_block_num(), 13); { now += db2.block_interval(); - auto b = db2.generate_block( now, db2.get_scheduled_witness( 1 ).first, delegate_priv_key ); + auto b = db2.generate_block(now, db2.get_scheduled_witness(1).first, delegate_priv_key); good_block = b; b.transactions.emplace_back(signed_transaction()); b.transactions.back().operations.emplace_back(transfer_operation()); @@ -265,7 +265,7 @@ BOOST_AUTO_TEST_CASE( fork_blocks ) BOOST_AUTO_TEST_CASE( undo_pending ) { try { - fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP ); + fc::time_point_sec now(GRAPHENE_GENESIS_TIMESTAMP); fc::temp_directory data_dir; { database db;