链的控制器controller 包含很多重要功能。
class controller {
struct config {
flat_set<account_name> actor_whitelist;白名单
flat_set<account_name> actor_blacklist;黑名单
flat_set<account_name> contract_whitelist;合约白名单
flat_set<account_name> contract_blacklist;合约黑名单
flat_set< pair<account_name, action_name> > action_blacklist;操作黑名单
flat_set<public_key_type> key_blacklist;key和名单
path blocks_dir = chain::config::default_blocks_dir_name;块的路径
path state_dir = chain::config::default_state_dir_name;
uint64_t state_size = chain::config::default_state_size;
uint64_t reversible_cache_size = chain::config::default_reversible_cache_size;
bool read_only = false;
bool force_all_checks = false;
bool contracts_console = false;
genesis_state genesis;
wasm_interface::vm_type wasm_runtime = chain::config::default_wasm_runtime;
};
enum class block_status {
irreversible = 0, ///< this block has already been applied before by this node and is considered irreversible
这个块以前已经被这个节点应用,并且被认为是不可逆的
validated = 1, ///< this is a complete block signed by a valid producer and has been previously applied by this node and therefore validated but it is not yet irreversible
这是一个完整的块,由一个有效的生产者签名,以前已经被这个节点应用,因此验证,但它仍然是不可逆转的。
complete = 2, ///< this is a complete block signed by a valid producer but is not yet irreversible nor has it yet been applied by this node
这是一个完整的块,由一个有效的生产者签名,但尚未不可逆转,也没有被这个节点所接受
incomplete = 3, ///< this is an incomplete block (either being produced by a producer or speculatively produced by a node)
这是一个不完整的块(由生产者产生或由一个节点推测产生)
};
......
void startup();
void finalize_block(); 完成块
void sign_block( const std::function<signature_type( const digest_type& )>& signer_callback );签名块
void commit_block();提交块
void push_block( const signed_block_ptr& b, block_status s = block_status::complete );
......
signal<void(const block_state_ptr&)> accepted_block_header; 接受区块头
signal<void(const block_state_ptr&)> accepted_block;接受区块
signal<void(const transaction_metadata_ptr&)> accepted_transaction;接受交易
signal<void(const transaction_trace_ptr&)> applied_transaction;
signal<void(const header_confirmation&)> accepted_confirmation;接受确认
在producer_plugin.cpp
class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin_impl> {
public:
producer_plugin_impl(boost::asio::io_service& io)
:_timer(io)
,_transaction_ack_channel(app().get_channel<compat::channels::transaction_ack>())
{
}
optional<fc::time_point> calculate_next_block_time(const account_name& producer_name) const;计算下一个块的时间
void schedule_production_loop();//循环计划产生
void produce_block();//产生块
bool maybe_produce_block();//可能产生块
插件启动的时候,调用循环计划产生块
void producer_plugin::plugin_startup()
{
…
my->schedule_production_loop();
…
}
尝试产生块
bool producer_plugin_impl::maybe_produce_block() {
auto reschedule = fc::make_scoped_exit([this]{
schedule_production_loop();
});
try {
produce_block();
return true;
} FC_LOG_AND_DROP();
fc_dlog(_log, "Aborting block due to produce_block error");
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
chain.abort_block();
return false;
}
产生块并签名,提交
//产生块
void producer_plugin_impl::produce_block() {
FC_ASSERT(_pending_block_mode == pending_block_mode::producing, "called produce_block while not actually producing");
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
const auto& pbs = chain.pending_block_state();
const auto& hbs = chain.head_block_state();
FC_ASSERT(pbs, "pending_block_state does not exist but it should, another plugin may have corrupted it");
auto signature_provider_itr = _signature_providers.find( pbs->block_signing_key );
FC_ASSERT(signature_provider_itr != _signature_providers.end(), "Attempting to produce a block for which we don't have the private key");
//idump( (fc::time_point::now() - chain.pending_block_time()) );
chain.finalize_block();//完成
chain.sign_block( [&]( const digest_type& d ) {
auto debug_logger = maybe_make_debug_time_logger();
return signature_provider_itr->second(d);
} );//签名
chain.commit_block();//提交
auto hbt = chain.head_block_time();
//idump((fc::time_point::now() - hbt));
block_state_ptr new_bs = chain.head_block_state();
// for newly installed producers we can set their watermarks to the block they became
if (hbs->active_schedule.version != new_bs->active_schedule.version) {
flat_set<account_name> new_producers;
new_producers.reserve(new_bs->active_schedule.producers.size());
for( const auto& p: new_bs->active_schedule.producers) {
if (_producers.count(p.producer_name) > 0)
new_producers.insert(p.producer_name);
}
for( const auto& p: hbs->active_schedule.producers) {
new_producers.erase(p.producer_name);
}
for (const auto& new_producer: new_producers) {
_producer_watermarks[new_producer] = chain.head_block_num();
}
}
_producer_watermarks[new_bs->header.producer] = chain.head_block_num();
if(new_bs->block_num % 50 == 0) //update by zhoufd
ilog("Produced block ${id}... #${n} @ ${t} signed by ${p} [trxs: ${count}, lib: ${lib}, confirmed: ${confs}]",
("p",new_bs->header.producer)("id",fc::variant(new_bs->id).as_string().substr(0,16))
("n",new_bs->block_num)("t",new_bs->header.timestamp)
("count",new_bs->block->transactions.size())("lib",chain.last_irreversible_block_num())("confs", new_bs->header.confirmed));
}