EOS 区块生产过程
1. 交易同步过程
1. 在cleos界面输入 cleos transfer ${from_account} ${to_account} ${quantity}
2. 调用chain_plugin 的push_transaction,发送transaction_async消息
3. 触发了producer_plugin的on_incoming_transaction_async,调用controller的 push_transaction,并执行trx。
4. controller发送消息accepted_transaction,触发了bnet_plugin和net_plugin(已废弃)的on_accepted_transaction
5. bnet_plugin和net_plugin(已废弃)将消息广播发送到其他节点
6. 其他节点收到消息后,进入on处理流程,发送transction消息,producer_plugin收到消息后,调用on_incoming_transaction_async,调用controller的 push_transaction,并执行trx。
2. 区块成产过程
producer 收到广播的交易之后,将交易保存下来放在pending_state中,producer_plugin在startup的时候就启动了区块生产schedule_production_loop,先做区块准备工作,即start_block,主要完成区块BFT的签名,之后进入maybe_produce_block,进入生产过程,即produce_block,这是区块生产的核心部分,包括计算merkle root,提交到DB中等,在最后重新调用schedule_production_loop,这样就形成了循环,具体流程见下图:
1. 检查自己是否是生产者,一个生产者500ms出一次块,共出12次之后切换生产者。
2. 对上次确认的区块到本次的区块做BFT签名,涉及函数set_confirmed和maybe_promote_pending
3. 等待一个出块周期500ms
4. 计算action的merkle root
5. 计算transaction的merkle root
6. 对区块签名
7. 提交区块到DB
8. 递归调用schedule_production_loop
3. 区块同步过程
1. 参考区块生产过程,producer_plugin循环生产区块,先start_block处理BFT签名并确定不可逆的区块数,之后produce_block调用controller
2. Controller使用finalize_block计算merkle root,使用commit_block提交到fork database中,fork db会依据1中计算的不可逆区块数,将不可逆的区块删除,并发送irreversible消息
3. Controller收到消息后,调用on_irreversible处理发送irreversible_block消息
4. bnet_plugin 收到消息后,调用on_irreversible_block处理。
5. Controller发送accepted_block_header和accepted_block消息
6. producer_plugin收到消息后, 调用on_block,calc_dpos_last_irreversible计算不可逆块。
7. bnet_plugin/net_plugin 收到之后广播到其他节点
8. 其他节点的bnet_plugin/net_plugin收到P2P消息后,通过发送block消息/调用accept_block函数发送block_async消息
9. Producer_plugin收到block/block_async消息后调用controller的push_block函数
10. Controller调用apply_block判断如果新收到的block比原有的链长,则切换到新链上
11. Controller调用finalize_block计算merkle root,使用commit_block提交到DB
下面贴张网上找到的log图,说明消息的时序: