提交 b2166804 编写于 作者: A arhag

enforce loaded checkpoints #3337

上级 d3eb2935
......@@ -151,6 +151,9 @@ struct controller_impl {
} catch (boost::interprocess::bad_alloc& e) {
wlog( "bad alloc" );
throw e;
} catch ( controller_emit_signal_exception& e ) {
wlog( "${details}", ("details", e.to_detail_string()) );
throw e;
} catch ( fc::exception& e ) {
wlog( "${details}", ("details", e.to_detail_string()) );
} catch ( ... ) {
......@@ -871,6 +874,7 @@ struct controller_impl {
try {
FC_ASSERT( b );
FC_ASSERT( s != controller::block_status::incomplete, "invalid block status for a completed block" );
emit( self.pre_accepted_block, b );
bool trust = !conf.force_all_checks && (s == controller::block_status::irreversible || s == controller::block_status::validated);
auto new_header_state = fork_db.add( b, trust );
emit( self.accepted_block_header, new_header_state );
......
......@@ -190,6 +190,7 @@ namespace eosio { namespace chain {
db_read_mode get_read_mode()const;
signal<void(const signed_block_ptr&)> pre_accepted_block;
signal<void(const block_state_ptr&)> accepted_block_header;
signal<void(const block_state_ptr&)> accepted_block;
signal<void(const block_state_ptr&)> irreversible_block;
......
......@@ -287,17 +287,22 @@ namespace eosio { namespace chain {
FC_DECLARE_DERIVED_EXCEPTION( whitelist_blacklist_exception, chain_exception,
3130000, "actor or contract whitelist/blacklist exception" )
FC_DECLARE_DERIVED_EXCEPTION( actor_whitelist_exception, chain_exception,
FC_DECLARE_DERIVED_EXCEPTION( actor_whitelist_exception, whitelist_blacklist_exception,
3130001, "Authorizing actor of transaction is not on the whitelist" )
FC_DECLARE_DERIVED_EXCEPTION( actor_blacklist_exception, chain_exception,
FC_DECLARE_DERIVED_EXCEPTION( actor_blacklist_exception, whitelist_blacklist_exception,
3130002, "Authorizing actor of transaction is on the blacklist" )
FC_DECLARE_DERIVED_EXCEPTION( contract_whitelist_exception, chain_exception,
FC_DECLARE_DERIVED_EXCEPTION( contract_whitelist_exception, whitelist_blacklist_exception,
3130003, "Contract to execute is not on the whitelist" )
FC_DECLARE_DERIVED_EXCEPTION( contract_blacklist_exception, chain_exception,
FC_DECLARE_DERIVED_EXCEPTION( contract_blacklist_exception, whitelist_blacklist_exception,
3130004, "Contract to execute is on the blacklist" )
FC_DECLARE_DERIVED_EXCEPTION( action_blacklist_exception, chain_exception,
FC_DECLARE_DERIVED_EXCEPTION( action_blacklist_exception, whitelist_blacklist_exception,
3130005, "Action to execute is on the blacklist" )
FC_DECLARE_DERIVED_EXCEPTION( key_blacklist_exception, chain_exception,
FC_DECLARE_DERIVED_EXCEPTION( key_blacklist_exception, whitelist_blacklist_exception,
3130006, "Public key in authority is on the blacklist" )
FC_DECLARE_DERIVED_EXCEPTION( controller_emit_signal_exception, chain_exception,
3140000, "exceptions that are allowed to bubble out of emit calls in controller" )
FC_DECLARE_DERIVED_EXCEPTION( checkpoint_exception, controller_emit_signal_exception,
3140001, "Block does not match checkpoint" )
} } // eosio::chain
......@@ -20,8 +20,9 @@ namespace eosio { namespace chain { namespace plugin_interface {
using next_function = std::function<void(const fc::static_variant<fc::exception_ptr, T>&)>;
struct chain_plugin_interface;
namespace channels {
using pre_accepted_block = channel_decl<struct pre_accepted_block_tag, signed_block_ptr>;
using rejected_block = channel_decl<struct rejected_block_tag, signed_block_ptr>;
using accepted_block_header = channel_decl<struct accepted_block_header_tag, block_state_ptr>;
using accepted_block = channel_decl<struct accepted_block_tag, block_state_ptr>;
......
......@@ -100,7 +100,8 @@ using boost::signals2::scoped_connection;
class chain_plugin_impl {
public:
chain_plugin_impl()
:accepted_block_header_channel(app().get_channel<channels::accepted_block_header>())
:pre_accepted_block_channel(app().get_channel<channels::pre_accepted_block>())
,accepted_block_header_channel(app().get_channel<channels::accepted_block_header>())
,accepted_block_channel(app().get_channel<channels::accepted_block>())
,irreversible_block_channel(app().get_channel<channels::irreversible_block>())
,accepted_transaction_channel(app().get_channel<channels::accepted_transaction>())
......@@ -124,6 +125,7 @@ public:
fc::optional<vm_type> wasm_runtime;
// retained references to channels for easy publication
channels::pre_accepted_block::channel_type& pre_accepted_block_channel;
channels::accepted_block_header::channel_type& accepted_block_header_channel;
channels::accepted_block::channel_type& accepted_block_channel;
channels::irreversible_block::channel_type& irreversible_block_channel;
......@@ -143,6 +145,7 @@ public:
methods::get_last_irreversible_block_number::method_type::handle get_last_irreversible_block_number_provider;
// scoped connections for chain controller
fc::optional<scoped_connection> pre_accepted_block_connection;
fc::optional<scoped_connection> accepted_block_header_connection;
fc::optional<scoped_connection> accepted_block_connection;
fc::optional<scoped_connection> irreversible_block_connection;
......@@ -300,7 +303,15 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
for(auto cp : cps)
{
auto item = fc::json::from_string(cp).as<std::pair<uint32_t,block_id_type>>();
my->loaded_checkpoints[item.first] = item.second;
auto itr = my->loaded_checkpoints.find(item.first);
if( itr != my->loaded_checkpoints.end() ) {
FC_ASSERT( itr->second == item.second,
"redefining existing checkpoint at block number ${num}: original: ${orig} new: ${new}",
("num", item.first)("orig", itr->second)("new", item.second)
);
} else {
my->loaded_checkpoints[item.first] = item.second;
}
}
}
......@@ -461,6 +472,19 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
});
// relay signals to channels
my->pre_accepted_block_connection = my->chain->pre_accepted_block.connect([this](const signed_block_ptr& blk) {
auto itr = my->loaded_checkpoints.find( blk->block_num() );
if( itr != my->loaded_checkpoints.end() ) {
auto id = blk->id();
EOS_ASSERT( itr->second == id, checkpoint_exception,
"Checkpoint does not match for block number ${num}: expected: ${expected} actual: ${actual}",
("num", blk->block_num())("expected", itr->second)("actual", id)
);
}
my->pre_accepted_block_channel.publish(blk);
});
my->accepted_block_header_connection = my->chain->accepted_block_header.connect([this](const block_state_ptr& blk) {
my->accepted_block_header_channel.publish(blk);
});
......@@ -493,7 +517,6 @@ void chain_plugin::plugin_startup()
if(!my->readonly) {
ilog("starting chain in read/write mode");
/// TODO: my->chain->add_checkpoints(my->loaded_checkpoints);
}
ilog("Blockchain started; head block is #${num}, genesis timestamp is ${ts}",
......@@ -503,6 +526,7 @@ void chain_plugin::plugin_startup()
} FC_CAPTURE_AND_RETHROW() }
void chain_plugin::plugin_shutdown() {
my->pre_accepted_block_connection.reset();
my->accepted_block_header_connection.reset();
my->accepted_block_connection.reset();
my->irreversible_block_connection.reset();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册