bitshares 比特股源码阅读笔记(三)

in #cn6 years ago

比特股重节点,也称重钱包,英文名称witness-node,无疑是比特股网络的核心。比特股内盘区块链中的区块生成,就是由见证人运行的witness_node生产的。
witness_node编译为一个单独的可执行文件,其main函数在programs\witness_node 目录下,在main函数当中,我们并不能看到太多有用的信息。因为bitshares-core 项目提供了一个应用框架(application)类,和一些插件接口(plugin)来访问bitshares区块网络和区块链数据库。witness_node实际就是一个启用了witness plugin的application的实例。
application 类位于命名空间graphene::app下,其重要的成员和方法有:
一个指向区块链数据库实例的智能共享指针
一个指向p2p网络节点的智能共享指针
插件的注册,启用,初始化,关闭等功能的接口
客户端访问api的权限设置方法
一个表示本地节点是否同步完毕的信号和方法
appliation 采用了桥接设计模式,以上接口和方法的真实实现其实都在graphene::app::detail::application_impl类当中。重钱包的websocket server 的智能指针就存放于application_impl类当中。

witness_node 的区块产生循环位于libraries\plugins\witness\witness.cpp文件中。witness区块生成循环启动时的堆栈调用过程:main()->node.startup()->application.startup_plugins()->witness_plugin.plugin_startup()-> schedule_production_loop()

schedule_production_loop()中使用到多线程,通过bitshares-fc 提供的基于promise/future的异步通信机制来与新线程通信。bitshares-fc后台是使用boost的多线程实现,只不过自己加了层封装。 schedule_production_loop()异步调用witness_plugin::block_production_loop()生成区块。witness_plugin::block_production_loop()生成区块后,又调用schedule_production_loop(),这样就构成了一个循环。循环周期在一秒左右。
block_production_loop()调用maybe_produce_block()检测是否可以并生成区块。

maybe_produce_block 先检查区块是否已经完成同步,然后检测是否已经到生成新区块的时间,如果是,则再检查当前轮先的见证人私钥是否在本地节点中,检测本地节点正常区块生成率是否高于33%,检测当前时间是否已经比预计的时间晚了500ms,最后生成新的区块并异步广播。