python ethereum 代码分析 《1》
python 版本以太坊
项目地址
https://github.com/ethereum/pyethapp
https://github.com/ethereum/pyethereum
https://github.com/ethereum/pydevp2p
其中 pyethapp 依赖pyethereum 和 pydevp2p。pyethereum主要包括对block的处理,对transaction的处理以及以太坊虚拟机部分;pydevp2p 是p2p网络库,主要包括节点发现协议(Node Discovery)的实现,p2p通信协议的实现,并定义了protocol基类和service基类
pydevp2p 模块
代码整体结构
1.协议基类BaseProtocol 查看代码
子类协议继承BaseProtocol中的command类
来实现对不同command进行处理。
receive_packet方法
def receive_packet(self, packet):
cmd_name = self.cmd_by_id[packet.cmd_id]
cmd = getattr(self, '_receive_' + cmd_name)
try:
cmd(packet)
except ProtocolError as e:
log.debug('protocol exception, stopping', error=e, peer=self.peer)
self.stop()
receive_packet 通过cmd_id 来获取到对应的command类从而获得该command类的receive方法,调用该方法处理数据包packet
BaseProtocol子类协议中所有command类的方法在协议实例化的时候通过调用_setup方法 被添加到BaseProtocol子类实例中
def _setup(self):
# collect commands
klasses = [k for k in self.__class__.__dict__.values()
if isinstance(k, type) and issubclass(k, self.command) and k != self.command]
assert len(set(k.cmd_id for k in klasses)) == len(klasses)
def create_methods(klass):
instance = klass()
def receive(packet):
"decode rlp, create dict, call receive"
assert isinstance(packet, Packet)
instance.receive(proto=self, data=klass.decode_payload(packet.payload))
def create(*args, **kargs):
"get data, rlp encode, return packet"
res = instance.create(self, *args, **kargs)
payload = klass.encode_payload(res)
return Packet(self.protocol_id, klass.cmd_id, payload=payload)
def send(*args, **kargs):
"create and send packet"
packet = create(*args, **kargs)
self.send_packet(packet)
return receive, create, send, instance.receive_callbacks
for klass in klasses:
receive, create, send, receive_callbacks = create_methods(klass)
setattr(self, '_receive_' + klass.__name__, receive)
setattr(self, 'receive_' + klass.__name__ + '_callbacks', receive_callbacks)
setattr(self, 'create_' + klass.__name__, create)
setattr(self, 'send_' + klass.__name__, send)
self.cmd_by_id = dict((klass.cmd_id, klass.__name__) for klass in klasses)
2.启动peermanager Service
基类BaseService,一个service对应一个WireProtocol
先看下客户端启动时用到哪些服务:
ethapp启动的服务
其中NodeDiscovery(节点发现服务), PeerManager(节点管理服务)在pydevp2p 模块中实现。
注册服务并启动
for service in services + contrib_services:
a