交易同步过程

1 通过命令cleos调用 cleos transfer ${from_account} ${to_account} ${quantity} 发起交易
2 eos调用chain_plugin 的push_transaction,内部调用注册好的方法。

1
app().get_method<incoming::methods::transaction_async>();

代码截图如下

在producer_plugin插件的plugin_initialize函数中提前注册了incoming::methods::transaction_async。

所以实际调用了producer_plugin_impl的on_incoming_transaction_async(trx, persist_until_expired, next )函数,
传递的参数分别是pretty_input,true,和一个lambda匿名函数

12345678910111213141516171819
app().get_method<incoming::methods::transaction_async>()(pretty_input, true, [this, next](const fc::static_variant<fc::exception_ptr, transaction_trace_ptr>& result) -> void{ if (result.contains<fc::exception_ptr>()) { next(result.get<fc::exception_ptr>()); } else { auto trx_trace_ptr = result.get<transaction_trace_ptr>();

 try { chain::transaction_id_type id = trx_trace_ptr->id; fc::variant output; try { output = db.to_variant_with_abi( *trx_trace_ptr, abi_serializer_max_time ); } catch( chain::abi_exception& ) { output = *trx_trace_ptr; }

 next(read_write::push_transaction_results{id, output}); } CATCH_AND_CALL(next); } });

3 在producer_plugin_impl的on_incoming_transaction_async中调用controller的 push_transaction,并执行trx。
将交易插入_pending_incoming_transactions中

接下来调用了controller的push_transaction函数

4 controller的push_transaction函数中发送消息accepted_transaction,而目前常用的网络插件为bnet_plugin,net_plugin目前已作为备用,
由于在bnet_plugin的startup函数中绑定了消息回调函数

1234
my->_on_appled_trx_handle = app().get_channel<channels::accepted_transaction>()                                .subscribe( [this]( transaction_metadata_ptr t ){                                       my->on_accepted_transaction(t);                                });

通过app().get_channel将channels::accepted_transaction信号和lambda表达式绑定起来,所以当controller发送信号accepted_transaction就会调用这个lambda表达式传递参数,从而调用bnet_plugin_impl中on_accepted_transaction函数。
5 bnet_plugin_impl通过on_accepted_transaction将消息广播到其他节点

1234
void on_accepted_transaction( transaction_metadata_ptr trx ) { if( trx->implicit || trx->scheduled ) return; for_each_session( [trx]( auto ses ){ ses->on_accepted_transaction( trx ); } ); }

6 其他节点收到消息后,进入on处理流程,发送transction消息
bnet_plugin处理消息函数

transaction消息处理

通过

1
app().get_channel<incoming::channels::transaction>().publish(p);

发送transaction消息。
7 producer_plugin绑定了消息处理的回调函数

收到消息后,调用on_incoming_transaction_async,调用controller的 push_transaction,并执行trx。
以上就是eos交易同步过程。

区块生产过程

整体的区块生产流程

1 检查自己是否是生产者,一个生产者500ms出一次块,共出12次之后切换生产者。
2 对上次确认的区块到本次的区块做BFT签名,涉及函数set_confirmed和maybe_promote_pending,具体可以参看controller中start_block函数
3 等待一个出块周期500ms
4 计算action的merkle root
5 计算transaction的merkle root
6 对区块签名
7 提交区块到DB
8 递归调用schedule_production_loop

区块同步过程

1 参考区块生产过程,producer_plugin循环生产区块,先start_block处理BFT签名并确定不可逆的区块数,之后produce_block调用controller
2 controller使用finalize_block计算merkle root,使用commit_block提交到fork database中,fork db会依据1中计算的不可逆区块数,将不可逆的区块删除,并发送irreversible消息,controller绑定了该消息处理的回调函数

123
fork_db.irreversible.connect( [&]( auto b ) {                                 on_irreversible(b);                                 });

3 controller收到消息后,调用on_irreversible处理发送irreversible_block消息。bnet注册了该消息处理的回调函数

1234
my->_on_irb_handle = app().get_channel<channels::irreversible_block>()                                .subscribe( [this]( block_state_ptr s ){                                       my->on_irreversible_block(s);                                });

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消息

123456789101112131415
void on( const signed_block_ptr& b ) { peer_ilog(this, "received signed_block_ptr"); if (!b) { peer_elog(this, "bad signed_block_ptr : null pointer"); EOS_THROW(block_validate_exception, "bad block" ); } status( "received block " + std::to_string(b->block_num()) ); //ilog( "recv block ${n}", ("n", b->block_num()) ); auto id = b->id(); mark_block_status( id, true, true );

 app().get_channel<incoming::channels::block>().publish(b);

 mark_block_transactions_known_by_peer( b ); }

9 Producer_plugin收到block消息后调用controller的push_block函数
10 Controller调用apply_block判断如果新收到的block比原有的链长,则切换到新链上
11 Controller调用finalize_block计算merkle root,使用commit_block提交到DB
以上就是区块同步过程。
感谢关注我的公众号

转载于:https://www.cnblogs.com/secondtonone1/p/10338918.html

eos交易同步过程和区块生产过程源码分析相关推荐

  1. hadoop作业初始化过程详解(源码分析第三篇)

    (一)概述 我们在上一篇blog已经详细的分析了一个作业从用户输入提交命令到到达JobTracker之前的各个过程.在作业到达JobTracker之后初始化之前,JobTracker会通过submit ...

  2. 【Android 启动过程】Activity 启动源码分析 ( ActivityThread 流程分析 二 )

    文章目录 前言 一.ActivityManagerService.attachApplicationLocked 二.ActivityStackSupervisor.attachApplication ...

  3. 【Android 启动过程】Activity 启动源码分析 ( ActivityThread -> Activity、主线程阶段 二 )

    文章目录 前言 一.ActivityThread 类 handleLaunchActivity -> performLaunchActivity 方法 二.Instrumentation.new ...

  4. 【Android 启动过程】Activity 启动源码分析 ( ActivityThread -> Activity、主线程阶段 一 )

    文章目录 前言 一.ClientTransactionHandler.scheduleTransaction 二.ActivityThread.H 处理 EXECUTE_TRANSACTION 消息 ...

  5. 【Android 启动过程】Activity 启动源码分析 ( AMS -> ActivityThread、AMS 线程阶段 二 )

    文章目录 前言 一.热启动与冷启动选择 二.AMS 进程中执行的相关操作 三.通过 Binder 机制转到 ActivityThread 中执行的操作 总结 前言 上一篇博客 [Android 启动过 ...

  6. EOS智能合约:system系统合约源码分析

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. eosio.system 概览 笔者使用的IDE是VScode,首先来看eosio.system的源码结构.如下图所示. ...

  7. 【精】EOS智能合约:system系统合约源码分析

    系统合约在链启动阶段就会被部署,是因为系统合约赋予了EOS链资源.命名拍卖.基础数据准备.生产者信息.投票等能力.本篇文章将会从源码角度详细研究system合约. 关键字:EOS,eosio.syst ...

  8. 【Android 启动过程】Activity 启动源码分析 ( AMS -> ActivityThread、AMS 线程阶段 )

    文章目录 一.Activity 启动源码分析 ( AMS | ActivityManagerService ) 1.Instrumentation 调用 AMS 方法 2.ActivityStarte ...

  9. 【Android 启动过程】Activity 启动源码分析 ( Activity -> AMS、主线程阶段 )

    文章目录 一.Activity 启动源码分析 ( Activity -> AMS 阶段 ) 一.Activity 启动源码分析 ( Activity -> AMS 阶段 ) 调用 star ...

最新文章

  1. ffmpeg php 抠像_PHP中使用ffmpeg截取视频图片笔记
  2. BZOJ 2037 Sue的小球
  3. VS2017 Intelligense C++ 设置的几个重点
  4. Oracle中的move命令
  5. solr定时实时重建索引和增量更新
  6. 信息检索 python_python-工程数据结构/信息检索和存储
  7. 清华计算机复试线2020,清华大学2020年研考复试线公布,复试时间待定
  8. codeforces 460C - Present 二分加模拟
  9. Djangon 基础总结 汇总 从请求到返回页面的过程,
  10. 2-visio使用与卸载
  11. 菜鸟教程Python教程100例(一)(持续更新)
  12. 把14亿中国人民都拉到一个微信群里在技术上能实现吗?
  13. ips 代理模式_IPS的完整形式是什么?
  14. 计算机的表白隐藏功能,微信还有这个功能?隐藏代码还能表白!教你高级告白手段...
  15. spring boot实现验证码登录
  16. WIN 7 系统 问题记录
  17. 泰拉瑞亚服务器一直显示什么,《泰拉瑞亚》Steam联机总是掉?教你一个稳定联机方法...
  18. 微信小程序:block制作动态商品列表
  19. 新一年级家长快查收,小学入学必备物品超强清单!
  20. 陌生人不小心将话费充到你号码里了,苦苦哀求你归还,你会怎么做?

热门文章

  1. 电子版,材料获取说明
  2. mybatis当遇到,用mysql关键字作为的字段的表,如何处理
  3. 2018-10-04-Python全栈开发-day61-DJANGO-MODELS操作补充
  4. maven+testng+eclipse
  5. SQL记录-PLSQL异常
  6. 【BZOJ-2938】病毒 Trie图 + 拓扑排序
  7. javascrip 中的一些方法
  8. rfcomm工具的使用方法 创建/dev/rfcomm0 并检测
  9. kubectl 命令管理(1)
  10. android自动关闭uvc相机服务,android 调用系统相机崩溃的解决方案