Resolve #52
This commit is contained in:
parent
57e569a672
commit
c9328cc7f4
7 changed files with 67 additions and 37 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue