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

Commit

Permalink
Merge pull request #5833 from EOSIO/disallow-mutable-db-access-to-plu…
Browse files Browse the repository at this point in the history
…gins

Allow only read-only access to state DB for consumers outside of the chain library
  • Loading branch information
arhag authored Sep 28, 2018
2 parents 2a1de3e + 4cdfbd1 commit c8d7ae5
Show file tree
Hide file tree
Showing 21 changed files with 105 additions and 75 deletions.
32 changes: 32 additions & 0 deletions contracts/eosio.bios/eosio.bios.abi
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@
{"name":"accounts", "type":"permission_level_weight[]"},
{"name":"waits", "type":"wait_weight[]"}
]
},{
"name": "blockchain_parameters",
"base": "",
"fields": [
{"name":"max_block_net_usage", "type":"uint64"},
{"name":"target_block_net_usage_pct", "type":"uint32"},
{"name":"max_transaction_net_usage", "type":"uint32"},
{"name":"base_per_transaction_net_usage", "type":"uint32"},
{"name":"net_usage_leeway", "type":"uint32"},
{"name":"context_free_discount_net_usage_num", "type":"uint32"},
{"name":"context_free_discount_net_usage_den", "type":"uint32"},
{"name":"max_block_cpu_usage", "type":"uint32"},
{"name":"target_block_cpu_usage_pct", "type":"uint32"},
{"name":"max_transaction_cpu_usage", "type":"uint32"},
{"name":"min_transaction_cpu_usage", "type":"uint32"},
{"name":"max_transaction_lifetime", "type":"uint32"},
{"name":"deferred_trx_expiration_window", "type":"uint32"},
{"name":"max_transaction_delay", "type":"uint32"},
{"name":"max_inline_action_size", "type":"uint32"},
{"name":"max_inline_action_depth", "type":"uint16"},
{"name":"max_authority_depth", "type":"uint16"}
]
},{
"name": "newaccount",
"base": "",
Expand Down Expand Up @@ -160,6 +182,12 @@
"fields": [
{"name":"schedule", "type":"producer_key[]"}
]
},{
"name": "setparams",
"base": "",
"fields": [
{"name":"params", "type":"blockchain_parameters"}
]
},{
"name": "require_auth",
"base": "",
Expand Down Expand Up @@ -219,6 +247,10 @@
"name": "setprods",
"type": "set_producers",
"ricardian_contract": ""
},{
"name": "setparams",
"type": "setparams",
"ricardian_contract": ""
},{
"name": "reqauth",
"type": "require_auth",
Expand Down
2 changes: 1 addition & 1 deletion contracts/eosio.bios/eosio.bios.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#include <eosio.bios/eosio.bios.hpp>

EOSIO_ABI( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(reqauth) )
EOSIO_ABI( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth) )
5 changes: 5 additions & 0 deletions contracts/eosio.bios/eosio.bios.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ namespace eosio {
set_proposed_producers(buffer, size);
}

void setparams( const eosio::blockchain_parameters& params ) {
require_auth( _self );
set_blockchain_parameters( params );
}

void reqauth( action_name from ) {
require_auth( from );
}
Expand Down
7 changes: 3 additions & 4 deletions libraries/chain/apply_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,7 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
}

uint32_t trx_size = 0;
auto& d = control.db();
if ( auto ptr = d.find<generated_transaction_object,by_sender_id>(boost::make_tuple(receiver, sender_id)) ) {
if ( auto ptr = db.find<generated_transaction_object,by_sender_id>(boost::make_tuple(receiver, sender_id)) ) {
EOS_ASSERT( replace_existing, deferred_tx_duplicate, "deferred transaction with the same sender_id and payer already exists" );

// TODO: Remove the following subjective check when the deferred trx replacement RAM bug has been fixed with a hard fork.
Expand All @@ -283,7 +282,7 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
// TODO: The logic of the next line needs to be incorporated into the next hard fork.
// add_ram_usage( ptr->payer, -(config::billable_size_v<generated_transaction_object> + ptr->packed_trx.size()) );

d.modify<generated_transaction_object>( *ptr, [&]( auto& gtx ) {
db.modify<generated_transaction_object>( *ptr, [&]( auto& gtx ) {
gtx.sender = receiver;
gtx.sender_id = sender_id;
gtx.payer = payer;
Expand All @@ -294,7 +293,7 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
trx_size = gtx.set( trx );
});
} else {
d.create<generated_transaction_object>( [&]( auto& gtx ) {
db.create<generated_transaction_object>( [&]( auto& gtx ) {
gtx.trx_id = trx.id();
gtx.sender = receiver;
gtx.sender_id = sender_id;
Expand Down
20 changes: 11 additions & 9 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,10 @@ struct controller_impl {
std::cerr<< "\n";
ilog( "${n} blocks replayed", ("n", head->block_num) );

// the irreverible log is played without undo sessions enabled, so we need to sync the
// if the irreverible log is played without undo sessions enabled, we need to sync the
// revision ordinal to the appropriate expected value here.
db.set_revision(head->block_num);
if( self.skip_db_sessions( controller::block_status::irreversible ) )
db.set_revision(head->block_num);

int rev = 0;
while( auto obj = reversible_blocks.find<reversible_block_object,by_num>(head->block_num+1) ) {
Expand Down Expand Up @@ -1051,7 +1052,7 @@ struct controller_impl {
// on replay irreversible is not emitted by fork database, so emit it explicitly here
if( s == controller::block_status::irreversible )
emit( self.irreversible_block, new_header_state );

} FC_LOG_AND_RETHROW( )
}

Expand Down Expand Up @@ -1387,22 +1388,23 @@ controller::~controller() {
my->fork_db.close();
}


void controller::startup() {

// ilog( "${c}", ("c",fc::json::to_pretty_string(cfg)) );
void controller::add_indices() {
my->add_indices();
}

void controller::startup() {
my->head = my->fork_db.head();
if( !my->head ) {
elog( "No head block in fork db, perhaps we need to replay" );
}
my->init();
}

chainbase::database& controller::db()const { return my->db; }
const chainbase::database& controller::db()const { return my->db; }

chainbase::database& controller::mutable_db()const { return my->db; }

fork_database& controller::fork_db()const { return my->fork_db; }
const fork_database& controller::fork_db()const { return my->fork_db; }


void controller::start_block( block_timestamp_type when, uint16_t confirm_block_count) {
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/include/eosio/chain/apply_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ class apply_context {
public:
apply_context(controller& con, transaction_context& trx_ctx, const action& a, uint32_t depth=0)
:control(con)
,db(con.db())
,db(con.mutable_db())
,trx_context(trx_ctx)
,act(a)
,receiver(act.account)
Expand Down
9 changes: 7 additions & 2 deletions libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ namespace eosio { namespace chain {
controller( const config& cfg );
~controller();

void add_indices();
void startup();

/**
Expand Down Expand Up @@ -145,9 +146,9 @@ namespace eosio { namespace chain {
*/
void push_confirmation( const header_confirmation& c );

chainbase::database& db()const;
const chainbase::database& db()const;

fork_database& fork_db()const;
const fork_database& fork_db()const;

const account_object& get_account( account_name n )const;
const global_property_object& get_global_properties()const;
Expand Down Expand Up @@ -285,6 +286,10 @@ namespace eosio { namespace chain {
}

private:
friend class apply_context;
friend class transaction_context;

chainbase::database& mutable_db()const;

std::unique_ptr<controller_impl> my;

Expand Down
6 changes: 3 additions & 3 deletions libraries/chain/transaction_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace eosio { namespace chain {
,pseudo_start(s)
{
if (!c.skip_db_sessions()) {
undo_session = c.db().start_undo_session(true);
undo_session = c.mutable_db().start_undo_session(true);
}
trace->id = id;
trace->block_num = c.pending_block_state()->block_num;
Expand Down Expand Up @@ -451,7 +451,7 @@ namespace eosio { namespace chain {
auto first_auth = trx.first_authorizor();

uint32_t trx_size = 0;
const auto& cgto = control.db().create<generated_transaction_object>( [&]( auto& gto ) {
const auto& cgto = control.mutable_db().create<generated_transaction_object>( [&]( auto& gto ) {
gto.trx_id = id;
gto.payer = first_auth;
gto.sender = account_name(); /// delayed transactions have no sender
Expand All @@ -467,7 +467,7 @@ namespace eosio { namespace chain {

void transaction_context::record_transaction( const transaction_id_type& id, fc::time_point_sec expire ) {
try {
control.db().create<transaction_object>([&](transaction_object& transaction) {
control.mutable_db().create<transaction_object>([&](transaction_object& transaction) {
transaction.trx_id = id;
transaction.expiration = expire;
});
Expand Down
2 changes: 1 addition & 1 deletion libraries/chainbase
3 changes: 3 additions & 0 deletions libraries/testing/include/eosio/testing/tester.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ namespace eosio { namespace testing {
vcfg.trusted_producers = trusted_producers;

validating_node = std::make_unique<controller>(vcfg);
validating_node->add_indices();
validating_node->startup();

init(true);
Expand All @@ -360,6 +361,7 @@ namespace eosio { namespace testing {
vcfg.state_dir = vcfg.state_dir.parent_path() / std::string("v_").append( vcfg.state_dir.filename().generic_string() );

validating_node = std::make_unique<controller>(vcfg);
validating_node->add_indices();
validating_node->startup();

init(config);
Expand Down Expand Up @@ -404,6 +406,7 @@ namespace eosio { namespace testing {

validating_node.reset();
validating_node = std::make_unique<controller>(vcfg);
validating_node->add_indices();
validating_node->startup();

return ok;
Expand Down
7 changes: 4 additions & 3 deletions libraries/testing/tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace eosio { namespace testing {
std::ifstream wast_file(fn);
FC_ASSERT( wast_file.is_open(), "wast file cannot be found" );
wast_file.seekg(0, std::ios::end);
std::vector<char> wast;
std::vector<char> wast;
int len = wast_file.tellg();
FC_ASSERT( len >= 0, "wast file length is -1" );
wast.resize(len+1);
Expand All @@ -32,7 +32,7 @@ namespace eosio { namespace testing {
std::ifstream wasm_file(fn, std::ios::binary);
FC_ASSERT( wasm_file.is_open(), "wasm file cannot be found" );
wasm_file.seekg(0, std::ios::end);
std::vector<uint8_t> wasm;
std::vector<uint8_t> wasm;
int len = wasm_file.tellg();
FC_ASSERT( len >= 0, "wasm file length is -1" );
wasm.resize(len);
Expand All @@ -46,7 +46,7 @@ namespace eosio { namespace testing {
std::ifstream abi_file(fn);
FC_ASSERT( abi_file.is_open(), "abi file cannot be found" );
abi_file.seekg(0, std::ios::end);
std::vector<char> abi;
std::vector<char> abi;
int len = abi_file.tellg();
FC_ASSERT( len >= 0, "abi file length is -1" );
abi.resize(len+1);
Expand Down Expand Up @@ -123,6 +123,7 @@ namespace eosio { namespace testing {

void base_tester::open() {
control.reset( new controller(cfg) );
control->add_indices();
control->startup();
chain_transactions.clear();
control->accepted_block.connect([this]( const block_state_ptr& block_state ){
Expand Down
7 changes: 2 additions & 5 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,8 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
[this]( const header_confirmation& conf ) {
my->accepted_confirmation_channel.publish( conf );
} );

my->chain->add_indices();
} FC_LOG_AND_RETHROW()

}
Expand Down Expand Up @@ -906,11 +908,6 @@ bool chain_plugin::export_reversible_blocks( const fc::path& reversible_dir,
return (end >= start) && ((end - start + 1) == num);
}

controller::config& chain_plugin::chain_config() {
// will trigger optional assert if called before/after plugin_initialize()
return *my->chain_config;
}

controller& chain_plugin::chain() { return *my->chain; }
const controller& chain_plugin::chain() const { return *my->chain; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -642,11 +642,9 @@ class chain_plugin : public plugin<chain_plugin> {
const fc::path& reversible_blocks_file
);

// Only call this in plugin_initialize() to modify controller constructor configuration
controller::config& chain_config();
// Only call this after plugin_startup()!
// Only call this after plugin_initialize()!
controller& chain();
// Only call this after plugin_startup()!
// Only call this after plugin_initialize()!
const controller& chain() const;

chain::chain_id_type get_chain_id() const;
Expand Down
2 changes: 1 addition & 1 deletion plugins/db_size_api_plugin/db_size_api_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void db_size_api_plugin::plugin_startup() {
}

db_size_stats db_size_api_plugin::get() {
chainbase::database& db = app().get_plugin<chain_plugin>().chain().db();
const chainbase::database& db = app().get_plugin<chain_plugin>().chain().db();
db_size_stats ret;

ret.free_bytes = db.get_segment_manager()->get_free_memory();
Expand Down
16 changes: 9 additions & 7 deletions plugins/history_plugin/history_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ namespace eosio {

void record_account_action( account_name n, const base_action_trace& act ) {
auto& chain = chain_plug->chain();
auto& db = chain.db();
chainbase::database& db = const_cast<chainbase::database&>( chain.db() ); // Override read-only access to state DB (highly unrecommended practice!)

const auto& idx = db.get_index<account_history_index, by_account_action_seq>();
auto itr = idx.lower_bound( boost::make_tuple( name(n.value+1), 0 ) );
Expand All @@ -227,7 +227,7 @@ namespace eosio {

void on_system_action( const action_trace& at ) {
auto& chain = chain_plug->chain();
auto& db = chain.db();
chainbase::database& db = const_cast<chainbase::database&>( chain.db() ); // Override read-only access to state DB (highly unrecommended practice!)
if( at.act.name == N(newaccount) )
{
const auto create = at.act.data_as<chain::newaccount>();
Expand Down Expand Up @@ -256,7 +256,7 @@ namespace eosio {
if( filter( at ) ) {
//idump((fc::json::to_pretty_string(at)));
auto& chain = chain_plug->chain();
auto& db = chain.db();
chainbase::database& db = const_cast<chainbase::database&>( chain.db() ); // Override read-only access to state DB (highly unrecommended practice!)

db.create<action_history_object>( [&]( auto& aho ) {
auto ps = fc::raw::pack_size( at );
Expand Down Expand Up @@ -344,10 +344,12 @@ namespace eosio {
EOS_ASSERT( my->chain_plug, chain::missing_chain_plugin_exception, "" );
auto& chain = my->chain_plug->chain();

chain.db().add_index<account_history_index>();
chain.db().add_index<action_history_index>();
chain.db().add_index<account_control_history_multi_index>();
chain.db().add_index<public_key_history_multi_index>();
chainbase::database& db = const_cast<chainbase::database&>( chain.db() ); // Override read-only access to state DB (highly unrecommended practice!)
// TODO: Use separate chainbase database for managing the state of the history_plugin (or remove deprecated history_plugin entirely)
db.add_index<account_history_index>();
db.add_index<action_history_index>();
db.add_index<account_control_history_multi_index>();
db.add_index<public_key_history_multi_index>();

my->applied_transaction_connection.emplace(
chain.applied_transaction.connect( [&]( const transaction_trace_ptr& p ) {
Expand Down
Loading

0 comments on commit c8d7ae5

Please sign in to comment.