diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index 1c1a2f41..8f775bbd 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -161,12 +161,12 @@ namespace detail { for( int i = 0; i < 10; ++i ) { auto name = "init"+fc::to_string(i); - initial_state.allocation_targets.emplace_back(name, nathan_key.get_public_key(), 0, true); + initial_state.initial_accounts.emplace_back(name, nathan_key.get_public_key(), true); initial_state.initial_committee.push_back({name}); initial_state.initial_witnesses.push_back({name, nathan_key.get_public_key(), secret}); } - initial_state.allocation_targets.emplace_back("nathan", address(public_key_type(nathan_key.get_public_key())), 1); + initial_state.initial_accounts.emplace_back("nathan", address(public_key_type(nathan_key.get_public_key())), 1); if( _options->count("genesis-json") ) initial_state = fc::json::from_file(_options->at("genesis-json").as()).as(); else @@ -195,8 +195,8 @@ namespace detail { * If delegate has the item, the network has no need to fetch it. */ virtual bool has_item( const net::item_id& id ) override - { - try + { + try { if( id.item_type == graphene::net::block_message_type ) { @@ -213,8 +213,8 @@ namespace detail { } else return _chain_db->is_known_transaction( id.item_hash ); // is_known_transaction behaves normally - } - FC_CAPTURE_AND_RETHROW( (id) ) + } + FC_CAPTURE_AND_RETHROW( (id) ) } /** diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 7ccb01ec..7346d8d4 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -113,7 +113,7 @@ void database::initialize_indexes() // this is the fast effecient version for validation only // add_index< primary_index> >(); - + // this is the slower version designed to aid GUI use. We will // default to the "slow" version until we need a faster version. add_index< primary_index >(); @@ -255,62 +255,57 @@ void database::init_genesis(const genesis_state_type& genesis_state) }); create([&](block_summary_object&) {}); - // Create user accounts, apply initial stake allocation - if( !genesis_state.allocation_targets.empty() ) + // Create genesis balances + if( !genesis_state.initial_balances.empty() ) { share_type total_allocation = 0; - for( const auto& handout : genesis_state.allocation_targets ) - total_allocation += handout.weight; + // Because we do scaling on balances, the final sum may not quite reach total_allocation + // Store the actual number of shares created here + share_type final_allocation = 0; + for( const auto& handout : genesis_state.initial_balances ) + total_allocation += handout.amount; - for( const auto& handout : genesis_state.allocation_targets ) + const auto& asset_idx = get_index_type().indices().get(); + for( const auto& handout : genesis_state.initial_balances ) { - asset amount(handout.weight); + final_allocation += create([&handout,&asset_idx,total_allocation](balance_object& b) { + b.balance = asset(handout.amount, asset_idx.find(handout.asset_symbol)->get_id()); + b.balance.amount = ((fc::uint128(b.balance.amount.value) * GRAPHENE_INITIAL_SUPPLY)/total_allocation.value).to_uint64(); + b.owner = handout.owner; + }).balance.amount; + } + assert(final_allocation <= dyn_asset.current_supply); + if( final_allocation < dyn_asset.current_supply ) + modify(dyn_asset, [final_allocation](asset_dynamic_data_object& d) { + d.current_supply = final_allocation; + }); + } + + // Create initial accounts + if( !genesis_state.initial_accounts.empty() ) + { + for( const auto& account : genesis_state.initial_accounts ) + { key_id_type key_id = apply_operation(genesis_eval_state, key_create_operation({asset(), committee_account.id, - handout.addr})).get(); + account.addr})).get(); account_create_operation cop; - cop.name = handout.name; + cop.name = account.name; cop.registrar = account_id_type(1); cop.active = authority(1, key_id, 1); cop.owner = cop.active; cop.options.memo_key = key_id; account_id_type account_id(apply_operation(genesis_eval_state, cop).get()); - if( handout.is_lifetime_member ) + if( account.is_lifetime_member ) { account_upgrade_operation op; op.account_to_upgrade = account_id; op.upgrade_to_lifetime_member = true; apply_operation(genesis_eval_state, op); } - - if( amount.amount > 0 ) - { - amount.amount = ((fc::uint128(amount.amount.value) * GRAPHENE_INITIAL_SUPPLY)/total_allocation.value).to_uint64(); - apply_operation(genesis_eval_state, transfer_operation({asset(), - committee_account.id, - account_id, - amount, - memo_data() - })); - } - } - - if( total_allocation != 0 ) - { - asset leftovers = get_balance(account_id_type(), asset_id_type()); - if( leftovers.amount > 0 ) - { - modify(*get_index_type().indices().get().find(boost::make_tuple(account_id_type(), asset_id_type())), - [](account_balance_object& b) { - b.adjust_balance(-b.get_balance()); - }); - modify(core_asset.dynamic_asset_data_id(*this), [&leftovers](asset_dynamic_data_object& d) { - d.accumulated_fees += leftovers.amount; - }); - } } } diff --git a/libraries/chain/include/graphene/chain/balance_object.hpp b/libraries/chain/include/graphene/chain/balance_object.hpp index e1a5fb32..9bbe6913 100644 --- a/libraries/chain/include/graphene/chain/balance_object.hpp +++ b/libraries/chain/include/graphene/chain/balance_object.hpp @@ -18,22 +18,22 @@ namespace graphene { namespace chain { /** * @ingroup object_index */ - typedef multi_index_container< + using balance_multi_index_type = multi_index_container< balance_object, indexed_by< hashed_unique< tag, member< object, object_id_type, &object::id > >, ordered_non_unique< tag, composite_key< balance_object, member, - const_mem_fun + const_mem_fun > > > - > balance_multi_index_type; + >; /** * @ingroup object_index */ - typedef generic_index balance_index; + using balance_index = generic_index; } } FC_REFLECT_DERIVED( graphene::chain::balance_object, (graphene::db::object), (owner)(balance) ) diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 9e003fe6..ac940567 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -40,17 +40,20 @@ namespace graphene { namespace chain { using graphene::db::object; struct genesis_state_type { - struct allocation_target_type { - allocation_target_type(const string& name = string(), + struct genesis_account_type { + genesis_account_type(const string& name = string(), const address& addr = address(), - share_type weight = share_type(), bool is_lifetime_member = false) - : name(name), addr(addr), weight(weight),is_lifetime_member(is_lifetime_member){} + : name(name), addr(addr), is_lifetime_member(is_lifetime_member){} string name; address addr; - share_type weight; bool is_lifetime_member; }; + struct genesis_balance_type { + address owner; + string asset_symbol; + share_type amount; + }; struct initial_witness_type { /// Must correspond to one of the allocation targets. string owner_name; @@ -63,7 +66,8 @@ namespace graphene { namespace chain { }; chain_parameters initial_parameters; - vector allocation_targets; + vector initial_accounts; + vector initial_balances; vector initial_witnesses; vector initial_committee; }; @@ -511,7 +515,9 @@ namespace graphene { namespace chain { } } } -FC_REFLECT(graphene::chain::genesis_state_type::allocation_target_type, (name)(addr)(weight)) +FC_REFLECT(graphene::chain::genesis_state_type::genesis_account_type, (name)(addr)(is_lifetime_member)) +FC_REFLECT(graphene::chain::genesis_state_type::genesis_balance_type, + (owner)(asset_symbol)(amount)) 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)) +FC_REFLECT(graphene::chain::genesis_state_type, (initial_parameters)(initial_accounts)(initial_balances)(initial_witnesses)(initial_committee)) diff --git a/libraries/chain/include/graphene/chain/operations.hpp b/libraries/chain/include/graphene/chain/operations.hpp index 232e7318..6d910037 100644 --- a/libraries/chain/include/graphene/chain/operations.hpp +++ b/libraries/chain/include/graphene/chain/operations.hpp @@ -131,7 +131,7 @@ namespace graphene { namespace chain { /** * This operation will claim all initial balance objects owned by any of the addresses and - * deposit them into the deposit_to_account. + * deposit them into the deposit_to_account. */ struct balance_claim_operation { @@ -145,7 +145,10 @@ namespace graphene { namespace chain { share_type calculate_fee(const fee_schedule_type& k)const { return 0; } void validate()const; - void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), total_claimed-fee); } + void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { + acc.adjust(fee_payer(), total_claimed); + acc.adjust(fee_payer(), -fee); + } }; /** diff --git a/tests/benchmarks/genesis_allocation.cpp b/tests/benchmarks/genesis_allocation.cpp index 92e64dd9..9bc63769 100644 --- a/tests/benchmarks/genesis_allocation.cpp +++ b/tests/benchmarks/genesis_allocation.cpp @@ -57,9 +57,8 @@ BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench ) #endif for( int i = 0; i < account_count; ++i ) - 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); + genesis_state.initial_accounts.emplace_back("target"+fc::to_string(i), + public_key_type(fc::ecc::private_key::regenerate(fc::digest(i)).get_public_key())); fc::temp_directory data_dir(fc::current_path()); diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index ee59c4a1..93e92530 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -66,7 +66,7 @@ database_fixture::database_fixture() for( int i = 0; i < 10; ++i ) { auto name = "init"+fc::to_string(i); - genesis_state.allocation_targets.emplace_back(name, delegate_priv_key.get_public_key(), 0, true); + genesis_state.initial_accounts.emplace_back(name, delegate_priv_key.get_public_key(), true); genesis_state.initial_committee.push_back({name}); genesis_state.initial_witnesses.push_back({name, delegate_priv_key.get_public_key(), secret}); } diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index f838dc34..70abf474 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -45,7 +45,7 @@ genesis_state_type make_genesis() { for( int i = 0; i < 10; ++i ) { auto name = "init"+fc::to_string(i); - genesis_state.allocation_targets.emplace_back(name, delegate_priv_key.get_public_key(), 0, true); + genesis_state.initial_accounts.emplace_back(name, delegate_priv_key.get_public_key(), true); genesis_state.initial_committee.push_back({name}); genesis_state.initial_witnesses.push_back({name, delegate_priv_key.get_public_key(), secret}); } diff --git a/tests/tests/operation_tests2.cpp b/tests/tests/operation_tests2.cpp index 2416139d..064a5517 100644 --- a/tests/tests/operation_tests2.cpp +++ b/tests/tests/operation_tests2.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -942,6 +943,43 @@ BOOST_AUTO_TEST_CASE( assert_op_test ) } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE( balance_object_test ) +{ try { + // Intentionally overriding the fixture's db; I need to control genesis on this one. + database db; + fc::temp_directory td; + genesis_state.initial_balances.push_back({generate_private_key("n").get_public_key(), GRAPHENE_SYMBOL, 1}); + genesis_state.initial_balances.push_back({generate_private_key("m").get_public_key(), GRAPHENE_SYMBOL, 1}); + genesis_state.initial_accounts.emplace_back("n", generate_private_key("n").get_public_key(), false); + + db.open(td.path(), genesis_state); + const balance_object& balance = *db.get_index_type().indices().find(balance_id_type()); + BOOST_CHECK_EQUAL(balance.balance.amount.value, GRAPHENE_INITIAL_SUPPLY / 2); + BOOST_CHECK_EQUAL(db.get_index_type().indices().find(balance_id_type())->balance.amount.value, GRAPHENE_INITIAL_SUPPLY / 2); + + balance_claim_operation op; + op.deposit_to_account = db.get_index_type().indices().get().find("n")->get_id(); + op.total_claimed = asset(GRAPHENE_INITIAL_SUPPLY / 2); + op.owners.insert(genesis_state.initial_balances.back().owner); + trx.operations = {op}; + trx.sign(*op.owners.begin(), generate_private_key("n")); + trx.sign(op.deposit_to_account(db).active.get_keys().front(), generate_private_key("n")); + // Fail because I'm claiming the wrong address + BOOST_CHECK_THROW(db.push_transaction(trx), fc::exception); + trx.clear(); + op.owners = {genesis_state.initial_balances.front().owner}; + trx.operations = {op}; + trx.sign(*op.owners.begin(), generate_private_key("n")); + trx.sign(op.deposit_to_account(db).active.get_keys().front(), generate_private_key("n")); + // Fail because I'm claiming the wrong address + db.push_transaction(trx); + + // Not using fixture's get_balance() here because it uses fixture's db, not my override + BOOST_CHECK_EQUAL(db.get_balance(op.deposit_to_account, asset_id_type()).amount.value, GRAPHENE_INITIAL_SUPPLY / 2); +} FC_LOG_AND_RETHROW() } + // TODO: Write linear VBO tests BOOST_AUTO_TEST_SUITE_END() + +