This commit is contained in:
Nathan Hourt 2015-06-17 11:47:50 -04:00
parent 57e569a672
commit c9328cc7f4
7 changed files with 67 additions and 37 deletions

View file

@ -149,9 +149,10 @@ namespace detail {
fc::create_directories(_data_dir / "blockchain/dblock"); fc::create_directories(_data_dir / "blockchain/dblock");
auto nathan_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); 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") ) if( _options->count("genesis-json") )
initial_allocation = fc::json::from_file(_options->at("genesis-json").as<boost::filesystem::path>()).as<genesis_allocation>(); initial_state = fc::json::from_file(_options->at("genesis-json").as<boost::filesystem::path>()).as<genesis_state_type>();
else else
dlog("Allocating all stake to ${key}", ("key", utilities::key_to_wif(nathan_key))); dlog("Allocating all stake to ${key}", ("key", utilities::key_to_wif(nathan_key)));
@ -161,12 +162,12 @@ namespace detail {
if( _options->count("replay-blockchain") ) if( _options->count("replay-blockchain") )
{ {
ilog("Replaying blockchain on user request."); 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 ) } else if( clean )
_chain_db->open(_data_dir / "blockchain", initial_allocation); _chain_db->open(_data_dir / "blockchain", initial_state);
else { else {
wlog("Detected unclean shutdown. Replaying blockchain..."); 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); reset_p2p_node(_data_dir);

View file

@ -127,7 +127,7 @@ void database::initialize_indexes()
add_index< primary_index< simple_index< witness_schedule_object > > >(); 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 { { try {
_undo_db.disable(); _undo_db.disable();
@ -222,7 +222,7 @@ void database::init_genesis(const genesis_allocation& initial_allocation)
for( const witness_id_type& wit : init_witnesses ) for( const witness_id_type& wit : init_witnesses )
p.active_witnesses.insert( wit ); p.active_witnesses.insert( wit );
p.next_available_vote_id = delegates_and_witnesses * 2; 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; (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) ); assert( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) );
(void)core_asset; (void)core_asset;
if( !initial_allocation.empty() ) if( !genesis_state.allocation_targets.empty() )
{ {
share_type total_allocation = 0; share_type total_allocation = 0;
for( const auto& handout : initial_allocation ) for( const auto& handout : genesis_state.allocation_targets )
total_allocation += handout.second; total_allocation += handout.weight;
auto mangle_to_name = [](const fc::static_variant<public_key_type, address>& key) { auto mangle_to_name = [](const fc::static_variant<public_key_type, address>& key) {
string addr = string(key.which() == std::decay<decltype(key)>::type::tag<address>::value? key.get<address>() string addr = string(key.which() == std::decay<decltype(key)>::type::tag<address>::value? key.get<address>()
@ -276,22 +276,22 @@ void database::init_genesis(const genesis_allocation& initial_allocation)
fc::time_point start_time = fc::time_point::now(); 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(); amount.amount = ((fc::uint128(amount.amount.value) * GRAPHENE_INITIAL_SUPPLY)/total_allocation.value).to_uint64();
if( amount.amount == 0 ) if( amount.amount == 0 )
{ {
wlog("Skipping zero allocation to ${k}", ("k", handout.first)); wlog("Skipping zero allocation to ${k}", ("k", handout.name));
continue; continue;
} }
signed_transaction trx; 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); relative_key_id_type key_id(0);
authority account_authority(1, key_id, 1); authority account_authority(1, key_id, 1);
account_create_operation cop; account_create_operation cop;
cop.name = mangle_to_name(handout.first); cop.name = handout.name;
cop.registrar = account_id_type(1); cop.registrar = account_id_type(1);
cop.active = account_authority; cop.active = account_authority;
cop.owner = 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; fc::microseconds duration = fc::time_point::now() - start_time;
ilog("Finished allocating to ${n} accounts in ${t} milliseconds.", 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(); _undo_db.enable();

View file

@ -33,7 +33,7 @@ database::~database(){
_pending_block_session->commit(); _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 { { try {
ilog("Open database in ${d}", ("d", data_dir)); ilog("Open database in ${d}", ("d", data_dir));
object_database::open( 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) ) } } 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 { { try {
wipe(data_dir, false); wipe(data_dir, false);
open(data_dir, initial_allocation); open(data_dir, initial_allocation);

View file

@ -38,7 +38,30 @@ namespace graphene { namespace chain {
using graphene::db::abstract_object; using graphene::db::abstract_object;
using graphene::db::object; using graphene::db::object;
typedef vector<std::pair<fc::static_variant<address, public_key_type>, 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_target_type> allocation_targets;
vector<initial_witness_type> initial_witnesses;
vector<initial_committee_member_type> initial_committee;
};
/** /**
* @class database * @class database
@ -67,14 +90,14 @@ namespace graphene { namespace chain {
skip_merkle_check = 0x200 ///< used while reindexing 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 * @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 * 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. * 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. * @brief wipe Delete database from disk, and potentially the raw chain as well.
@ -205,7 +228,7 @@ namespace graphene { namespace chain {
void initialize_evaluators(); void initialize_evaluators();
/// Reset the object graph in-memory /// Reset the object graph in-memory
void initialize_indexes(); 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<typename EvaluatorType> template<typename EvaluatorType>
void register_evaluator() 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))

View file

@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE( two_node_network )
fc::temp_directory app_dir; fc::temp_directory app_dir;
fc::temp_directory app2_dir; fc::temp_directory app2_dir;
fc::temp_file genesis_json; 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 ); fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP );

View file

@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE( operation_sanity_check )
BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench ) BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench )
{ {
try { try {
genesis_allocation allocation; genesis_state_type genesis_state;
#ifdef NDEBUG #ifdef NDEBUG
ilog("Running in release mode."); ilog("Running in release mode.");
@ -57,14 +57,15 @@ 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 )
allocation.emplace_back(public_key_type(fc::ecc::private_key::regenerate(fc::digest(i)).get_public_key()), genesis_state.allocation_targets.emplace_back("target"+fc::to_string(i),
GRAPHENE_INITIAL_SUPPLY / account_count); 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());
{ {
database db; database db;
db.open(data_dir.path(), allocation); db.open(data_dir.path(), genesis_state);
for( int i = 11; i < account_count + 11; ++i) 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); 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(); auto start_time = fc::time_point::now();
wlog( "about to start reindex..." ); 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)); ilog("Replayed database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));
for( int i = 0; i < blocks_to_produce; ++i ) for( int i = 0; i < blocks_to_produce; ++i )

View file

@ -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")) ); auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) );
{ {
database db; 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 ); b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key );
for( uint32_t i = 1; i < 200; ++i ) for( uint32_t i = 1; i < 200; ++i )
@ -161,7 +161,7 @@ BOOST_AUTO_TEST_CASE( undo_block )
fc::temp_directory data_dir; fc::temp_directory data_dir;
{ {
database db; 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 ); fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP );
auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) ); 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 ); fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP );
database db1; database db1;
db1.open( data_dir1.path(), genesis_allocation() ); db1.open(data_dir1.path(), genesis_state_type());
database db2; 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")) ); auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) );
for( uint32_t i = 0; i < 10; ++i ) for( uint32_t i = 0; i < 10; ++i )
{ {
now += db1.block_interval(); 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 { try {
db2.push_block(b); db2.push_block(b);
} FC_CAPTURE_AND_RETHROW( ("db2") ); } FC_CAPTURE_AND_RETHROW( ("db2") );
@ -220,13 +220,13 @@ BOOST_AUTO_TEST_CASE( fork_blocks )
for( uint32_t i = 10; i < 13; ++i ) for( uint32_t i = 10; i < 13; ++i )
{ {
now += db1.block_interval(); 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(); string db1_tip = db1.head_block_id().str();
for( uint32_t i = 13; i < 16; ++i ) for( uint32_t i = 13; i < 16; ++i )
{ {
now += db2.block_interval(); 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. // notify both databases of the new block.
// only db2 should switch to the new fork, db1 should not // only db2 should switch to the new fork, db1 should not
db1.push_block(b); db1.push_block(b);
@ -241,7 +241,7 @@ BOOST_AUTO_TEST_CASE( fork_blocks )
BOOST_CHECK_EQUAL(db2.head_block_num(), 13); BOOST_CHECK_EQUAL(db2.head_block_num(), 13);
{ {
now += db2.block_interval(); 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; good_block = b;
b.transactions.emplace_back(signed_transaction()); b.transactions.emplace_back(signed_transaction());
b.transactions.back().operations.emplace_back(transfer_operation()); b.transactions.back().operations.emplace_back(transfer_operation());
@ -265,7 +265,7 @@ BOOST_AUTO_TEST_CASE( fork_blocks )
BOOST_AUTO_TEST_CASE( undo_pending ) BOOST_AUTO_TEST_CASE( undo_pending )
{ {
try { try {
fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP ); fc::time_point_sec now(GRAPHENE_GENESIS_TIMESTAMP);
fc::temp_directory data_dir; fc::temp_directory data_dir;
{ {
database db; database db;