一、P2P模块

1、P2P模块介绍

是处理节点相互通信的组件,包括节点发现并建立连接,广播区块和交易,同步区块。

 

2、P2P上下文

与 Mempool 模块的交互:广播 Mempool 模块发送过来的交易,获取 Mempool 模块中的交易

与 Blockchain 模块的交互:广播 Blockchain 模块发送过来的区块,处理获取 peer 信息的请求,处理从对端下载区块和区块头的请求

 

3、P2P逻辑结构包含如下功能模块

1)节点发现模块:发现网络中的节点,并尝试建立连接

2)数据下载模块:请求对端节点下载区块,用于同步区块

3)数据过滤模块:过滤重复接收到的广播交易和区块

4)节点监控模块:动态监测已建立连接的对端节点

 

 

二、存储模块

 

 

1、存储模块介绍

和传统的区块链实现相同,CICP区块链中使用高性能、高可靠的KV DB来进行数据的存储,并且设计上提供的DB接口也都是针对KV存储的特性定义的。

在系统中,目前存在4个数据库实例,

1)addrbook:实现的能力比较单一,主要是存储P2P的节点以及相关的状态信息。

2)wallet:存储本地账号信息。

3)blockchain.db:存储区块头、区块体以及区块相关的附加信息,还存储交易本地执行返回的结果信息。

4)store:存储交易执行的结果以及区块状态哈希信息。

存储模块,有以下几个要点:

1)底层存储及操作通过灵活配置可支持多种实现方式。底层根据配置可以支持多种类型的KV DB实现,比如goleveldb、gobadgerdb、gomemdb、gossdb等。上述addrbook、wallet、blockchain.db、store这4个数据库实例的底层存储操作都是通过配置的具体的KV DB来实现的,比如默认配置的goleveldb。

2)实际应用中,Excutor执行器通过StateDB和LocalDB两个抽象数据库概念,分别用来对blockchain.db和store的存储进行消息查询等操作。

3)Store模块数据的存储格式,也采用可配置、可插拔的方式,默认支持mavl tree的存储格式。也支持用户自行扩展新的存储格式,比如单纯的KVDB存储格式、基于MVCC的KVDB存储格式、MPT存储格式等。,最终对数据存储的底层操作还是通过配置的具体的KV DB来实现的,比如goleveldb。

 

2、存储模块上下文

P2P、Wallet、Blockchain、Store几个模块均涉及数据存储,底层通过DB接口向KV DB实例写入及读出数据。

BlockChain及Store模块也提供数据查询接口,具体通过StateDB、LocalDB抽象数据库对象使用消息来进行操作。

BlockChain模块在生成区块时,可以通过消息向Store模块写入状态信息。

Wallet、Consensus、Client等模块可以通过执行器,由StateDB、LocalDB对象分别向Blockchain、Store使用消息发起数据查询。

Client模块也可以通过消息直接向Store发起状态数据查询。

 

3、底层存储KV DB的逻辑架构

1)DB接口:底层数据存储支持的kv db都需要适配上述接口。

2)goleveldb:可以看到goleveldb实现了DB接口、Iterator接口、Batch接口,就可以作为存储模块的底层数据库实现来在系统中被使用。

3)gobadgerdb、gomemdb、gossdb等不同的kv db的实现也是类似的,都需要实现DB接口、Iterator接口、Batch接口以满足上层逻辑功能的需要。

 

4、StateDB和LocalDB的逻辑架构

两个抽象数据库的功能非常简单,容易导致误解的是两个DB的使用场景和存储内容,所以下面使用表格方式,列出了两个DB之间的区别。

 

5、Store的逻辑架构

1)Store层决定了状态数据在底层KV DB中将以何种格式进行组织。

2)系统默认支持mavl tree格式的实现,通过加载插件还可支持单纯的KV DB的实现、基于MVCC的KV DB的实现、MPT的实现等。

3)开发者如果要扩展开发自己的数据组织格式,需要实现SubStore接口,并注册到系统中,做好对应配置即可。

 

 

三、Blockchain 模块

 

 

1、Blockchain模块介绍

Blockchain 模块是处理 block 的组件,包括存储 block 信息,将 block 加入主链或者侧链,同步 block。同时对外提供查询 block 以及区块链状态信息的接口。

 

2、Blockchain模块上下文

1)与 Consensus 模块的交互:处理 Consensus 模块打包的区块,处理 Consensus 模块查询 block 信息的请求

2)与 P2P 模块的交互:处理 P2P 模块接收的广播区块,向 P2P 模块发送区块进行广播,处理 P2P 模块查询 block 信息的请求

3)与 Mempool,Executor 模块的交互:处理这两个模块查询区块链状态的请求

 

3、 Blockchain模块逻辑结构

Blockchain 模块主要由三个子模块组成:消息接收模块,区块同步模块和区块存储模块

1)消息接收模块:接受其他模块的有关 block 以及区块链状态的信息查询的消息

2)区块同步模块:在节点起动之后,比较网络中 peer 最新高度和自己的高度,如果自己的高度比 peer 的最新高度低就主动发起 block 的同步请求追赶主链

3)区块存储模块:将 block 信息按照不同类型存储到数据库

 

 

四、Client模块

 

 

1、Client模块介绍

Client模块可以通过RPC接口直接调用系统内已实现的服务,可以简单的将Cli模块理解成一个前端应用。

 

RPC是通过提供一系列协议方式,对外部应用提供各种系统服务的,在系统中主要采用了用protobuf定义协议的grpc服务和用json定义协议的jsonrpc服务,分别为不同的前端应用提供相同的系统服务。

 

2、Client模块上下文

模块与系统的关系

1)根据输入的指令的不同,调用相的Rpc接口

2)Rpc模块在接收到rpc请求之后,会通过设置topic将消息发送到指定的模块

3)各个模块处理完毕之后,将结果返回给rpc模块

4)最终rpc模块根据响应中的信息,构造成cli需要的结构并返回。

 

 

五、Mempool模块

 

 

1、Mempool模块介绍

mempool中文名就是交易池,顾名思义,就是做交易的一个缓存功能。

主要目的是为了解决共识模块可能比rpc模块速度慢的问题。

在mempool中会对接收的交易做初步合法性的校验,过滤掉一些非法的交易。

对交易发送者做流量限制,防止同一地址发送太过频繁。同时,mempool会与其他模块会有消息交互,

 

2、Mempool模块逻辑架构及上下文

1)mempool与 blockchain的交互:

当有新的区块成写入后,blockchain 会给mempool发送types.EventAddBlock消息事件,告诉mempool,已经有block成功写入了,mempool收到后,会触发 mem.RemoveTxsOfBlock(block)方法,移除Mempool中已被Blockchain打包的tx。

当有区块回退时,blockchain会给mempool 发送一条types.EventDelBlock 消息类型的消息,告诉mempool,有区块需要回退,会触发mem.setHeader()和mem.DelBlock()方法,把相应区块内的交易重新加回Mempool中.

 

2)mempool与 consensus的交互:

区块打包时,consensus会主动发送一个types.EventTxList 消息,去触发mem.GetTxList()方法,获取需要打包的交易列表。

区块打包时,当consensus给blockchain,发送types.EventAddBlockDetail消息事件,有新的区块需要写入,如果新块写成功了,blockchain会给consensus返回相应的 blockdetail信息,根据这个和原始block找出错误交易列表,然后往mempool 发送types.EventDelTxList消息,去删除相应的错误交易。

 

3)mempool与 p2p的交互:

如果mempool收到rpc 发送过来的tx,会经过一系列校验检查,如果校验过了,就会把合法tx 通过p2p 模块广播出去。

 

4)mempool与 rpc的交互:

mempool中给rpc提供了 GetLastMempool(),GetMempool(),SendTx() 3个接口,供外部调用。

 

 

六、共识模块

 

 

1、共识模块介绍

共识模块是实现区块链共识机制的模块,共识机制是区块链技术的重要组件。区块链共识机制的目标是使所有的诚实节点保存一致的区块链视图,同时满足两个性质:

1)一致性:所有诚实节点保存的区块链的前缀部分完全相同。

2)有效性:由某诚实节点发布的信息终将被其他所有诚实节点记录在自己的区块链中。

通俗来说,共识机制在区块链网络内起到决定谁负责生成新区块以及维护区块链统一的作用。

目前区块链的共识机制大致可以分为PoW(Proof of Work 工作量证明)、PoS(Proof of Stack 权益证明)、DPoS(Delegated Proof of Stake 委托权益证明)以及分布式一致性算法几类。

 

2、共识模块逻辑架构及上下文

共识模块是可插拔的,支持平行链共识,PBFT,Raft,Tendermint,Ticket几种共识算法。

共识模块是连接交易与区块的桥梁,作用主要体现在推动区块的产生。所有由共识模块发出的事件都是实现这一目标。

注:EventBlockChainQuery事件除外,在该模块中此事件只与Tendermint共识的动态增加,删除Validator节点功能有关。

为实现这一目标分成如下几步:

1)同步区块高度:通过向Blockchain模块发送EventIsSync事件,得到当前区块高度是否已经与主链高度一致,如果一致,则可以参与新高度区块的共识过程;否则,继续等待同步到最新高度。

2)获取交易:通过向Mempool模块发送EventTxList事件触发,获取需要打包进区块的交易。

3)交易共识:对这些将要打包的交易进行验证,并确定哪个节点负责生成新区块。

4)产生新区块:通过向Blockchain模块发送EventAddBlockDetail事件触发。

5)删除错误交易:通过向Mempool模块发送EventDelTxList事件触发。

注:EventGetBlocks用于向Blockchain模块获取指定高度范围的区块,EventGetLastBlock事件用于向Blockchain模块获取最新的区块。

 

 

七、钱包模块

 

 

1、钱包模块介绍

钱包模块主要面向钱包app提供两大服务,一个是区块链账户管理,包括账户的创建,公私钥和地址信息的管理。钱包客户端可以通过这些服务接口创建和管理账户,导出导入私钥等。另一个是交易的签名和发送,用于bty转账和智能合约交易的发送。

 

2、钱包模块结构

1)BIP44钱包结构

钱包模块使用BIP44定义,通过一套seed管理多个币种,seed支持中文字符和英文字符。同时,用户对wallet设置一个password来加密seed信息,password由用户指定和保存。

2)私钥、地址、公钥信息管理

wallet模块对应有AccountDB,用于存储用户创建的账户信息,包括私钥、地址、公钥等。AccountDB对应的配置信息在区块链配置文件中可配。AccountDB中主要存储3张表。

AccountTable以时间戳和账户地址为key,主要用于所有Account账户的list输出

AddressTable以账户地址为key,主要用于通过address地址查询账户信息

LabelTable以label为key,主要用于通过label查询账户信息

 

 

八、执行器模块

 

 

1、执行器模块介绍

顾名思义,执行器模块主要是用于执行逻辑的。在区块链中,所有的数据都是通过交易生成的,这些数据按照一定的规则,组装成一个个区块,最终形成一个完整的区块链条。

而在一个完整的区块链系统中,交易的执行是核心,比如一次A到B的转账交易,A账户的余额会减少,B账户的余额会增加,这个账户余额变更的逻辑就是执行器要执行的内容。

拿智能合约来说,合约中包含的所有逻辑,就是执行器要执行的逻辑;只不过,合约只是一个具体的逻辑,而执行器则是一个容器,它可以执行数个合约,而不需要知道合约的具体内容。

所以说,执行器模块是一个容器,它支持各种合约的运行(包括系统合约以及各种扩展合约),接收交易,并将交易分配给对应的合约具体执行,同时响应区块链上的各种事件(交易校验、查询请求、执行交易、新增区块、回滚区块),并将事件派发给具体的合约逻辑。

 

2、执行器逻辑架构及上下文

执行器自身能力对外体现为5个接口:

两个只读接口:

1)交易校验:通过EventCheckTx事件触发,对交易的有效性进行检查,请求来源于Mempool模块;

2)查询请求:查询操作,从交易生成的数据中查询指定信息,具体查询内容不固定,因调用的查询方法而异,一般请求来源于Wallet/Client/Consensus模块;

 

三个写接口:

1)交易执行:通过EventExecTxList事件触发,执行交易列表中的每一笔交易,并返回执行结果,请求来源于Blockchain模块;

2)区块新增:通过EventAddBlock事件触发,执行区块写入链的后处理操作,生成一些本地数据并返回,请求来源于Blockchain模块;

3)区块回滚:通过EventDelBlock事件触发,执行链中区块回滚的后处理操作,生成一些本地数据并返回,请求来源于Blockchain模块;

执行器本身是一个容器框架,它本身只包含一些通用的调度处理逻辑,将请求分发给具体的执行器合约进行执行,然后收集结果返回。

从设计上来说,每一个具体的执行器(这里指合约,可以认为两者等价)都实现了Driver中的几个核心方法,容器在执行操作时,会根据交易中附带的执行器信息,调用具体的XXXExecutor执行逻辑。

每一个具体的执行器在实现时均分成两部分:

 

1)执行器对象(XXXExecutor):实现Driver接口,继承DriverBase基类;是执行器的主体,包含执行器的主要执行逻辑,一般根据功能划分成多个程序文件,分别执行对应的逻辑;

2)执行器对象类型(XXXType):实现ExecutorType接口,继承ExecTypeBase基类;包装执行器类型相关的一些通用能力,如方法列表,Payload结构等,辅助执行器框架完成定制化的处理逻辑;

 

 

九、Queue模块

 

 

1、Queue模块介绍

queue 顾名思义,这个模块实现了消息队列的功能。

主要目的是为了降低系统中各个模块的耦合度,引入queue模块后,每个模块相对来说独立,模块之间通信不是通过接口调用,而是通过消息进行传递。这也方便我们日后按模块拆分,为后面各个模块的微服务化做铺垫。

 

2、Queue模块逻辑架构及上下文

1)系统只实例化一个queue,每个模块都实例化了一个queue.client

2)一个queue可以对应多个订阅主题,也就是一个queue可以实例化多个queue.client

3)一个queue.client只能对应一个订阅主题。

4)exector和rpc模块各自都额外实例化一个QueueProtocol

 

>

十、RPC模块

 

 

1、RPC模块介绍

RPC,即 Remote Procedure Call(远程过程调用)

rpc模块主要为外部程序提供交易构造及发送,区块、交易以及其他信息查询接口。

rpc模块同时支持grpc和jsonrpc两种接口,其他进程既可以调用grpc接口,也可以调用jrpc接口,一般地,如果某进程能够访问内部数据结构构造数据,优先采用grpc接口,反之,推荐使用jrpc接口。

 

2、RPC模块逻辑架构及上下文

rpc模块引用了”grpc”和”net/rpc”包,在系统初始化时,注册了服务处理server,对所有的rpc调用方法进行注册。

rpc模块根据配置文件,绑定相应的端口,在底层,实际是对tcp端口进行监听,一旦收到请求消息,根据消息数据里的方法名,调用之前注册的方法进行响应。

rpc模块实例化了一个QueueProtocol,来实现与chain33中其他模块交互,例如实际的区块/交易查询都是通过消息与BlockChain模块交互实现的,关于消息队列可以参考Queue模块介绍。