提交 b2c417bf 编写于 作者: D Daniel Larimer

Fix eosio.system abi & skip sig checks

- signature checks are skipped while replaying
- abi of eosio.system contract was inconsistant, Fix #2999
- reduced console spam while syncing and replaying
- add max usage of resources when querying account
上级 556d7d62
......@@ -54,9 +54,8 @@
"fields": [
{"name":"from", "type":"account_name"},
{"name":"to", "type":"account_name"},
{"name":"net_weight", "type":"uint64"},
{"name":"cpu_weight", "type":"uint64"},
{"name":"ram_bytes", "type":"uint64"}
{"name":"net_weight", "type":"asset"},
{"name":"cpu_weight", "type":"asset"},
]
},{
"name": "user_resources",
......
......@@ -81,8 +81,8 @@ EOSIO_ABI( eosiosystem::system_contract,
(delegatebw)(undelegatebw)(refund)
(buyram)(buyrambytes)(sellram)
// voting.cpp
(regproxy)(regproducer)(unregprod)(voteproducer)
// producer_pay.cpp
(regproxy)(regproducer)(unregprod)(voteproducer)
(claimrewards)
// native.hpp
//XXX
......
......@@ -4,60 +4,17 @@
namespace eosio { namespace chain {
/*
uint32_t block_header_state::calc_dpos_last_irreversible()const {
if( producer_to_last_produced.size() == 0 )
return 0;
vector<uint32_t> irb;
irb.reserve( producer_to_last_produced.size() );
for( const auto& item : producer_to_last_produced )
irb.push_back(item.second);
size_t offset = EOS_PERCENT(irb.size(), config::percent_100- config::irreversible_threshold_percent);
std::nth_element( irb.begin(), irb.begin() + offset, irb.end() );
return irb[offset];
}
*/
bool block_header_state::is_active_producer( account_name n )const {
return producer_to_last_produced.find(n) != producer_to_last_produced.end();
}
/*
block_timestamp_type block_header_state::get_slot_time( uint32_t slot_num )const {
auto t = header.timestamp;
FC_ASSERT( std::numeric_limits<decltype(t.slot)>::max() - t.slot >= slot_num, "block timestamp overflow" );
t.slot += slot_num;
return t;
}
uint32_t block_header_state::get_slot_at_time( block_timestamp_type t )const {
auto first_slot_time = get_slot_time(1);
if( t < first_slot_time )
return 0;
return (t.slot - first_slot_time.slot + 1);
}
producer_key block_header_state::get_scheduled_producer( uint32_t slot_num )const {
return get_scheduled_producer( get_slot_time(slot_num) );
}
*/
producer_key block_header_state::get_scheduled_producer( block_timestamp_type t )const {
auto index = t.slot % (active_schedule.producers.size() * config::producer_repetitions);
index /= config::producer_repetitions;
return active_schedule.producers[index];
}
/*
uint32_t block_header_state::producer_participation_rate()const
{
return static_cast<uint32_t>(config::percent_100); // Ignore participation rate for now until we construct a better metric.
}
*/
/**
* Generate a template block header state for a given block time, it will not
......@@ -153,7 +110,7 @@ namespace eosio { namespace chain {
*
* If the header specifies new_producers then apply them accordingly.
*/
block_header_state block_header_state::next( const signed_block_header& h )const {
block_header_state block_header_state::next( const signed_block_header& h, bool trust )const {
FC_ASSERT( h.timestamp != block_timestamp_type(), "", ("h",h) );
FC_ASSERT( h.header_extensions.size() == 0, "no supported extensions" );
......@@ -178,16 +135,16 @@ namespace eosio { namespace chain {
result.set_confirmed( h.confirmed );
// idump( (result.confirm_count.size()) );
result.header.action_mroot = h.action_mroot;
result.header.transaction_mroot = h.transaction_mroot;
result.header.producer_signature = h.producer_signature;
//idump((result.header));
result.id = result.header.id();
FC_ASSERT( result.block_signing_key == result.signee(), "block not signed by expected key",
("result.block_signing_key", result.block_signing_key)("signee", result.signee() ) );
if( !trust ) {
FC_ASSERT( result.block_signing_key == result.signee(), "block not signed by expected key",
("result.block_signing_key", result.block_signing_key)("signee", result.signee() ) );
}
return result;
} /// next
......@@ -232,10 +189,12 @@ namespace eosio { namespace chain {
return digest_type::hash( std::make_pair(header_bmroot, pending_schedule_hash) );
}
void block_header_state::sign( const std::function<signature_type(const digest_type&)>& signer ) {
void block_header_state::sign( const std::function<signature_type(const digest_type&)>& signer, bool trust ) {
auto d = sig_digest();
header.producer_signature = signer( d );
FC_ASSERT( block_signing_key == fc::crypto::public_key( header.producer_signature, d ) );
if( !trust ) {
FC_ASSERT( block_signing_key == fc::crypto::public_key( header.producer_signature, d ) );
}
}
public_key_type block_header_state::signee()const {
......
......@@ -10,8 +10,8 @@ namespace eosio { namespace chain {
static_cast<block_header&>(*block) = header;
}
block_state::block_state( const block_header_state& prev, signed_block_ptr b )
:block_header_state( prev.next( *b )), block( move(b) )
block_state::block_state( const block_header_state& prev, signed_block_ptr b, bool trust )
:block_header_state( prev.next( *b, trust )), block( move(b) )
{ }
......
......@@ -260,14 +260,14 @@ struct controller_impl {
auto start = fc::time_point::now();
while( auto next = blog.read_block_by_num( head->block_num + 1 ) ) {
self.push_block( next );
if( next->block_num() % 10 == 0 ) {
self.push_block( next, true );
if( next->block_num() % 100 == 0 ) {
std::cerr << std::setw(10) << next->block_num() << " of " << end->block_num() <<"\r";
}
}
std::cerr<< "\n";
auto end = fc::time_point::now();
ilog( "replayed blocks in ${n} seconds", ("n", (end-start).count()/1000000.0) );
ilog( "replayed blocks in ${n} seconds, ${spb} spb", ("n", (end-start).count()/1000000.0)("spb", ((end-start).count()/1000000.0)/head->block_num) );
replaying = false;
} else if( !end ) {
......@@ -700,18 +700,20 @@ struct controller_impl {
void sign_block( const std::function<signature_type( const digest_type& )>& signer_callback ) {
void sign_block( const std::function<signature_type( const digest_type& )>& signer_callback, bool trust ) {
auto p = pending->_pending_block_state;
try {
p->sign( signer_callback );
p->sign( signer_callback, false); //trust );
} catch ( ... ) {
edump(( fc::json::to_pretty_string( *p->block ) ) );
edump(( fc::json::to_pretty_string( p->header ) ) );
throw;
}
static_cast<signed_block_header&>(*p->block) = p->header;
} /// sign_block
void apply_block( const signed_block_ptr& b ) { try {
void apply_block( const signed_block_ptr& b, bool trust ) { try {
try {
FC_ASSERT( b->block_extensions.size() == 0, "no supported extensions" );
start_block( b->timestamp, b->confirmed );
......@@ -728,7 +730,7 @@ struct controller_impl {
}
finalize_block();
sign_block( [&]( const auto& ){ return b->producer_signature; } );
sign_block( [&]( const auto& ){ return b->producer_signature; }, trust );
// this is implied by the signature passing
//FC_ASSERT( b->id() == pending->_pending_block_state->block->id(),
......@@ -744,14 +746,14 @@ struct controller_impl {
} FC_CAPTURE_AND_RETHROW() } /// apply_block
void push_block( const signed_block_ptr& b ) {
void push_block( const signed_block_ptr& b, bool trust ) {
// idump((fc::json::to_pretty_string(*b)));
FC_ASSERT(!pending, "it is not valid to push a block when there is a pending block");
try {
FC_ASSERT( b );
auto new_header_state = fork_db.add( b );
auto new_header_state = fork_db.add( b, trust );
emit( self.accepted_block_header, new_header_state );
maybe_switch_forks();
maybe_switch_forks( trust );
} FC_LOG_AND_RETHROW( )
}
......@@ -762,12 +764,12 @@ struct controller_impl {
maybe_switch_forks();
}
void maybe_switch_forks() {
void maybe_switch_forks( bool trust = false ) {
auto new_head = fork_db.head();
if( new_head->header.previous == head->id ) {
try {
apply_block( new_head->block );
apply_block( new_head->block, trust );
fork_db.mark_in_current_chain( new_head, true );
fork_db.set_validity( new_head, true );
head = new_head;
......@@ -790,7 +792,7 @@ struct controller_impl {
for( auto ritr = branches.first.rbegin(); ritr != branches.first.rend(); ++ritr) {
optional<fc::exception> except;
try {
apply_block( (*ritr)->block );
apply_block( (*ritr)->block, false /*don't trust*/ );
head = *ritr;
fork_db.mark_in_current_chain( *ritr, true );
}
......@@ -813,7 +815,7 @@ struct controller_impl {
// re-apply good blocks
for( auto ritr = branches.second.rbegin(); ritr != branches.second.rend(); ++ritr ) {
apply_block( (*ritr)->block );
apply_block( (*ritr)->block, true /* we previously validated these blocks*/ );
head = *ritr;
fork_db.mark_in_current_chain( *ritr, true );
}
......@@ -1046,7 +1048,7 @@ void controller::finalize_block() {
}
void controller::sign_block( const std::function<signature_type( const digest_type& )>& signer_callback ) {
my->sign_block( signer_callback );
my->sign_block( signer_callback, false /* don't trust */);
}
void controller::commit_block() {
......@@ -1057,8 +1059,8 @@ void controller::abort_block() {
my->abort_block();
}
void controller::push_block( const signed_block_ptr& b ) {
my->push_block( b );
void controller::push_block( const signed_block_ptr& b, bool trust ) {
my->push_block( b, trust );
log_irreversible_blocks();
}
......
......@@ -121,7 +121,6 @@ void apply_eosio_newaccount(apply_context& context) {
void apply_eosio_setcode(apply_context& context) {
const auto& cfg = context.control.get_global_properties().configuration;
context.checktime( cfg.base_setcode_cpu_usage );
auto& db = context.db;
auto act = context.act.data_as<setcode>();
......@@ -131,7 +130,6 @@ void apply_eosio_setcode(apply_context& context) {
FC_ASSERT( act.vmtype == 0 );
FC_ASSERT( act.vmversion == 0 );
context.checktime( act.code.size() * 20 );
auto code_id = fc::sha256::hash( act.code.data(), (uint32_t)act.code.size() );
......@@ -180,7 +178,6 @@ void apply_eosio_setabi(apply_context& context) {
int64_t old_size = (int64_t)account.abi.size();
int64_t new_size = (int64_t)fc::raw::pack_size(act.abi);
context.checktime( new_size * 2 );
db.modify( account, [&]( auto& a ) {
a.set_abi( act.abi );
......@@ -223,7 +220,6 @@ void apply_eosio_updateauth(apply_context& context) {
validate_authority_precondition(context, update.auth);
context.checktime( 5000 );
auto permission = authorization.find_permission({update.account, update.permission});
......@@ -284,7 +280,6 @@ void apply_eosio_deleteauth(apply_context& context) {
context.trx_context.add_ram_usage( remove.account, -old_size );
context.checktime( 3000 );
}
void apply_eosio_linkauth(apply_context& context) {
......@@ -332,7 +327,6 @@ void apply_eosio_linkauth(apply_context& context) {
);
}
context.checktime( 3000 );
} FC_CAPTURE_AND_RETHROW((requirement))
}
......@@ -353,7 +347,6 @@ void apply_eosio_unlinkauth(apply_context& context) {
);
db.remove(*link);
context.checktime( 3000 );
}
static const abi_serializer& get_abi_serializer() {
......@@ -373,8 +366,6 @@ void apply_eosio_canceldelay(apply_context& context) {
const auto& trx_id = cancel.trx_id;
context.cancel_deferred_transaction(transaction_id_to_sender_id(trx_id), account_name());
context.checktime( 1000 );
}
} } // namespace eosio::chain
......@@ -141,7 +141,7 @@ namespace eosio { namespace chain {
return n;
}
block_state_ptr fork_database::add( signed_block_ptr b ) {
block_state_ptr fork_database::add( signed_block_ptr b, bool trust ) {
FC_ASSERT( b, "attempt to add null block" );
FC_ASSERT( my->head, "no head block set" );
......@@ -152,7 +152,7 @@ namespace eosio { namespace chain {
auto prior = by_id_idx.find( b->previous );
FC_ASSERT( prior != by_id_idx.end(), "unlinkable block", ("id", b->id())("previous", b->previous) );
auto result = std::make_shared<block_state>( **prior, move(b) );
auto result = std::make_shared<block_state>( **prior, move(b), trust );
FC_ASSERT( result );
return add(result);
}
......
......@@ -24,7 +24,7 @@ struct block_header_state {
vector<uint8_t> confirm_count;
vector<header_confirmation> confirmations;
block_header_state next( const signed_block_header& h )const;
block_header_state next( const signed_block_header& h, bool trust = false )const;
block_header_state generate_next( block_timestamp_type when )const;
void set_new_producers( producer_schedule_type next_pending );
......@@ -46,7 +46,7 @@ struct block_header_state {
producer_key get_scheduled_producer( block_timestamp_type t )const;
const block_id_type& prev()const { return header.previous; }
digest_type sig_digest()const;
void sign( const std::function<signature_type(const digest_type&)>& signer );
void sign( const std::function<signature_type(const digest_type&)>& signer, bool trust = false );
public_key_type signee()const;
};
......
......@@ -13,7 +13,7 @@ namespace eosio { namespace chain {
struct block_state : public block_header_state {
block_state( const block_header_state& cur ):block_header_state(cur){}
block_state( const block_header_state& prev, signed_block_ptr b );
block_state( const block_header_state& prev, signed_block_ptr b, bool trust = false );
block_state( const block_header_state& prev, block_timestamp_type when );
block_state() = default;
......
......@@ -99,7 +99,7 @@ namespace eosio { namespace chain {
void log_irreversible_blocks();
void pop_block();
void push_block( const signed_block_ptr& b );
void push_block( const signed_block_ptr& b, bool trust = false /* does the caller trust the block*/ );
/**
* Call this method when a producer confirmation is received, this might update
......
......@@ -40,7 +40,7 @@ namespace eosio { namespace chain {
* block_state and will return a pointer to the new block state or
* throw on error.
*/
block_state_ptr add( signed_block_ptr b );
block_state_ptr add( signed_block_ptr b, bool trust = false );
block_state_ptr add( block_state_ptr next_block );
void remove( const block_id_type& id );
......
......@@ -29,7 +29,7 @@ namespace eosio { namespace chain { namespace resource_limits {
struct account_resource_limit {
int64_t used = 0; ///< quantity used in current window
int64_t available = 0; ///< quantity available in current window (based upon fractional reserve)
int64_t max_gauranteed = 0; ///< max per window under 100% congestion
int64_t max = 0; ///< max per window under current congestion
};
class resource_limits_manager {
......@@ -76,4 +76,4 @@ namespace eosio { namespace chain { namespace resource_limits {
};
} } } /// eosio::chain
FC_REFLECT( eosio::chain::resource_limits::account_resource_limit, (used)(available)(max_gauranteed) )
FC_REFLECT( eosio::chain::resource_limits::account_resource_limit, (used)(available)(max) )
......@@ -401,7 +401,9 @@ account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const
uint128_t user_weight = cpu_weight;
uint128_t all_user_weight = state.total_cpu_weight;
auto max_user_use_in_window = (virtual_cpu_capacity_in_window * user_weight) / all_user_weight;
wdump((cpu_weight));
auto max_user_use_in_window = (uint128_t(virtual_cpu_capacity_in_window) * user_weight) / all_user_weight;
auto cpu_used_in_window = (usage.cpu_usage.value_ex * window_size) / config::rate_limiting_precision;
if( max_user_use_in_window <= cpu_used_in_window )
......@@ -410,6 +412,7 @@ account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const
arl.available = max_user_use_in_window - cpu_used_in_window;
arl.used = cpu_used_in_window;
arl.max = max_user_use_in_window;
return arl;
}
......@@ -471,6 +474,7 @@ account_resource_limit resource_limits_manager::get_account_net_limit_ex( const
arl.available = max_user_use_in_window - net_used_in_window;
arl.used = net_used_in_window;
arl.max = max_user_use_in_window;
return arl;
}
......
......@@ -181,6 +181,12 @@ class producer_plugin_impl {
};
void on_incoming_block(const signed_block_ptr& block) {
if( block->timestamp > fc::time_point::now() ) {
FC_ASSERT( block->timestamp < fc::time_point::now(), "received a block from the future, ignoring it" );
}
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
// abort the pending block
chain.abort_block();
......@@ -197,10 +203,13 @@ class producer_plugin_impl {
if( chain.head_block_state()->header.timestamp.next().to_time_point() >= fc::time_point::now() )
_production_enabled = true;
ilog("Received block ${id}... #${n} @ ${t} signed by ${p} [trxs: ${count}, lib: ${lib}, confirmed: ${confs}]",
("p",block->producer)("id",fc::variant(block->id()).as_string().substr(0,16))
("n",block_header::num_from_id(block->id()))("t",block->timestamp)
("count",block->transactions.size())("lib",chain.last_irreversible_block_num())("confs", block->confirmed) );
if( fc::time_point::now() - block->timestamp < fc::seconds(5) || (block->block_num() % 1000 == 0) ) {
ilog("Received block ${id}... #${n} @ ${t} signed by ${p} [trxs: ${count}, lib: ${lib}, confirmed: ${confs}]",
("p",block->producer)("id",fc::variant(block->id()).as_string().substr(0,16))
("n",block_header::num_from_id(block->id()))("t",block->timestamp)
("count",block->transactions.size())("lib",chain.last_irreversible_block_num())("confs", block->confirmed) );
}
}
......@@ -409,8 +418,8 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
if((block_time - now) < fc::microseconds(config::block_interval_us/10) ) { // we must sleep for at least 50ms
ilog("Less than ${t}us to next block time, time_to_next_block_time ${bt}",
("t", config::block_interval_us/10)("bt", block_time));
// ilog("Less than ${t}us to next block time, time_to_next_block_time ${bt}",
// ("t", config::block_interval_us/10)("bt", block_time));
block_time += fc::microseconds(config::block_interval_us);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册