Merge branch 'master' of github.com:cryptonomex/graphene

This commit is contained in:
Daniel Larimer 2015-06-29 17:29:11 -04:00
commit 873cf4dcf8
9 changed files with 102 additions and 61 deletions

View file

@ -161,12 +161,12 @@ namespace detail {
for( int i = 0; i < 10; ++i ) for( int i = 0; i < 10; ++i )
{ {
auto name = "init"+fc::to_string(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_committee.push_back({name});
initial_state.initial_witnesses.push_back({name, nathan_key.get_public_key(), secret}); 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") ) if( _options->count("genesis-json") )
initial_state = fc::json::from_file(_options->at("genesis-json").as<boost::filesystem::path>()).as<genesis_state_type>(); initial_state = fc::json::from_file(_options->at("genesis-json").as<boost::filesystem::path>()).as<genesis_state_type>();
else else
@ -195,8 +195,8 @@ namespace detail {
* If delegate has the item, the network has no need to fetch it. * If delegate has the item, the network has no need to fetch it.
*/ */
virtual bool has_item( const net::item_id& id ) override virtual bool has_item( const net::item_id& id ) override
{ {
try try
{ {
if( id.item_type == graphene::net::block_message_type ) if( id.item_type == graphene::net::block_message_type )
{ {
@ -213,8 +213,8 @@ namespace detail {
} }
else else
return _chain_db->is_known_transaction( id.item_hash ); // is_known_transaction behaves normally return _chain_db->is_known_transaction( id.item_hash ); // is_known_transaction behaves normally
} }
FC_CAPTURE_AND_RETHROW( (id) ) FC_CAPTURE_AND_RETHROW( (id) )
} }
/** /**

View file

@ -113,7 +113,7 @@ void database::initialize_indexes()
// this is the fast effecient version for validation only // this is the fast effecient version for validation only
// add_index< primary_index<simple_index<key_object>> >(); // add_index< primary_index<simple_index<key_object>> >();
// this is the slower version designed to aid GUI use. We will // this is the slower version designed to aid GUI use. We will
// default to the "slow" version until we need a faster version. // default to the "slow" version until we need a faster version.
add_index< primary_index<key_index> >(); add_index< primary_index<key_index> >();
@ -258,62 +258,57 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}); });
create<block_summary_object>([&](block_summary_object&) {}); create<block_summary_object>([&](block_summary_object&) {});
// Create user accounts, apply initial stake allocation // Create genesis balances
if( !genesis_state.allocation_targets.empty() ) if( !genesis_state.initial_balances.empty() )
{ {
share_type total_allocation = 0; share_type total_allocation = 0;
for( const auto& handout : genesis_state.allocation_targets ) // Because we do scaling on balances, the final sum may not quite reach total_allocation
total_allocation += handout.weight; // 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<asset_index>().indices().get<by_symbol>();
for( const auto& handout : genesis_state.initial_balances )
{ {
asset amount(handout.weight); final_allocation += create<balance_object>([&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_id_type key_id = apply_operation(genesis_eval_state,
key_create_operation({asset(), key_create_operation({asset(),
committee_account.id, committee_account.id,
handout.addr})).get<object_id_type>(); account.addr})).get<object_id_type>();
account_create_operation cop; account_create_operation cop;
cop.name = handout.name; cop.name = account.name;
cop.registrar = account_id_type(1); cop.registrar = account_id_type(1);
cop.active = authority(1, key_id, 1); cop.active = authority(1, key_id, 1);
cop.owner = cop.active; cop.owner = cop.active;
cop.options.memo_key = key_id; cop.options.memo_key = key_id;
account_id_type account_id(apply_operation(genesis_eval_state, cop).get<object_id_type>()); account_id_type account_id(apply_operation(genesis_eval_state, cop).get<object_id_type>());
if( handout.is_lifetime_member ) if( account.is_lifetime_member )
{ {
account_upgrade_operation op; account_upgrade_operation op;
op.account_to_upgrade = account_id; op.account_to_upgrade = account_id;
op.upgrade_to_lifetime_member = true; op.upgrade_to_lifetime_member = true;
apply_operation(genesis_eval_state, op); 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<account_balance_index>().indices().get<by_balance>().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;
});
}
} }
} }

View file

@ -18,22 +18,22 @@ namespace graphene { namespace chain {
/** /**
* @ingroup object_index * @ingroup object_index
*/ */
typedef multi_index_container< using balance_multi_index_type = multi_index_container<
balance_object, balance_object,
indexed_by< indexed_by<
hashed_unique< tag<by_id>, member< object, object_id_type, &object::id > >, hashed_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
ordered_non_unique< tag<by_owner>, composite_key< ordered_non_unique< tag<by_owner>, composite_key<
balance_object, balance_object,
member<balance_object, address, &balance_object::owner>, member<balance_object, address, &balance_object::owner>,
const_mem_fun<balance_object, asset_id_type, &balance_object::asset_type> const_mem_fun<balance_object, asset_id_type, &balance_object::asset_type>
> > > >
> >
> balance_multi_index_type; >;
/** /**
* @ingroup object_index * @ingroup object_index
*/ */
typedef generic_index<balance_object, balance_multi_index_type> balance_index; using balance_index = generic_index<balance_object, balance_multi_index_type>;
} } } }
FC_REFLECT_DERIVED( graphene::chain::balance_object, (graphene::db::object), (owner)(balance) ) FC_REFLECT_DERIVED( graphene::chain::balance_object, (graphene::db::object), (owner)(balance) )

View file

@ -40,17 +40,20 @@ namespace graphene { namespace chain {
using graphene::db::object; using graphene::db::object;
struct genesis_state_type { struct genesis_state_type {
struct allocation_target_type { struct genesis_account_type {
allocation_target_type(const string& name = string(), genesis_account_type(const string& name = string(),
const address& addr = address(), const address& addr = address(),
share_type weight = share_type(),
bool is_lifetime_member = false) 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; string name;
address addr; address addr;
share_type weight;
bool is_lifetime_member; bool is_lifetime_member;
}; };
struct genesis_balance_type {
address owner;
string asset_symbol;
share_type amount;
};
struct initial_witness_type { struct initial_witness_type {
/// Must correspond to one of the allocation targets. /// Must correspond to one of the allocation targets.
string owner_name; string owner_name;
@ -63,7 +66,8 @@ namespace graphene { namespace chain {
}; };
chain_parameters initial_parameters; chain_parameters initial_parameters;
vector<allocation_target_type> allocation_targets; vector<genesis_account_type> initial_accounts;
vector<genesis_balance_type> initial_balances;
vector<initial_witness_type> initial_witnesses; vector<initial_witness_type> initial_witnesses;
vector<initial_committee_member_type> initial_committee; vector<initial_committee_member_type> 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_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_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))

View file

@ -131,7 +131,7 @@ namespace graphene { namespace chain {
/** /**
* This operation will claim all initial balance objects owned by any of the addresses and * 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 struct balance_claim_operation
{ {
@ -145,7 +145,10 @@ namespace graphene { namespace chain {
share_type calculate_fee(const fee_schedule_type& k)const { return 0; } share_type calculate_fee(const fee_schedule_type& k)const { return 0; }
void validate()const; 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);
}
}; };
/** /**

View file

@ -57,9 +57,8 @@ BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench )
#endif #endif
for( int i = 0; i < account_count; ++i ) for( int i = 0; i < account_count; ++i )
genesis_state.allocation_targets.emplace_back("target"+fc::to_string(i), 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()), 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()); fc::temp_directory data_dir(fc::current_path());

View file

@ -66,7 +66,7 @@ database_fixture::database_fixture()
for( int i = 0; i < 10; ++i ) for( int i = 0; i < 10; ++i )
{ {
auto name = "init"+fc::to_string(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_committee.push_back({name});
genesis_state.initial_witnesses.push_back({name, delegate_priv_key.get_public_key(), secret}); genesis_state.initial_witnesses.push_back({name, delegate_priv_key.get_public_key(), secret});
} }

View file

@ -45,7 +45,7 @@ genesis_state_type make_genesis() {
for( int i = 0; i < 10; ++i ) for( int i = 0; i < 10; ++i )
{ {
auto name = "init"+fc::to_string(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_committee.push_back({name});
genesis_state.initial_witnesses.push_back({name, delegate_priv_key.get_public_key(), secret}); genesis_state.initial_witnesses.push_back({name, delegate_priv_key.get_public_key(), secret});
} }

View file

@ -23,6 +23,7 @@
#include <graphene/chain/key_object.hpp> #include <graphene/chain/key_object.hpp>
#include <graphene/chain/asset_object.hpp> #include <graphene/chain/asset_object.hpp>
#include <graphene/chain/account_object.hpp> #include <graphene/chain/account_object.hpp>
#include <graphene/chain/balance_object.hpp>
#include <graphene/chain/witness_object.hpp> #include <graphene/chain/witness_object.hpp>
#include <graphene/chain/delegate_object.hpp> #include <graphene/chain/delegate_object.hpp>
#include <graphene/chain/call_order_object.hpp> #include <graphene/chain/call_order_object.hpp>
@ -942,6 +943,43 @@ BOOST_AUTO_TEST_CASE( assert_op_test )
} FC_LOG_AND_RETHROW() } 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<balance_index>().indices().find(balance_id_type());
BOOST_CHECK_EQUAL(balance.balance.amount.value, GRAPHENE_INITIAL_SUPPLY / 2);
BOOST_CHECK_EQUAL(db.get_index_type<balance_index>().indices().find(balance_id_type())->balance.amount.value, GRAPHENE_INITIAL_SUPPLY / 2);
balance_claim_operation op;
op.deposit_to_account = db.get_index_type<account_index>().indices().get<by_name>().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 // TODO: Write linear VBO tests
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()