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");
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<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
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);

View file

@ -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<public_key_type, address>& key) {
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();
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();

View file

@ -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);

View file

@ -38,7 +38,30 @@ namespace graphene { namespace chain {
using graphene::db::abstract_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
@ -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<typename EvaluatorType>
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 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 );

View file

@ -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 )

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")) );
{
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;