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

This commit is contained in:
Daniel Larimer 2015-09-28 15:42:52 -04:00
commit d3b283b60e
20 changed files with 114 additions and 73 deletions

View file

@ -260,7 +260,7 @@ namespace graphene { namespace app {
{
case impl_global_property_object_type:{
} case impl_dynamic_global_property_object_type:{
} case impl_index_meta_object_type:{
} case impl_reserved0_object_type:{
} case impl_asset_dynamic_data_type:{
} case impl_asset_bitasset_data_type:{
break;

View file

@ -273,7 +273,7 @@ signed_block database::generate_block(
signed_block result;
detail::with_skip_flags( *this, skip, [&]()
{
result = _generate_block( when, witness_id, block_signing_private_key, true );
result = _generate_block( when, witness_id, block_signing_private_key );
} );
return result;
}
@ -281,8 +281,7 @@ signed_block database::generate_block(
signed_block database::_generate_block(
fc::time_point_sec when,
witness_id_type witness_id,
const fc::ecc::private_key& block_signing_private_key,
bool retry_on_failure
const fc::ecc::private_key& block_signing_private_key
)
{
try {
@ -353,8 +352,15 @@ signed_block database::_generate_block(
{
wlog( "Postponed ${n} transactions due to block size limit", ("n", postponed_tx_count) );
}
_pending_tx_session.reset();
// We have temporarily broken the invariant that
// _pending_tx_session is the result of applying _pending_tx, as
// _pending_tx now consists of the set of postponed transactions.
// However, the push_block() call below will re-create the
// _pending_tx_session.
pending_block.previous = head_block_id();
pending_block.timestamp = when;
pending_block.transaction_merkle_root = pending_block.calculate_merkle_root();
@ -363,6 +369,7 @@ signed_block database::_generate_block(
if( !(skip & skip_witness_signature) )
pending_block.sign( block_signing_private_key );
// TODO: Move this to _push_block() so session is restored.
FC_ASSERT( fc::raw::pack_size(pending_block) <= get_global_properties().parameters.maximum_block_size );
push_block( pending_block, skip );
@ -643,4 +650,9 @@ void database::add_checkpoints( const flat_map<uint32_t,block_id_type>& checkpts
_checkpoints[i.first] = i.second;
}
bool database::before_last_checkpoint()const
{
return (_checkpoints.size() > 0) && (_checkpoints.rbegin()->first >= head_block_num());
}
} }

View file

@ -21,6 +21,9 @@
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/io/fstream.hpp>
#include <fstream>
#include <functional>
#include <iostream>
@ -105,6 +108,31 @@ void database::open(
{
try
{
auto is_new = [&]() -> bool
{
// directory doesn't exist
if( !fc::exists( data_dir ) )
return true;
// if directory exists but is empty, return true; else false.
return ( fc::directory_iterator( data_dir ) == fc::directory_iterator() );
};
auto is_outdated = [&]() -> bool
{
if( !fc::exists( data_dir / "db_version" ) )
return true;
std::string version_str;
fc::read_file_contents( data_dir / "db_version", version_str );
return (version_str != GRAPHENE_CURRENT_DB_VERSION);
};
if( (!is_new()) && is_outdated() )
{
ilog( "Old database version detected, reindex is required" );
wipe( data_dir, false );
fc::remove_all( data_dir / "db_version" );
}
object_database::open(data_dir);
_block_id_to_block.open(data_dir / "database" / "block_num_to_block");
@ -122,6 +150,19 @@ void database::open(
FC_ASSERT( head_block_num() == 0, "last block ID does not match current chain state" );
}
}
// doing this down here helps ensure that DB will be wiped
// if any of the above steps were interrupted on a previous run
if( !fc::exists( data_dir / "db_version" ) )
{
std::ofstream db_version(
(data_dir / "db_version").generic_string().c_str(),
std::ios::out | std::ios::binary | std::ios::trunc );
std::string version_string = GRAPHENE_CURRENT_DB_VERSION;
db_version.write( version_string.c_str(), version_string.size() );
db_version.close();
}
//idump((head_block_id())(head_block_num()));
}
FC_CAPTURE_AND_RETHROW( (data_dir) )
@ -155,6 +196,11 @@ void database::close(uint32_t blocks_to_rewind)
{
}
// Since pop_block() will move tx's in the popped blocks into pending,
// we have to clear_pending() after we're done popping to get a clean
// DB state (issue #336).
clear_pending();
object_database::flush();
object_database::close();

View file

@ -43,8 +43,8 @@ void database::update_global_dynamic_data( const signed_block& b )
for( uint32_t i = 0; i < missed_blocks; ++i ) {
const auto& witness_missed = get_scheduled_witness( i+1 )(*this);
if( witness_missed.id != b.witness ) {
const auto& witness_account = witness_missed.witness_account(*this);
/*
const auto& witness_account = witness_missed.witness_account(*this);
if( (fc::time_point::now() - b.timestamp) < fc::seconds(30) )
wlog( "Witness ${name} missed block ${n} around ${t}", ("name",witness_account.name)("n",b.block_num())("t",b.timestamp) );
*/

View file

@ -41,11 +41,7 @@ namespace graphene { namespace chain {
account_id_type owner;
/**
* Keep the most recent operation as a root pointer to a linked list of the transaction history. This field is
* not required by core validation and could in theory be made an annotation on the account object, but
* because transaction history is so common and this object is already cached in the undo buffer (because it
* likely affected the balances of this account) it is convienent to simply track this data here. Account
* balance objects don't currenty inherit from annotated object.
* Keep the most recent operation as a root pointer to a linked list of the transaction history.
*/
account_transaction_history_id_type most_recent_op;
@ -110,7 +106,7 @@ namespace graphene { namespace chain {
* Accounts are the primary unit of authority on the graphene system. Users must have an account in order to use
* assets, trade in the markets, vote for committee_members, etc.
*/
class account_object : public graphene::db::annotated_object<account_object>
class account_object : public graphene::db::abstract_object<account_object>
{
public:
static const uint8_t space_id = protocol_ids;
@ -134,7 +130,7 @@ namespace graphene { namespace chain {
account_id_type lifetime_referrer;
/// Percentage of fee which should go to network.
uint16_t network_fee_percentage;
uint16_t network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
/// Percentage of fee which should go to lifetime referrer.
uint16_t lifetime_referrer_fee_percentage = 0;
/// Percentage of referral rewards (leftover fee after paying network and lifetime referrer) which should go
@ -235,20 +231,6 @@ namespace graphene { namespace chain {
account_id_type get_id()const { return id; }
};
/**
* This object is attached as the meta annotation on the account object, this information is not relevant to
* validation.
*/
class meta_account_object : public graphene::db::abstract_object<meta_account_object>
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = meta_account_object_type;
public_key_type memo_key;
committee_member_id_type committee_member_id; // optional
};
/**
* @brief This secondary index will allow a reverse lookup of all accounts that a particular key or account
* is an potential signing authority.
@ -342,7 +324,7 @@ namespace graphene { namespace chain {
}}
FC_REFLECT_DERIVED( graphene::chain::account_object,
(graphene::db::annotated_object<graphene::chain::account_object>),
(graphene::db::object),
(membership_expiration_date)(registrar)(referrer)(lifetime_referrer)
(network_fee_percentage)(lifetime_referrer_fee_percentage)(referrer_rewards_percentage)
(name)(owner)(active)(options)(statistics)(whitelisting_accounts)(blacklisting_accounts)
@ -353,11 +335,8 @@ FC_REFLECT_DERIVED( graphene::chain::account_balance_object,
(graphene::db::object),
(owner)(asset_type)(balance) )
FC_REFLECT_DERIVED( graphene::chain::meta_account_object,
(graphene::db::object),
(memo_key)(committee_member_id) )
FC_REFLECT_DERIVED( graphene::chain::account_statistics_object, (graphene::chain::object),
FC_REFLECT_DERIVED( graphene::chain::account_statistics_object,
(graphene::chain::object),
(owner)
(most_recent_op)
(total_core_in_orders)

View file

@ -68,7 +68,7 @@ namespace graphene { namespace chain {
* All assets have a globally unique symbol name that controls how they are traded and an issuer who
* has authority over the parameters of the asset.
*/
class asset_object : public graphene::db::annotated_object<asset_object>
class asset_object : public graphene::db::abstract_object<asset_object>
{
public:
static const uint8_t space_id = protocol_ids;
@ -249,8 +249,7 @@ FC_REFLECT_DERIVED( graphene::chain::asset_bitasset_data_object, (graphene::db::
(settlement_fund)
)
FC_REFLECT_DERIVED( graphene::chain::asset_object,
(graphene::db::annotated_object<graphene::chain::asset_object>),
FC_REFLECT_DERIVED( graphene::chain::asset_object, (graphene::db::object),
(symbol)
(precision)
(issuer)

View file

@ -137,6 +137,8 @@
#define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4
#define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3
#define GRAPHENE_CURRENT_DB_VERSION "test3d"
/**
* Reserved Account IDs with special meaning
*/

View file

@ -122,6 +122,7 @@ namespace graphene { namespace chain {
void add_checkpoints( const flat_map<uint32_t,block_id_type>& checkpts );
const flat_map<uint32_t,block_id_type> get_checkpoints()const { return _checkpoints; }
bool before_last_checkpoint()const;
bool push_block( const signed_block& b, uint32_t skip = skip_nothing );
processed_transaction push_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );
@ -140,8 +141,7 @@ namespace graphene { namespace chain {
signed_block _generate_block(
const fc::time_point_sec when,
witness_id_type witness_id,
const fc::ecc::private_key& block_signing_private_key,
bool retry_on_failure
const fc::ecc::private_key& block_signing_private_key
);
void pop_block();

View file

@ -50,7 +50,7 @@ struct skip_flags_restorer
}
node_property_object& _npo;
uint32_t _old_skip_flags;
uint32_t _old_skip_flags; // initialized in ctor
};
/**

View file

@ -37,7 +37,7 @@ namespace graphene { namespace chain {
block_id_type previous_id()const { return data.previous; }
weak_ptr< fork_item > prev;
uint32_t num;
uint32_t num; // initialized in ctor
/**
* Used to flag a block as invalid and prevent other blocks from
* building on top of it.

View file

@ -40,7 +40,7 @@ struct genesis_state_type {
string issuer_name;
string description;
uint8_t precision;
uint8_t precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
share_type max_supply;
share_type accumulated_fees;
@ -84,7 +84,7 @@ struct genesis_state_type {
vector<initial_asset_type> initial_assets;
vector<initial_balance_type> initial_balances;
vector<initial_vesting_balance_type> initial_vesting_balances;
uint64_t initial_active_witnesses;
uint64_t initial_active_witnesses = GRAPHENE_DEFAULT_MIN_WITNESS_COUNT;
vector<initial_witness_type> initial_witness_candidates;
vector<initial_committee_member_type> initial_committee_candidates;
vector<initial_worker_type> initial_worker_candidates;

View file

@ -92,7 +92,7 @@ namespace graphene { namespace chain {
* On the @ref settlement_date the @ref balance will be converted to the collateral asset
* and paid to @ref owner and then this object will be deleted.
*/
class force_settlement_object : public graphene::db::annotated_object<force_settlement_object>
class force_settlement_object : public abstract_object<force_settlement_object>
{
public:
static const uint8_t space_id = protocol_ids;

View file

@ -33,9 +33,9 @@ namespace graphene { namespace chain {
class node_property_object
{
public:
node_property_object() : skip_flags(0) {}
node_property_object(){}
~node_property_object(){}
uint32_t skip_flags;
uint32_t skip_flags = 0;
};
} } // graphene::chain

View file

@ -141,7 +141,7 @@ namespace graphene { namespace chain {
account_id_type account_to_list;
/// The new white and blacklist status of account_to_list, as determined by authorizing_account
/// This is a bitfield using values defined in the account_listing enum
uint8_t new_listing;
uint8_t new_listing = no_listing;
extensions_type extensions;
account_id_type fee_payer()const { return authorizing_account; }

View file

@ -21,7 +21,7 @@ namespace graphene { namespace chain {
asset fee;
account_id_type payer;
flat_set<account_id_type> required_auths;
uint16_t id;
uint16_t id = 0;
vector<char> data;
account_id_type fee_payer()const { return payer; }

View file

@ -29,7 +29,7 @@ namespace graphene { namespace chain {
* be unique with high probability as long as the generating host has a high-resolution clock OR a strong source
* of entropy for generating private keys.
*/
uint64_t nonce;
uint64_t nonce = 0;
/**
* This field contains the AES encrypted packed @ref memo_message
*/

View file

@ -132,7 +132,7 @@ namespace graphene { namespace chain {
{
impl_global_property_object_type,
impl_dynamic_global_property_object_type,
impl_index_meta_object_type,
impl_reserved0_object_type, // formerly index_meta_object_type, TODO: delete me
impl_asset_dynamic_data_type,
impl_asset_bitasset_data_type,
impl_account_balance_object_type,
@ -145,12 +145,6 @@ namespace graphene { namespace chain {
impl_witness_schedule_object_type
};
enum meta_info_object_type
{
meta_asset_object_type,
meta_account_object_type
};
//typedef fc::unsigned_int object_id_type;
//typedef uint64_t object_id_type;
class account_object;
@ -186,7 +180,6 @@ namespace graphene { namespace chain {
// implementation types
class global_property_object;
class dynamic_global_property_object;
class index_meta_object;
class asset_dynamic_data_object;
class asset_bitasset_data_object;
class account_balance_object;
@ -225,8 +218,8 @@ namespace graphene { namespace chain {
{
struct binary_key
{
binary_key():check(0){}
uint32_t check;
binary_key() {}
uint32_t check = 0;
fc::ecc::public_key_data data;
};
fc::ecc::public_key_data key_data;
@ -277,7 +270,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
FC_REFLECT_ENUM( graphene::chain::impl_object_type,
(impl_global_property_object_type)
(impl_dynamic_global_property_object_type)
(impl_index_meta_object_type)
(impl_reserved0_object_type)
(impl_asset_dynamic_data_type)
(impl_asset_bitasset_data_type)
(impl_account_balance_object_type)
@ -290,8 +283,6 @@ FC_REFLECT_ENUM( graphene::chain::impl_object_type,
(impl_witness_schedule_object_type)
)
FC_REFLECT_ENUM( graphene::chain::meta_info_object_type, (meta_account_object_type)(meta_asset_object_type) )
FC_REFLECT_TYPENAME( graphene::chain::share_type )
FC_REFLECT_TYPENAME( graphene::chain::account_id_type )

View file

@ -35,9 +35,9 @@ namespace graphene { namespace chain {
/// The maximum amount authorized_account is allowed to withdraw in a given withdrawal period
asset withdrawal_limit;
/// Length of the withdrawal period in seconds
uint32_t withdrawal_period_sec;
uint32_t withdrawal_period_sec = 0;
/// The number of withdrawal periods this permission is valid for
uint32_t periods_until_expiration;
uint32_t periods_until_expiration = 0;
/// Time at which the first withdrawal period begins; must be in the future
time_point_sec period_start_time;
@ -70,11 +70,11 @@ namespace graphene { namespace chain {
/// New maximum amount the withdrawer is allowed to charge per withdrawal period
asset withdrawal_limit;
/// New length of the period between withdrawals
uint32_t withdrawal_period_sec;
uint32_t withdrawal_period_sec = 0;
/// New beginning of the next withdrawal period; must be in the future
time_point_sec period_start_time;
/// The new number of withdrawal periods for which this permission will be valid
uint32_t periods_until_expiration;
uint32_t periods_until_expiration = 0;
account_id_type fee_payer()const { return withdraw_from_account; }
void validate()const;

View file

@ -67,6 +67,19 @@ namespace graphene { namespace db {
return a.number < b.number;
}
template< typename T >
bool is() const
{
return (number >> 48) == ((T::space_id << 8) | (T::type_id));
}
template< typename T >
T as() const
{
FC_ASSERT( is<T>() );
return T( *this );
}
uint64_t number;
};

View file

@ -68,12 +68,6 @@ database_fixture::database_fixture()
boost::program_options::variables_map options;
// app.initialize();
ahplugin->plugin_set_app(&app);
ahplugin->plugin_initialize(options);
mhplugin->plugin_set_app(&app);
mhplugin->plugin_initialize(options);
genesis_state.initial_timestamp = time_point_sec( GRAPHENE_TESTING_GENESIS_TIMESTAMP );
genesis_state.initial_active_witnesses = 10;
@ -88,7 +82,14 @@ database_fixture::database_fixture()
genesis_state.initial_witness_candidates.push_back({name, init_account_priv_key.get_public_key()});
}
genesis_state.initial_parameters.current_fees->zero_all_fees();
db.init_genesis(genesis_state);
open_database();
// app.initialize();
ahplugin->plugin_set_app(&app);
ahplugin->plugin_initialize(options);
mhplugin->plugin_set_app(&app);
mhplugin->plugin_initialize(options);
ahplugin->plugin_startup();
mhplugin->plugin_startup();
@ -292,8 +293,6 @@ void database_fixture::open_database()
signed_block database_fixture::generate_block(uint32_t skip, const fc::ecc::private_key& key, int miss_blocks)
{
open_database();
skip |= database::skip_undo_history_check;
// skip == ~0 will skip checks specified in database::validation_steps
auto block = db.generate_block(db.get_slot_time(miss_blocks + 1),