冲冲冲!!
lizelin 发布的帖子
-
DPOS+PBFT共识算法在区块链中的具体实现
RAW DPOS CONSENSUS ALGORITHM
区块链中的共识算法核心就是解决三个问题
- 谁来产生block
- 何时产生block
- 如何验证block的合法性
DPOS的做法:
- 由当前的排名靠前的委托人列表和当前的时间偏移共同决定。
- 按照固定的时间间隔定期产生。
- 通过block(区块)的时间戳确定合法锻造者,而在PBFT中也说明了通过DIGITAL SIGNATURE的不可篡改性。
DPOS的问题
-
使用时间戳对委托人个数取余的方式,确定当前时间片的锻造者,这增大了出错的可能,如果委托人服务器的时间出现漂移(比如可能是网络问题 或者没有正确配置ntp服务),就会造成网络的分叉,具体可以参考这里[https://github.com/LiskHQ/lisk/issues/82]
-
委托人的权利过高,可能会被滥用,因为DPOS不像POW那样对算力有要求,DPOS的委托人锻造区块不需要算力,他们可以在瞬间锻造出无数区块, 并发往不同的网络节点,导致网络分叉。
对于第一个问题,DPOS没有很好的应对方案,只能寄希望于委托人拥有良好的服务器运维经验,如果他们稍微粗心,就会出现卡块、分叉的危险。 第二个问题,DPOS主要采取的应对方案是对委托人随机排序和最长链同步的方法。最长链同步是最基本的技术,比较常用的是merkel树。
PBFT
加入PBFT后,DPOS算法的前半部分不变,即委托人名单的确定方式和排序算法不变。
变化的是后半部分,即区块的验证和持久化。 区块的验证,不再采用单一的签名验证,而是全节点投票的方式,每当新区块创造出来时,忠诚的节点并不会立即将其写入区块链,而是等待其他节点的投票。 当这个票数超过一定数量后,才进入执行阶段。详见pbft论文《Practical Byzantine Fault Tolerance 》
相对与纯粹的DPOS不会出现很复杂的分叉情况:(所以暂时不用使用merkel树)
- 如果一个正确的节点接受并执行了一个block,那么所有正确的节点都提交相同的block。
- 分叉的正确的节点(极端情况下就是F个)要么落后于最长链,要么与最长链一致,不会出现高度相同但block hash不同的情况。
PBFT结合DPOS在区块链中的具体实现流程
算法流程如下:
- 当前时间片的块的锻造者(DPOS投票结果轮流出块)是此次验证的主节点。假定DPOS委托此节点进行出块的请求,并委任他为此轮共识的主节点。
- 锻造者(主节点)广播pre-prepare消息。<pre-prepare,m,n,i,d,s>,其中m是新区块,n是此轮出块中的出块块序号,i是该节点在此轮出块节点中该节点的序号,d是m的摘要(d=d(m),把byte求hash的过程),s是对摘要的签名
- 其余副本节点第一次收到过这个消息并且验证合法后,就广播一个<prepare,m,n, i,d, s>消息,消息的内容含义和上述一致。
- 所有节点(包括主节点和副本节点)收到prepare消息后,节点开始在内存中累加消息数量,当收到超过2f+1不同节点的相同的prepare消息后,节点则认证块中每一个交易,并在消息m中附上对每一个交易的验证结果,便之后会广播一个<commit, m,n, i,d, s>消息。
- 每个节点收到超过2f+1个不同节点的commit消息后,就认为该区块已经基本达成一致,进入通过状态,并将块中可以通过的交易打包成块,转换成不可逆转的固定块。
- 主节点或者副本节点在收到某一个消息时,启动一个定时器,当定时到期后,如果还没达成一致,就放弃本次共识,丢弃。
需要说明的是,本算法与PBFT论文中的算法有所不同。一个是取消了commit-local的状态,另一个是没有视图变化的过程。因为PBFT最初提出来主要是面向的一般的C-S架构的服务系统,服务器对与客户端的每一个请求都要有所响应,但是在区块链系统中,区块的生成是可以延迟到下一个时间片的,而且这种延迟很常见,这跟视图变化本质上是一样的,每一个时间片相当于一个视图,slot = time_offset / interval,这个slot就相当于视图编号。
算法复杂度:
假设系统中总共有N个节点,包括超级节点(有出块资格,有被选举、委托权)和轻节点(没有被选举权,只能对超级节点进行投票的节点)。系统P2P广播的时间复杂度为N,假如普通节点只接收不广播,那么N可以降为委托人的节点总数n,因为系统中委托人数量一定时期内保持不变,可以认为一次广播的时间开销为常数t。确认一个block需要3轮广播,也就是总时间为3t。 block消息大小设为B,prepare和commit的消息大小设为b,那么总共的带宽消耗为(B+2b)N。(非常初略的计算,看看就行)
-
RE: 李泽霖的工作日志
时间:2019.7.7-2019.7.14
工作时长:35h
工作内容:- dpos+pbft的实现,看了一波pbft的论文和相关的。
- 转账结构的修改。
下周计划
- 看algorand论文
- 在aos里面测试,fongle
-
PBFT共识算法
PBFT共识算法
实用的拜占庭容错算法
BFT 是区块链共识算法中,需要解决的一个核心问题。比特币的POW,eos的dpos,以及共识算法pos,这些公链算法,解决的是共识节点众多情况下的bft问题。bft问题
拜占庭将军问题。也称为拜占庭容错。
用来描述分布式系统一致性问题。背景如下:
拜占庭帝国想要进攻一个强大的敌人,为此派出了10支军队去包围这个敌人。这个敌人虽不比拜占庭帝国,但也足以抵御5支常规拜占庭军队的同时袭击。这10支军队在分开的包围状态下同时攻击。他们任一支军队单独进攻都毫无胜算,除非有至少6支军队(一半以上)同时袭击才能攻下敌国。他们分散在敌国的四周,依靠通信兵骑马相互通信来协商进攻意向及进攻时间。困扰这些将军的问题是,他们不确定他们中是否有叛徒,叛徒可能擅自变更进攻意向或者进攻时间。在这种状态下,拜占庭将军们才能保证有多于6支军队在同一时间一起发起进攻,从而赢取战斗?单从上面的说明可能无法理解这个问题的复杂性,我们来简单分析一下:
先看在没有叛徒情况下,假如一个将军A提一个进攻提议(如:明日下午1点进攻,你愿意加入吗?)由通信兵通信分别告诉其他的将军,如果幸运中的幸运,他收到了其他6位将军以上的同意,发起进攻。如果不幸,其他的将军也在此时发出不同的进攻提议(如:明日下午2点、3点进攻,你愿意加入吗?),由于时间上的差异,不同的将军收到(并认可)的进攻提议可能是不一样的,这是可能出现A提议有3个支持者,B提议有4个支持者,C提议有2个支持者等等。
再加一点复杂性,在有叛徒情况下,一个叛徒会向不同的将军发出不同的进攻提议(通知A明日下午1点进攻, 通知B明日下午2点进攻等等),一个叛徒也会可能同意多个进攻提议(即同意下午1点进攻又同意下午2点进攻)。
叛徒发送前后不一致的进攻提议,被称为“拜占庭错误”,而能够处理拜占庭错误的这种容错性称为「Byzantine fault tolerance」,简称为BFT。
pbft算法
使用密码学算法保证节点之间的消息传送是不可篡改的,通过下面的算法我们可以保证A将军收到B将军发来的消息确实是B将军本人的真实请求。
我们采用的是哈希函数(散列算法)SHA256 -- 从数据(byte)值中创建独一无二的hash值,并压缩成摘要,将数据格式固定下来。通过这个摘要与个人私钥生成Digital Signature 和个人公钥Public-key certificate,接收方验证签名和摘要,如果是通过验证,即证明摘要内容没有经过篡改。
pbft容忍无效或者恶意节点数量 e 。为了保证整个系统可以正常运作,需要有2f+1个正常节点,系统的总结点数为 :3f+1。即pbft算法容忍小于1/3的恶意或者无效节点。原因见节点作恶的极端情况
pbft是一种状态机副本复制算法,所有副本在一个view轮换过程中操作,哪些是主节点(进攻的提议者的大将军们,轮流当)通过view中其他节点(其他将军)赋予的编号和节点数集合来确定,即:主节点p=v mod |R| 。 v:view编号,|R|节点个数,p:主节点编号。关于状态机复制算法、view change的意义(主要是防止主节点作恶),主节点详见论文。
算法概述:
基于拜占庭将军问题,PBFT算法一致性的确保主要分为这三个阶段:预准备(pre-prepare)、准备(prepare)和确认(commit)。流程如下图所示:
首先解释一下上面各个符号表达的意思:
- C表示客户端;
- 0,1,2,3表示4个节点;
- 0在这里为主节点,1,2,3为副本节点;(注意,这里其他节点也可以作为主节点,若0发生错误只能由服务器监测。如果服务器在一段时间内不能完成客户端的请求,则会触发视图更换协议,将其他副本节点换为主节点)
- 3为故障节点;
下面结合上图,详细说一下PBFT的步骤:
- Request:请求端C发送请求到主节点,这里是0节点;
- Pre-Prepare:节点0收到C的请求后进行广播,扩散至123;
- Prepare:123节点收到后记录并再次广播,1->023,2->013,3因为宕机无法广播(这一步是为了防止主节点作恶,给不同副本节点发送不同的请求,所以所有副本节点都进行一次广播)
- Commit:0123节点在Prepare阶段,若收到超过一定数量(>2F,实际使用中,F为可以容忍的拜占庭节点个数)的相同请求,则进入Commit阶段,广播Commit请求;
- Reply:0123节点在Commit阶段,若其中有一个收到超过一定数量(2F+1)的相同请求,则对C进行反馈;
根据上述流程,在 N ≥ 3F + 1 的情況下一致性是可能解決,N为总计算机数,F为有问题的计算机总数。
算法具体流程
下面所有的校验流程略去对消息内容、签名和身份的验证,即已经保证了节点之间消息传播是不可篡改的
-
请求:
-
将军C向主节点发送请求,主节点收到请求。
-
消息格式:
<REQUEST, o, t, c>
o: 请求的具体操作,t: 请求时客户端追加的时间戳,c:客户端标识。REQUEST: 包含消息内容m,以及消息摘要d(m)。
-
-
主节点收到(客户端发送或者存活的非主节点广播)请求,第一阶段认证准备:pre-prepare
-
验证请求是否非法。
-
如果合法,执行下面操作:
-
对每一个请求分配编号n,每一个请求都有一个编号。然后广播消息给其他副本节点:
-
<<PRE-PREPARE, v, n, d>, m>
v:视图编号,d客户端消息摘要,m消息内容。
-
-
n要在某一个区间内的[h,H]。
- 这是为了确保在view切换过程中,能够恢复之前的请求,具体流程见后头的垃圾回收环节
-
-
副本节点收到消息,第二阶段认证准备:prepare
副本节点i收到主节点发来的pre-prepare消息,进行如下校验:
-
副本节点i(自己)是否曾经收到了一条在同一个view下并且编号也是n,但是签名不一样的pre-prepare消息。如果有,这条新的消息就是非法的。
-
d、m摘要保持一致,不一致则是非法的。
-
n是否在区间[h,H]之间,如果不是,则非法。
非法则丢弃
-
对正确消息的处理:
-
副本节点向其他所有节点(包括主节点和副本节点)发送(广播)一条消息:
-
<PREPARE, v, n, d, i>
其中v, n, d与收到的pre-prepare消息内容一致,i则为副本节点的编号。
-
并记录pre-prepare、prepare消息到log中,用于view change过程中恢复未完成的请求操作。
-
-
-
对prepare消息的确认和提交 ,第三阶段认证阶段:commit
主节点和副本节点收到prepare消息,进行如下校验:
- 当前副本节点是否已经收到了同一个view下的pre-prepare消息n,没有则非法。
- n是否在区间[h,H]中,不在则非法。
- d是否与当前存储的pre-prepare消息的d一致,不一致则非法。
- 如果副本节点i收到了2f+1个验证通过的prepare消息,则向其他所有节点(包括主节点和副本节点)发送(广播)一条消息:
- <COMMIT, v, n, d, i>
- 其中v, n, d与上述PREPARE消息内容相同,i则是自己的标识。
- 记录commit消息到log记录中,用view change过程中恢复未完成的请求操作,记录其他副本节点发送的prepare消息到log记录中。
-
对commit消息的回复,第四回复确认阶段(最后):reply
- 当前副本节点i是否已经收到同一view下的prepare消息n,没有收到的话判定为非法。
- d和m的摘要是否一致,不一致判定为非法。
- n是否在区间[h,H]内,不在的判定为非法。
- 如果副本节点i收到了2f+1个经过上述验证的commit消息,说明当前网络中的大部分节点已经达成共识,运行客户端的请求o,并返回回复消息给客户端。消息格式如下:
- <REPLY, v, t, c, i, r>,r:是请求操作结果。
- 客户端如果收到2f+1个相同的reply消息,说明客户端发起的请求已经达成全网共识,否则客户端需要判断是否重新发送该请求,请求链上重新进行验证。
- 同时此时记录其他副本节点发送的commit消息到log中。
垃圾回收环节
上述算法中,比较重要的一个点是view change,为了能恢复之前的请求,每一个副本节点收到消息之后或者发送消息的时候都会记录消息到本地的log记录中。当执行请求后,副本节点需要把之前该请求的记录消息清除掉。最简单的做法是在reply消息后,在执行一次当前状态的共识同步,但是为了节省资源,一般在多条请求K后执行一次状态同步。这个状态同步就是checkpoint消息。
checkpoint详细解释:
为了节省内存,系统需要一种将日志中的无异议消息记录删除的机制。为了保证系统的安全性,副本节点在删除自己的消息日志前,需要确保至少f+1个正常副本节点执行了消息对应的请求,并且可以在视图变更时向其他副本节点证明。另外,如果一些副本节点错过部分消息,但是这些消息已经被所有正常副本节点删除了,这就需要通过传输部分或者全部服务状态实现该副本节点的同步。因此,副本节点同样需要证明状态的正确性。
在每一个操作执行后都生成这样的证明是非常消耗资源的。因此,证明过程只有在请求序号可以被某个常数(比如100)整除的时候才会周期性地进行。我们将这些请求执行后得到的状态称作检查点(checkpoint),并且将具有证明的检查点称作稳定检查点(stable checkpoint)。
流程:
- 副本节点i发送checkpoint消息给其他节点,消息格式如下:
- <CheckPoint, n, d, i>
- n是当前节点所保留的最后一个视图请求编号,d是对当前状态的一个摘要。
- 如果副本节点i收到了2f+1个验证过的checkpoint消息,则清除之前日志中的消息,并以收到的n作为当前一个stable checkpoint
上述情况是理想情况,实际上当副本节点i向其他节点发出checkpoint消息之后,其他节点还没有完成K条请求的相互共识,所以不会立即对i的请求作出响应。其他节点会按照自己的处理步骤和顺序,向前行进和共识。但是此时i发出的checkpoint没有形成stable,为了防止i太快,超过自己太多,于是被便会设置一个高水位H=h+L,其中L就是我们指定允许的高度差,等于checkpoint周期处理数K的整数倍,可以设置为L=2K。当副本节点i处理请求超过高水位H时,副本节点即使接受到请求也会视为非法请求。等待stable checkpoint发生变化,再继续向前推进处理。
View Change
如果主节点作恶,它可能会给不同的请求编上相同的序号,或者不去分配序号,或者让相邻请求的序号不连续。备份节点(备份主节点)应当有职责来主动检查这些序号的合法性。如果主节点掉线或者作恶不广播客户端的请求,客户端设置超时机制,超时的话,向所有副本节点广播请求消息。副本节点检测出主节点或者下线,发起view change流程。
流程:
- 副本节点向其他节点广播消息:
- <view-change, v+1,n,C,P,i>
- n是最新的stable checkpoint的编号,C是2f+1验证过的checkpoint消息集合,P是当前副本节点未完成的请求的pre-prepare和prepare的消息集合。
- 当主节点p=v+1 mod |R|收到2f个有效的view-change消息后,向其他节点广播消息,消息格式如下:
- <new-view,v+1,V,O>
- V是有效的view-change消息的集合。O是主节点重新发起的未完成的pre-prepare消息集合。pre-prepare消息集合的选取规则:
- 选取V中最小的stable checkpoint编号min-s,选取V中prepare消息的最大编号max-s。
- 在min-s和max-s之间,如果P消息集合在这个区间,则创建pre-prepare消息并广播:
- <<pre-prepare,v+1,n,d>,m>格式和之前的pre-prepare格式一致
- 如果不在这个区间,则创建空的pre-prepare:
- <<PRE-PREPARE, v+1, n, d(null)>, m(null)>, m(null)空消息,d(null)空消息摘要。
- 副本节点收到主节点的new-view消息,验证有效性。有效的话进入v+1消息,并且开始处理O中的pre-prepare消息(即生成prepare消息)
节点作恶的极端情况
我们在上面讲到,当网络中有F台有问题的计算机时,至少需要3F+1台计算机才能保证一致性问题的解决,我们在这里讨论一下原因。
我们可以考虑:由于有F个节点为故障或被攻击的节点,故我们只能从N-F个节点中进行判断。但是由于异步传输,故当收到N-F个消息后,并不能确定后面是否有新的消息。(有可能是目前收到的N-F个节点的消息中存在被攻击的节点发来的消息,而好的节点的消息由于异步传输还没有被收到。)
我们考虑最坏的情况,即剩下F个都是好的节点,收到的中有F个被攻击的节点,故我们需要使得收到的中好节点的数量**(N-F)-F大于被攻击节点的数量F**,于是有N-2F>F,即N>3F,所以N的最小整数为N=3F+1。
总览:
pbft是需要参与认证的节点进行的。所以一个完整的共识算法包括DPOS+PBFT。其速度是可以达到1500tps左右的。
参考文献:
https://mathpretty.com/9602.html
https://blog.csdn.net/jfkidear/article/details/81275974
Practical Byzantine Fault Tolerance
Miguel Castro and Barbara Liskov Laboratory for Computer Science, Massachusetts Institute of Technology, 545 Technology Square, Cambridge, MA 02139 castro,liskov @lcs.mit.edu
-
分布式系统(数据库)实现中的CAP原则和ACID原则
在学习分布式数据库和编写区块链超级账本的同步过程中,CAP原则(强一致性,可用性,分区容忍性)和ACID原则是我们必须考虑的问题
CAP原则
Consistency, Availability, Partition Tolerance
定义
-
强一致性: 在分布式系统中(分布式数据库)同一个数据存在多个副本,每台机器都维护自己的账本,我们需要保证外部用户访问的时候,对于数据库的增删读写操作和集中式数据库是一样的。(外面的人看来数据只有一份)
-
可用性: 外部用户(客户端)在使用我们分布式数据库的增删读写操作应该在一定时间内完成,应该是人类可以接受的速度。起码不能一个操作花一分钟吧?
-
分区容忍性: 在大规模的分布式数据库中,必须能保证在同一片区域的服务器全部宕机的情况下,不影响整体的功能和使用。
对于一个大规模分布式数据系统来说,CAP三要素是不可兼得的,同一系统至多只能实现其中的两个,而必须放宽第3个要素来保证其他两个要素被满足。一般在网络环境下,运行环境出现网络分区是不可避免的,所以系统必须具备分区容忍性(P)特性,所以在一般在这种场景下设计大规模分布式系统时,往往在A或者C中选择一个进行舍弃。
分布式数据库下三者不可兼得
上述分布式数据库中,必须保证可用性,所以分区容忍性必须优先。那么consistency和availability就是不能相互兼容得了了。如果要加快用户的操作速度,就必须牺牲一致性(即同步的速度,而不会出现数据完全不一样的问题)。
情况一
如果这个分布式系统中数据没有副本,那么系统必然满足强一致性,因为只有孤本数据,不会出现数据不一致的问题,此时C、P都满足,但是这是不符合分布式数据库的要求的。一旦这些孤本数据所在的机器宕机了,那么数据库就崩了。
情况二
如果在分布式系统(数据库)中数据有多个副本,那么某些服务器宕机,整个分布式系统还是可以正常服务,这里满足Availability,但是副本之间不能保证实时的一致,所以损害了Consistency原则。(有可能导致用户获得的数据是过时的,旧的,不准确的)
总结
所以一般情况下,会根据具体业务来侧重于C或者A,对于一致性要求比较高的业务,那么对访问延迟时间要求就会低点;对于访问延时有要求的业务,那么对于数据一致性要求就会低点。一致性模型主要可以分为下面几类:强一致性、弱一致性、最终一致性、因果一致性、读你所写一致性、会话一致性、单调读一致性、以及单调写一致性,所以需要根据不同的业务选择合适的一致性模型。
ACID原则
ACID是关系型数据库系统采纳的原则,其代表的含义分别是:Atomicity,Consistency,Isolation,Durability。
Atomicity原子性
一个事务要么完全执行,要么就不开始执行。在GO中可以用互斥锁或者channel来保证这个事情。
Consistency一致性
事务开始和结束的时候,要始终满足一致性的约束。即保证数据是符合某一个标准的,不会出现改了某个数据,造成另外数据的紊乱。比如系统要求A+B=100,那么事务如果改变了A的数值,则B的数值也要相应修改来满足这样一致性要求。
Isolation事物的独立性
如果有多个事物同时执行,彼此之间不需要知晓对方的存在,而且执行时互不影响,事务之间需要序列化执行,有时间顺序。这里相当于异步操作,在GO中可以用多线程来完成。
Durability持久性
事务的持久性是指事务执行成功以后,对系统状态的更新是永久的,不会无缘无故回滚撤销。
以上原则对于分布式数据库,区块链中的超级账本有比较重要的指导作用。当讨论实现方法的时候,会有折中的问题,这时候就应该上升到这些理论的原则分类问题。只有在充分讨论开发的系统侧重之后,并结合上述原则来实现系统的功能,才能最大程度保证系统的稳定性和可用性。
-
-
RE: 李泽霖的工作日志
时间:2019.6.22-2019.6.29
工作时长:25h
工作内容:- API签名验证的添加。
- 广播和接受同步时候的签名验证功能,确保同步的安全性,防止恶意节点篡改链上信息
需要添加签名的地方:
交易池同步,区块确认的prepare,preprepare , commit, 待审批节点表的同步,区块的广播
-
RE: 李泽霖的工作日志
时间:2019.6.15-2019.6.22
工作时长:45h
工作内容:
- 修改上传文件合约的确认API
- 完成申请成为全节点的API,包括签名认证、链上同步、查询等功能
- 重构了合约确认的结构
-
常用的git命令,记录一下
以下内容在git GUI都有,但是每次换一个环境要装GUI也不现实,所以还是习惯用命令行吧
参考https://www.git-scm.com/book/zh/v2
使用前配置
-
git config --global user.name "chiellini"
-
git config --global user.email "18319277690@163.com"
设置默认记住密码
- git config --global credential.helper store
检查状态
- git status
- git diff
- git diff --staged 查看已经暂存的
查看历史和版本
- git log
- git log -p -2 最近两个版本
- git log --stat 简要列出每次提交修改的文件
可以补充commit
git add forgotten_file $ git commit --amend 并和远处同步
- git reset --hard origin/develop
取消本地修改
- git checkout .
查看所有分支
- git branch -a
- git checkout -b 本地分支名字 上面获得的远程分支全名
合并
- git merge your_tmp_branch
冲突
在不同分支中,对同一个文件的同一个部分进行了不同的修改,git就没法干净的合并他们会报错
Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.
打开没有合并的文件,像下面
<<<<<<< HEAD:index.html <div id="footer">contact : email.support@github.com</div> ======= <div id="footer"> please contact us at support@github.com </div> >>>>>>> iss53:index.html
现在就修改,选择你要的那部分就可以
选择完之后
git add <>
git commit
git push只在一条分支上做开发,然后又冲突了的,某一方保存自己的修改文件,直接回退到远程版本(或者新建分支再参考上述合并)
git reset --hard origin
.gitignore
忽略二进制或者无用文件.gitignore在git根目录下
使得ignore生效必须先清空git缓存器中具体命令如下
危险命令!谨慎使用!
-
git rm -r --cached . -f
-
git add .
-
git commit -m "update .gitignore"
看一个例子就明白了
我们再看一个 .gitignore 文件的例子: # no .a files *.a # but do track lib.a, even though you're ignoring .a files above !lib.a # only ignore the TODO file in the current directory, not subdir/TODO /TODO # ignore all files in the build/ directory build/ # ignore doc/notes.txt, but not doc/server/arch.txt doc/*.txt # ignore all .pdf files in the doc/ directory doc/**/*.pdf
-
-
李泽霖的工作日志
时间:2019.5.18-2019.5.25
工作时长:25h
工作内容:- 尝试调试KODO的编译,使用waf编译的时候出现了阻碍。
- 把之前的代码在PLAN9上运行,把该系统与真机相连并测试。
时间:2019.5.5-2019.5.12
工作时长:45h
工作内容:- 讨论区块链整体架构,确认文档
- 写shell脚本自动遍历所有测试节点的信息,验证是否一致
- 强哥http模块代码熟悉
时间:2019.4.28-2019.5.4
工作时长:10h
工作内容:- 学习golang语言,看强哥代码。
- 结合kvm和tmux在ovs上继续尝试搭建蝴蝶拓扑的结构,证明它的性能和丢包率好于没有进行网络编码的时候。(争取下周弄完吧...)