python ethereum 代码分析

本文分析了python版以太坊中的pydevp2p模块,包括其代码结构、协议基类BaseProtocol、启动peermanager Service以及节点发现协议。重点讨论了BaseProtocol的receive_packet方法、peermanager的启动过程、节点发现协议的kademlia实现,以及NodeDiscovery如何将发现的节点添加到peermanager的peers列表。
摘要由CSDN通过智能技术生成

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值