版权声明:本文为作者原创,如需转载请通知本人,并标明出处和作者。擅自转载的,保留追究其侵权的权利。golang群:570992072。qq 29185807 个人公众号:月牙寂道长 公众号微信号yueyajidaozhang https://cloud.tencent.com/developer/article/1454526
本文微信公众号 月牙寂道长 文章链接为:https://mp.weixin.qq.com/s/gdVIXq75MW3SrH6Of-wT2A
本文图片可能不太清晰,看清晰版本的,可以看原文链接微信公众号链接。
以太坊go-ethereum源码的模块划分非常清晰,所以其各个模块,几乎是相互独立的。
有一个以太坊的架构图:
图片来自:https://blog.csdn.net/s_lisheng/article/details/77990523
(已得到原作者转载许可)
以太坊源码分析---go-ethereum之MPT(Merkle-Patricia Trie) 是讲解其中Trie模块
此次分析的是事件Event模块
源码目录为:github.com/ethereum/go-ethereum/event
注:代码版本为1.0.0
Event
event是一个订阅与发布模块
先看看github.com/ethereum/go-ethereum/event/example_test.go
这里面显示了用法
22-24:定义了三个不同类型的数据结构
26:声明了一个TypeMux变量mux
29-30:注册订阅了两种数据类型的消息
31-37:开启一个协程,用于接收订阅消息
40-43:post发布消息
48:停止订阅发布系统
那么看源码github.com/ethereum/go-ethereum/event/event.go
46:读写锁
47:重点subm为保存注册的消息类型与订阅的者的muxsub
48:停止标识
其结构如下图
subm用于保存不同类型的消息订阅者,其中每个类型后面是一个队列,队列里保存的是muxsub,多个类型中,也可以有相同的订阅者muxsub
Subscribe
注册订阅者
58:声明一个变量订阅者sub
59-60:加锁
61-62:判断是否已经stop
64-65:判断subm是否初始化过,没有则初始化
67-77:为注册流程
68:获取消息类型
69:获取消息类型已经注册过的所有订阅者
70:从旧的订阅者查找是否是重复订阅
73-76:将新的订阅者放到队列尾部
这里的注册过程很简单也很清晰
Post
85:获取发布消息的类型
91:查找消息类型对于的订阅者队列
93-95:对每个订阅者进行消息传递 deliver
muxsub
消息订阅者
145:订阅发布者
154:消息读取chan
155:消息发布chan
162-163:初始化,读取和发送初始化都是同一个chan
读取
在example中,就有获取消息读取chan,进行等待读取的。如下图红框
发送
195:将ev通过postC发送
event/filter
过滤模块
还是先看案例
github.com/ethereum/go-ethereum/event/filter/filter_test.go
28:初始化了一个过滤系统 New
29:过滤系统启动 Start
30-42:Install过滤模块
43:Notify进行过滤
44:过滤系统停止 Stop
github.com/ethereum/go-ethereum/event/filter/filter.go
Filters
33:id记录filter数量
34:注册的过滤模块
35:事件chan
37:退出chan
22-24:Filter接口,两个方法Compare、Trigger
27-29:FilterEvent
Start
loop
主要流程在77-84
77:从事件chan中获取事件event
78:遍历所有注册的watcher
80:判断事件类型与watcher的类型是否一致
81:进行事件的Compare
82:进行Trigger
Install
其中id就是从0开始。就是将过滤的规则注册到watchers中
Notify
将需要过滤的事件,发送到过滤处理loop中
github.com/ethereum/go-ethereum/event/filter/generic_filter.go
一个简单的字符串过滤,实现了Compare和Trigger方法
eth_filter
流程是类似的
github.com/ethereum/go-ethereum/event/filter/eth_filter.go
这里的区别在于
filters是core.Filter(github.com/ethereum/go-ethereum/core中的)
Installfilter
注册,将filter注册到filters中(mapint*core.Filter)
Start
filterLoop
订阅了三个类型的消息ChainEvent、TxPreEvent、state.Logs
93:从订阅的消息中,等待获取消息事件
95-102:处理的是ChainEvent
104-111:处理的是TxPreEvent
113-123:处理的是state.Logs
龚浩华
月牙寂道长
QQ 29185807
2018年09月04日