Merge branch 'master' of github.com:cryptonomex/graphene
This commit is contained in:
commit
d3b283b60e
20 changed files with 114 additions and 73 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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) );
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Reference in a new issue