cita横向扩展的问题思考

在cita白皮书中,服务分片是作为亮点和重点突出的部分,就如同官方的这两张设计架构图

每个节点切分了若干个单独服务,各个服务之中通过一个消息总线(在cita代码中所用的是rabbitmq)进行交互,而每个单独的微服务又可以进行横向扩展,比如多个rpc服务,多个Auth服务,多个exector服务等,总之可以动态地增加或者减少单个微服务的服务能力。

然而通读代码之后,发现并非如此,cita现在做到的只是第一步:把节点分析成多个单独服务,这些服务可以在一台机器上,也可以在不同的机器上。

第二步的将单个微服务进行横向扩展,其实是还没有实现的,而且在现在的cita代码的架构上,也不太容易实现,根据rabbitmq的无状态分发特性,如果是多个相同的微服务同时订阅某一类消息,mq会无差别地分发到各个服务中,而不会根据服务状态。比如一个rpc服务启动了三个相同的微服务A,B,C来同时提供rpc服务,A收到了一个请求后,通过mq转发到其它的服务(比如 Auth服务),在Auth处理请求后,将结果放到mq中,这时候因为有A,B,C三个rpc服务同时订阅了这一类消息,所以A不保证会收到处理结果并返回给用户,导致服务的出错。其它的微服务也一样

还有就是Executor服务,在执行evm的时候会对世界状态树进行修改,有多个executor,就代码着有多个evm在执行,而修改世界状态树必需是线性的,并发会造成很多问题,所以理论上evm也不能并行执行合约。executor只能有一个

以现在的cita代码,这些问题都是不容易解决的。但不排除cita团队后续会跟进并解决这些问题, 这是需要对cita架构重新设计的,毕竟这是他们吹过的牛B。

基于CITA链的web3.js

CITA官方版本的web3太简陋,其中也有很多不合理之处。

工作上需要把以太坊上编写好的脚本,拿到cita链上来能直接跑。

于是自己基于web3.js自己实现了一个,也整合了cita的signer,为了和ethereum的web3兼容,里面尽量用了web3.js的变量命名(虽然对于cita链来说不太合理),这样就基本能满足以太坊的脚本作极少的改动就可以跑在cita链上。

github地址:

https://github.com/ijustgoon/sweb3

记一个CITA的bug

同事发现了solidity代码在cita链上运行有个怪异的问题,而同样的代码之前在以太坊链上测试是没有问题的,我第一反应就是难道cita的evm又有bug。

经调查后发现是solidity中的now变量时间不对,在cita链上now返回的时间单位是毫秒,对比了一下,以太坊上now返回的时间单位是秒。

再去查solidity文档,now是返回当前块的时间戳:

now (uint): current block timestamp (alias for block.timestamp)

于是再去对比以太坊和cita块的时间戳,果然发现以太坊出块时的timestamp为 s 为单位,而cita出块时用了 ms 为单位。

这样问题就明了了,只要把cita的block的timestamp改为秒即可。两个地方,一个python脚本生成的genesis,

一个打包块时的timestamp,cita_bft.rs文件中

修改后block的时间戳为秒,但不确定修改会不会对其它模块造成影响,在待详细测试。

问题已提交到cita的issues中

https://github.com/cryptape/cita/issues/192