Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
add light validation mode
Browse files Browse the repository at this point in the history
This mode enables skipping of auth checks, transaction signature recovery and other tests that can be inferred as passed if the node implicitly trusts the active set of producers to maintain correctness
  • Loading branch information
b1bart committed Aug 9, 2018
1 parent 2b6419b commit 8942727
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 4 deletions.
29 changes: 26 additions & 3 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1652,15 +1652,34 @@ optional<producer_schedule_type> controller::proposed_producers()const {
}

bool controller::skip_auth_check() const {
return my->replaying && !my->conf.force_all_checks && !my->in_trx_requiring_checks;
// replaying
bool consider_skipping = my->replaying;

// OR in light validation mode
consider_skipping = consider_skipping || my->conf.validation_mode == validation_mode::LIGHT;

return consider_skipping
&& !my->conf.force_all_checks
&& !my->in_trx_requiring_checks;
}

bool controller::skip_db_sessions() const {
return !my->conf.disable_replay_opts && my->pending && !my->in_trx_requiring_checks && my->pending->_block_status == block_status::irreversible;
bool consider_skipping = my->pending && my->pending->_block_status == block_status::irreversible;
return consider_skipping
&& !my->conf.disable_replay_opts
&& !my->in_trx_requiring_checks;
}

bool controller::skip_trx_checks() const {
return !my->conf.disable_replay_opts && my->pending && !my->in_trx_requiring_checks && (my->pending->_block_status == block_status::irreversible || my->pending->_block_status == block_status::validated);
// in a pending irreversible or previously validated block
bool consider_skipping = my->pending && ( my->pending->_block_status == block_status::irreversible || my->pending->_block_status == block_status::validated );

// OR in light validation mode
consider_skipping = consider_skipping || my->conf.validation_mode == validation_mode::LIGHT;

return consider_skipping
&& !my->conf.disable_replay_opts
&& !my->in_trx_requiring_checks;
}

bool controller::contracts_console()const {
Expand All @@ -1675,6 +1694,10 @@ db_read_mode controller::get_read_mode()const {
return my->read_mode;
}

validation_mode controller::get_validation_mode()const {
return my->conf.validation_mode;
}

const apply_handler* controller::find_apply_handler( account_name receiver, account_name scope, action_name act ) const
{
auto native_handler_scope = my->apply_handlers.find( receiver );
Expand Down
9 changes: 8 additions & 1 deletion libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ namespace eosio { namespace chain {
IRREVERSIBLE
};

enum class validation_mode {
FULL,
LIGHT
};

class controller {
public:

Expand All @@ -63,7 +68,8 @@ namespace eosio { namespace chain {
genesis_state genesis;
wasm_interface::vm_type wasm_runtime = chain::config::default_wasm_runtime;

db_read_mode read_mode = db_read_mode::SPECULATIVE;
db_read_mode read_mode = db_read_mode::SPECULATIVE;
validation_mode validation_mode = validation_mode::FULL;

flat_set<account_name> resource_greylist;
};
Expand Down Expand Up @@ -221,6 +227,7 @@ namespace eosio { namespace chain {
chain_id_type get_chain_id()const;

db_read_mode get_read_mode()const;
validation_mode get_validation_mode()const;

void set_subjective_cpu_leeway(fc::microseconds leeway);

Expand Down
41 changes: 41 additions & 0 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,39 @@ void validate(boost::any& v,
}
}

std::ostream& operator<<(std::ostream& osm, eosio::chain::validation_mode m) {
if ( m == eosio::chain::validation_mode::FULL ) {
osm << "full";
} else if ( m == eosio::chain::validation_mode::LIGHT ) {
osm << "light";
}

return osm;
}

void validate(boost::any& v,
std::vector<std::string> const& values,
eosio::chain::validation_mode* /* target_type */,
int)
{
using namespace boost::program_options;

// Make sure no previous assignment to 'v' was made.
validators::check_first_occurrence(v);

// Extract the first string from 'values'. If there is more than
// one string, it's an error, and exception will be thrown.
std::string const& s = validators::get_single_string(values);

if ( s == "full" ) {
v = boost::any(eosio::chain::validation_mode::FULL);
} else if ( s == "light" ) {
v = boost::any(eosio::chain::validation_mode::LIGHT);
} else {
throw validation_error(validation_error::invalid_option_value);
}
}

}

using namespace eosio;
Expand Down Expand Up @@ -202,6 +235,10 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip
"In \"speculative\" mode database contains changes done up to the head block plus changes made by transactions not yet included to the blockchain.\n"
"In \"head\" mode database contains changes done up to the current head block.\n")
//"In \"irreversible\" mode database contains changes done up the current irreversible block.\n")
("validation-mode", boost::program_options::value<eosio::chain::validation_mode>()->default_value(eosio::chain::validation_mode::FULL),
"Chain validation mode (\"full\" or \"light\").\n"
"In \"full\" mode all incoming blocks will be fully validated.\n"
"In \"light\" mode all incoming blocks headers will be fully validated; transactions in those validated blocks will be trusted \n")
;

// TODO: rate limiting
Expand Down Expand Up @@ -516,6 +553,10 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
EOS_ASSERT( my->chain_config->read_mode != db_read_mode::IRREVERSIBLE, plugin_config_exception, "irreversible mode not currently supported." );
}

if ( options.count("validation-mode") ) {
my->chain_config->validation_mode = options.at("validation-mode").as<validation_mode>();
}

my->chain.emplace( *my->chain_config );
my->chain_id.emplace( my->chain->get_chain_id());

Expand Down
4 changes: 4 additions & 0 deletions plugins/producer_plugin/producer_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,10 @@ void producer_plugin::plugin_startup()
EOS_ASSERT( my->_producers.empty() || chain.get_read_mode() == chain::db_read_mode::SPECULATIVE, plugin_config_exception,
"node cannot have any producer-name configured because block production is impossible when read_mode is not \"speculative\"" );

EOS_ASSERT( my->_producers.empty() || chain.get_validation_mode() == chain::validation_mode::FULL, plugin_config_exception,
"node cannot have any producer-name configured because block production is not safe when validation_mode is not \"full\"" );


my->_accepted_block_connection.emplace(chain.accepted_block.connect( [this]( const auto& bsp ){ my->on_block( bsp ); } ));
my->_irreversible_block_connection.emplace(chain.irreversible_block.connect( [this]( const auto& bsp ){ my->on_irreversible_block( bsp->block ); } ));

Expand Down

0 comments on commit 8942727

Please sign in to comment.