提交 f414fe04 编写于 作者: N Nathan Hourt

Unify db_*.cpp files

All the db_*.cpp sources are now merged together in database.cpp again.
上级 0e43c707
......@@ -2,29 +2,9 @@
file(GLOB HEADERS "include/eos/chain/*.hpp")
file(GLOB PROTOCOL_HEADERS "include/eos/chain/protocol/*.hpp")
if( EOS_DISABLE_UNITY_BUILD )
set( EOS_DB_FILES
db_block.cpp
db_debug.cpp
db_getter.cpp
db_init.cpp
db_maint.cpp
db_management.cpp
db_update.cpp
db_producer_schedule.cpp
)
message( STATUS "Eos database unity build disabled" )
else( EOS_DISABLE_UNITY_BUILD )
set( EOS_DB_FILES
database.cpp )
message( STATUS "Eos database unity build enabled" )
endif( EOS_DISABLE_UNITY_BUILD )
## SORT .cpp by most likely to change / break compile
add_library( eos_chain
# As database takes the longest to compile, start it first
${EOS_DB_FILES}
database.cpp
fork_database.cpp
protocol/types.cpp
......
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <eos/chain/database.hpp>
#include <eos/chain/producer_object.hpp>
namespace eos { namespace chain {
/**
* This method dumps the state of the blockchain in a semi-human readable form for the
* purpose of tracking down funds and mismatches in currency allocation
*/
void database::debug_dump()
{
}
void debug_apply_update( database& db, const fc::variant_object& vo )
{
}
void database::apply_debug_updates()
{
}
void database::debug_update( const fc::variant_object& update )
{
}
} }
/*
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <eos/chain/database.hpp>
#include <eos/chain/chain_property_object.hpp>
#include <eos/chain/global_property_object.hpp>
#include <fc/smart_ref_impl.hpp>
namespace eos { namespace chain {
const global_property_object& database::get_global_properties()const
{
return get<global_property_object>();
}
const dynamic_global_property_object&database::get_dynamic_global_properties() const
{
return get<dynamic_global_property_object>();
}
time_point_sec database::head_block_time()const
{
return get_dynamic_global_properties().time;
}
uint32_t database::head_block_num()const
{
return get_dynamic_global_properties().head_block_number;
}
block_id_type database::head_block_id()const
{
return get_dynamic_global_properties().head_block_id;
}
producer_id_type database::head_block_producer() const
{
if (auto head_block = fetch_block_by_id(head_block_id()))
return head_block->producer;
return {};
}
decltype( chain_parameters::block_interval ) database::block_interval( )const
{
return get_global_properties().parameters.block_interval;
}
const chain_id_type& database::get_chain_id( )const
{
return get<chain_property_object>().chain_id;
}
const node_property_object& database::get_node_properties()const
{
return _node_property_object;
}
node_property_object& database::node_properties()
{
return _node_property_object;
}
uint32_t database::last_non_undoable_block_num() const
{
#warning TODO: Figure out how to do this
return 1; //head_block_num() - _undo_db.size();
}
} }
/*
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <eos/chain/database.hpp>
#include <eos/chain/account_object.hpp>
#include <eos/chain/block_summary_object.hpp>
#include <eos/chain/chain_property_object.hpp>
#include <eos/chain/global_property_object.hpp>
#include <eos/chain/operation_history_object.hpp>
#include <eos/chain/transaction_object.hpp>
#include <eos/chain/producer_object.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/uint128.hpp>
#include <fc/crypto/digest.hpp>
#include <boost/algorithm/string.hpp>
namespace eos { namespace chain {
// C++ requires that static class variables declared and initialized
// in headers must also have a definition in a single source file,
// else linker errors will occur [1].
//
// The purpose of this source file is to collect such definitions in
// a single place.
//
// [1] http://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char
void database::initialize_evaluators()
{
_operation_evaluators.resize(255);
// TODO: Figure out how to do this
}
void database::initialize_indexes()
{
add_index<account_multi_index>();
add_index<global_property_multi_index>();
add_index<dynamic_global_property_multi_index>();
add_index<block_summary_multi_index>();
add_index<transaction_multi_index>();
add_index<producer_multi_index>();
add_index<chain_property_multi_index>();
}
void database::init_genesis(const genesis_state_type& genesis_state)
{ try {
FC_ASSERT( genesis_state.initial_timestamp != time_point_sec(), "Must initialize genesis timestamp." );
FC_ASSERT( genesis_state.initial_timestamp.sec_since_epoch() % EOS_DEFAULT_BLOCK_INTERVAL == 0,
"Genesis timestamp must be divisible by EOS_DEFAULT_BLOCK_INTERVAL." );
FC_ASSERT(genesis_state.initial_producer_count >= genesis_state.initial_producers.size(),
"Initial producer count is ${c} but only ${w} producers were defined.",
("c", genesis_state.initial_producer_count)("w", genesis_state.initial_producers.size()));
struct auth_inhibitor {
auth_inhibitor(database& db) : db(db), old_flags(db.node_properties().skip_flags)
{ db.node_properties().skip_flags |= skip_authority_check; }
~auth_inhibitor()
{ db.node_properties().skip_flags = old_flags; }
private:
database& db;
uint32_t old_flags;
} inhibitor(*this);
// Create initial accounts
for (const auto& acct : genesis_state.initial_accounts) {
create<account_object>([&acct](account_object& a) {
a.name = acct.name.c_str();
a.active_key = acct.active_key;
a.owner_key = acct.owner_key;
});
}
// Create initial producers
std::vector<producer_id_type> initialProducers;
for (const auto& producer : genesis_state.initial_producers) {
auto owner = find<account_object, by_name>(producer.owner_name);
FC_ASSERT(owner != nullptr, "Producer belongs to an unknown account: ${acct}", ("acct", producer.owner_name));
auto id = create<producer_object>([&producer](producer_object& w) {
w.signing_key = producer.block_signing_key;
w.owner_name = producer.owner_name.c_str();
}).id;
initialProducers.push_back(id);
}
transaction_evaluation_state genesis_eval_state(this);
// Initialize block summary index
chain_id_type chain_id = genesis_state.compute_chain_id();
// Create global properties
create<global_property_object>([&](global_property_object& p) {
p.parameters = genesis_state.initial_parameters;
p.active_producers = initialProducers;
});
create<dynamic_global_property_object>([&](dynamic_global_property_object& p) {
p.time = genesis_state.initial_timestamp;
p.dynamic_flags = 0;
p.recent_slots_filled = fc::uint128::max_value();
});
FC_ASSERT( (genesis_state.immutable_parameters.min_producer_count & 1) == 1, "min_producer_count must be odd" );
create<chain_property_object>([&](chain_property_object& p)
{
p.chain_id = chain_id;
p.immutable_parameters = genesis_state.immutable_parameters;
} );
create<block_summary_object>([&](block_summary_object&) {});
//TODO: Figure out how to do this
// Create initial accounts
// Create initial producers
// Set active producers
} FC_CAPTURE_AND_RETHROW() }
} }
/*
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <eos/chain/database.hpp>
#include <eos/chain/operation_history_object.hpp>
#include <fc/io/fstream.hpp>
#include <fstream>
#include <functional>
#include <iostream>
namespace eos { namespace chain {
database::database()
{}
database::~database()
{
clear_pending();
}
void database::reindex(fc::path data_dir, uint64_t shared_file_size, const genesis_state_type& initial_allocation)
{ try {
ilog( "reindexing blockchain" );
wipe(data_dir, false);
open(data_dir, shared_file_size, [&initial_allocation]{return initial_allocation;});
auto start = fc::time_point::now();
auto last_block = _block_id_to_block.last();
if( !last_block ) {
elog( "!no last block" );
edump((last_block));
return;
}
const auto last_block_num = last_block->block_num();
ilog( "Replaying blocks..." );
// _undo_db.disable();
for( uint32_t i = 1; i <= last_block_num; ++i )
{
if( i % 5000 == 0 ) std::cerr << " " << double(i*100)/last_block_num << "% "<<i << " of " <<last_block_num<<" \n";
fc::optional< signed_block > block = _block_id_to_block.fetch_by_number(i);
if( !block.valid() )
{
wlog( "Reindexing terminated due to gap: Block ${i} does not exist!", ("i", i) );
uint32_t dropped_count = 0;
while( true )
{
fc::optional< block_id_type > last_id = _block_id_to_block.last_id();
// this can trigger if we attempt to e.g. read a file that has block #2 but no block #1
if( !last_id.valid() )
break;
// we've caught up to the gap
if( block_header::num_from_id( *last_id ) <= i )
break;
_block_id_to_block.remove( *last_id );
dropped_count++;
}
wlog( "Dropped ${n} blocks from after the gap", ("n", dropped_count) );
break;
}
apply_block(*block, skip_producer_signature |
skip_transaction_signatures |
skip_transaction_dupe_check |
skip_tapos_check |
skip_producer_schedule_check |
skip_authority_check);
}
// _undo_db.enable();
auto end = fc::time_point::now();
ilog( "Done reindexing, elapsed time: ${t} sec", ("t",double((end-start).count())/1000000.0 ) );
} FC_CAPTURE_AND_RETHROW( (data_dir) ) }
void database::wipe(const fc::path& data_dir, bool include_blocks)
{
ilog("Wiping database", ("include_blocks", include_blocks));
close();
chainbase::database::wipe(data_dir);
if( include_blocks )
fc::remove_all( data_dir / "database" );
}
void database::open(const fc::path& data_dir, uint64_t shared_file_size,
std::function<genesis_state_type()> genesis_loader)
{
try
{
chainbase::database::open(data_dir, read_write, shared_file_size);
initialize_indexes();
initialize_evaluators();
_block_id_to_block.open(data_dir / "database" / "block_num_to_block");
if( !find<global_property_object>() )
init_genesis(genesis_loader());
fc::optional<signed_block> last_block = _block_id_to_block.last();
if( last_block.valid() )
{
_fork_db.start_block( *last_block );
idump((last_block->id())(last_block->block_num()));
idump((head_block_id())(head_block_num()));
if( last_block->id() != head_block_id() )
{
FC_ASSERT( head_block_num() == 0, "last block ID does not match current chain state",
("last_block->id", last_block->id())("head_block_num",head_block_num()) );
}
}
}
FC_CAPTURE_LOG_AND_RETHROW( (data_dir) )
}
void database::close()
{
// TODO: Save pending tx's on close()
clear_pending();
// 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();
chainbase::database::flush();
chainbase::database::close();
if( _block_id_to_block.is_open() )
_block_id_to_block.close();
_fork_db.reset();
}
} }
/*
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <eos/chain/database.hpp>
#include <eos/chain/global_property_object.hpp>
#include <eos/chain/producer_object.hpp>
namespace eos { namespace chain {
using boost::container::flat_set;
producer_id_type database::get_scheduled_producer(uint32_t slot_num)const
{
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
uint64_t current_aslot = dpo.current_aslot + slot_num;
const auto& gpo = get<global_property_object>();
return gpo.active_producers[ current_aslot % gpo.active_producers.size() ];
}
fc::time_point_sec database::get_slot_time(uint32_t slot_num)const
{
if( slot_num == 0 )
return fc::time_point_sec();
auto interval = block_interval();
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
if( head_block_num() == 0 )
{
// n.b. first block is at genesis_time plus one block interval
fc::time_point_sec genesis_time = dpo.time;
return genesis_time + slot_num * interval;
}
int64_t head_block_abs_slot = head_block_time().sec_since_epoch() / interval;
fc::time_point_sec head_slot_time(head_block_abs_slot * interval);
return head_slot_time + (slot_num * interval);
}
uint32_t database::get_slot_at_time(fc::time_point_sec when)const
{
fc::time_point_sec first_slot_time = get_slot_time( 1 );
if( when < first_slot_time )
return 0;
return (when - first_slot_time).to_seconds() / block_interval() + 1;
}
uint32_t database::producer_participation_rate()const
{
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
return uint64_t(EOS_100_PERCENT) * dpo.recent_slots_filled.popcount() / 128;
}
void database::update_producer_schedule()
{
}
} }
/*
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <eos/chain/database.hpp>
#include <eos/chain/db_with.hpp>
#include <eos/chain/global_property_object.hpp>
#include <eos/chain/transaction_object.hpp>
#include <eos/chain/producer_object.hpp>
#include <fc/uint128.hpp>
namespace eos { namespace chain {
void database::update_global_dynamic_data( const signed_block& b )
{
const dynamic_global_property_object& _dgp = get<dynamic_global_property_object>();
uint32_t missed_blocks = get_slot_at_time( b.timestamp );
assert( missed_blocks != 0 );
missed_blocks--;
for(uint32_t i = 0; i < missed_blocks; ++i) {
const auto& producer_missed = get(get_scheduled_producer(i+1));
if(producer_missed.id != b.producer) {
/*
const auto& producer_account = producer_missed.producer_account(*this);
if( (fc::time_point::now() - b.timestamp) < fc::seconds(30) )
wlog( "Producer ${name} missed block ${n} around ${t}", ("name",producer_account.name)("n",b.block_num())("t",b.timestamp) );
*/
modify( producer_missed, [&]( producer_object& w ) {
w.total_missed++;
});
}
}
// dynamic global properties updating
modify( _dgp, [&]( dynamic_global_property_object& dgp ){
if( BOOST_UNLIKELY( b.block_num() == 1 ) )
dgp.recently_missed_count = 0;
else if( _checkpoints.size() && _checkpoints.rbegin()->first >= b.block_num() )
dgp.recently_missed_count = 0;
else if( missed_blocks )
dgp.recently_missed_count += EOS_RECENTLY_MISSED_COUNT_INCREMENT*missed_blocks;
else if( dgp.recently_missed_count > EOS_RECENTLY_MISSED_COUNT_INCREMENT )
dgp.recently_missed_count -= EOS_RECENTLY_MISSED_COUNT_DECREMENT;
else if( dgp.recently_missed_count > 0 )
dgp.recently_missed_count--;
dgp.head_block_number = b.block_num();
dgp.head_block_id = b.id();
dgp.time = b.timestamp;
dgp.current_producer = b.producer;
dgp.recent_slots_filled = (
(dgp.recent_slots_filled << 1)
+ 1) << missed_blocks;
dgp.current_aslot += missed_blocks+1;
});
if( !(get_node_properties().skip_flags & skip_undo_history_check) )
{
EOS_ASSERT( _dgp.head_block_number - _dgp.last_irreversible_block_num < EOS_MAX_UNDO_HISTORY, undo_database_exception,
"The database does not have enough undo history to support a blockchain with so many missed blocks. "
"Please add a checkpoint if you would like to continue applying blocks beyond this point.",
("last_irreversible_block_num",_dgp.last_irreversible_block_num)("head", _dgp.head_block_number)
("recently_missed",_dgp.recently_missed_count)("max_undo",EOS_MAX_UNDO_HISTORY) );
}
_fork_db.set_max_size( _dgp.head_block_number - _dgp.last_irreversible_block_num + 1 );
}
void database::update_signing_producer(const producer_object& signing_producer, const signed_block& new_block)
{
const global_property_object& gpo = get_global_properties();
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
uint64_t new_block_aslot = dpo.current_aslot + get_slot_at_time( new_block.timestamp );
modify( signing_producer, [&]( producer_object& _wit )
{
_wit.last_aslot = new_block_aslot;
_wit.last_confirmed_block_num = new_block.block_num();
} );
}
void database::update_last_irreversible_block()
{
const global_property_object& gpo = get_global_properties();
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
vector< const producer_object* > wit_objs;
wit_objs.reserve( gpo.active_producers.size() );
for( const producer_id_type& wid : gpo.active_producers )
wit_objs.push_back( &(get(wid)) );
static_assert( EOS_IRREVERSIBLE_THRESHOLD > 0, "irreversible threshold must be nonzero" );
// 1 1 1 2 2 2 2 2 2 2 -> 2 .7*10 = 7
// 1 1 1 1 1 1 1 2 2 2 -> 1
// 3 3 3 3 3 3 3 3 3 3 -> 3
size_t offset = ((EOS_100_PERCENT - EOS_IRREVERSIBLE_THRESHOLD) * wit_objs.size() / EOS_100_PERCENT);
std::nth_element( wit_objs.begin(), wit_objs.begin() + offset, wit_objs.end(),
[]( const producer_object* a, const producer_object* b )
{
return a->last_confirmed_block_num < b->last_confirmed_block_num;
} );
uint32_t new_last_irreversible_block_num = wit_objs[offset]->last_confirmed_block_num;
if( new_last_irreversible_block_num > dpo.last_irreversible_block_num )
{
modify( dpo, [&]( dynamic_global_property_object& _dpo )
{
_dpo.last_irreversible_block_num = new_last_irreversible_block_num;
} );
}
}
void database::clear_expired_transactions()
{ try {
//Look for expired transactions in the deduplication list, and remove them.
//Transactions must have expired by at least two forking windows in order to be removed.
auto& transaction_idx = get_mutable_index<transaction_multi_index>();
const auto& dedupe_index = transaction_idx.indices().get<by_expiration>();
while( (!dedupe_index.empty()) && (head_block_time() > dedupe_index.rbegin()->trx.expiration) )
transaction_idx.remove(*dedupe_index.rbegin());
} FC_CAPTURE_AND_RETHROW() }
} }
......@@ -59,7 +59,7 @@ namespace eos { namespace chain {
enum validation_steps
{
skip_nothing = 0,
skip_producer_signature = 1 << 0, ///< used while reindexing
skip_producer_signature = 1 << 0, ///< used while reindexing
skip_transaction_signatures = 1 << 1, ///< used by non-producer nodes
skip_transaction_dupe_check = 1 << 2, ///< used while reindexing
skip_fork_db = 1 << 3, ///< used while reindexing
......@@ -69,7 +69,7 @@ namespace eos { namespace chain {
skip_merkle_check = 1 << 7, ///< used while reindexing
skip_assert_evaluation = 1 << 8, ///< used while reindexing
skip_undo_history_check = 1 << 9, ///< used while reindexing
skip_producer_schedule_check = 1 << 10, ///< used while reindexing
skip_producer_schedule_check= 1 << 10, ///< used while reindexing
skip_validate = 1 << 11 ///< used prior to checkpoint, skips validate() call on transaction
};
......@@ -126,7 +126,7 @@ namespace eos { namespace chain {
*/
uint32_t producer_participation_rate()const;
void add_checkpoints( const flat_map<uint32_t,block_id_type>& checkpts );
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;
......@@ -271,7 +271,7 @@ namespace eos { namespace chain {
signed_transaction apply_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );
void apply_operation( transaction_evaluation_state& eval_state, const operation& op );
private:
void _apply_block( const signed_block& next_block );
void _apply_block( const signed_block& next_block );
signed_transaction _apply_transaction( const signed_transaction& trx );
///Steps involved in applying a new block
......@@ -288,7 +288,7 @@ namespace eos { namespace chain {
void clear_expired_transactions();
vector< signed_transaction > _pending_tx;
fork_database _fork_db;
fork_database _fork_db;
/**
* Note: we can probably store blocks by block num rather than
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册