FruitChain的cpp代码分析[湖南区块链技术社区]

FruitChain C++代码地址: https://github.com/anon4567/fruitchain.git,是基于BitCoin 2016年9 月份的源码修改的。

  1. Block结构调整
参考paper当中定义,在文件 src\primitives\block.h 中,将CBlockHeader和CBlock类调整如下:
CBlockHeader当中增加 h’和digest(F)字段,以及相应的初始化以及序列化修改。
CBlock当中添加 vector表示F (fruits set),只包含了Header信息。

可以看出,Fruit的结构与Block结构是一样的,使用了相同的CBlockHeader。

  1. Fruit Memory Pool
参考交易内存池CTxMemPool定义了类CFrtMemPool用于fruit内存池,具体定义见文件 src\frtmempool.h,其中,用于fruit的存储,使用了一个boost的多关键字索引容器,具体定义如下:

MapFrt容器用于保存fruit,按照frtid排序(也是fruit的hash),可以通过多种方式进行查找,分别是:非唯一索引指向block的高度(pointer_height_fruit)、非唯一索引收到fruit的时间(entry_time_fruit)和唯一索引fruit的hash值(minint_hash_fruit),每个fruit的结构为 CFrtMemPoolEntry,也定义在frtmempool.h当中。

同时在main.cpp当中定义了fruitpool的全局变量:

  1. 数据接收
与标准bitcoin程序一样,通过注册的ProcessMessages函数进行数据的接收与发送,但是在消息类型中增加了对fruit的支持。具体定义在src\protocol.cpp当中:
关于Fruit的消息处理,具体代码见src\main.cpp的ProcessMessage函数:
对于该fruit,调用AcceptToFruitMemoryPool来进行处理:
  • 调用CheckFruit判断该fruit的difficulty是否满足
  • 判断frtmempool当中是否已经存在
  • 判断该fruit指向的block是否是足够近的block,即是否满足freshness要求
在判断freshness的时候,8个之内block满足要求:

  • 判断该fruit是否已经被之前的block打包过了,全局定义的frtmempool_used容器中包含了已经被用过的fruit的信息。
  • 如果以上都满足要求,将其放入frtmempool当中,便于mining模块使用。

  1. 挖矿流程
挖矿具体代码见源文件 src\rpc\mining.cpp和src\miner.cpp。
调用generateBlocks产生新的block,具体流程如下:
  • 创建新的block,通过CreateNewBlock方法
在创建block时,基本参照bitcoin流程,初始化BlockHeader,计算difficulty获取需要计算的0个位数,并通过addFrts将之前收到的fruits放进来
  • 基于block的diffculty计算fruit的difficulty,可以看出这里直接将当前block的difficulty降了100倍作为fruit的difficulty:
  • 开始挖矿流程,核心流程如下所示,将nNonce递增,循环计算block的hash,如果满足block的要求,则block挖成功,如果不成功,再判断是否满足fruit的要求。
  • 挖到新的block后,调用ProcessNewBlock进行块的处理,处理中注意方法AcceptBlock:接受该block并保持到本地,并将该block中包含的fruit信息从frtmempool移至frtmempool_used当中。
同时,继续调用方法ActivateBestChain方法,在将该block添加到chain上时,做出Mining的激励。

  1. Mining的激励

与标准bitcoin的激励方式不同,在调用CreateNewBlock创建新的块时,并没有构造创币交易,即coinbase交易,已经注释掉:

而当挖到block以后,调用ProcessNewBlock将该block添加到chain上时,包含了对于Mining的奖励生成。
调用顺序为:
ProcessNewBlock->ActiveBestChain->ActivateBestChainStep->ConnectTip
->ConnectBlock->CalculateRewardDistribution
最后生成的所以激励交易txChanged,再进行进一步的确认:

下面具体分析激励分配部分,具体代码如下:
首先调用IsTimeToDistributeReward函数,判断是否需要分配,按照设计,它这里每16个块才进行一次激励分配,而且是已经确认的(8个block之前的16个block进行激励分配):
按照注释,分配原则如下:
calculate reward distribution of this episode   total reward S = nfees + GetBlockSubsidy()for each block  let f[i] = number of fruits collected by block i, F = sum f[i]  then for each fruit collected by block j,  its collector get co =(1 - tax + RewardFractionDiff(i))*(1 / F)*S,  its creator get cr = (1 / F) * S – co  additionally:  creator of block i get FEE_FRACTION_C1 * fee[i] for reward  RewardFractionDiff(i) =  REWARD_DIFF_FRACTION_C3 * (1 - (i - 1) / (k - 1))
即:
要分配总奖励:S=所有矿工费 nfees + 这个周期所有block应得奖励总和
f[i] 表示包含于block i中fruits的个数, F = sum f[i],即周期内所有fruit个数

对于每个fruits j,包含它的block 可以得到奖励:
Co = (1 – tax + RewardFractionDiff(i)) * (1 / F) * S
挖到fruit的可以得到奖励:
Cr = (1 / F ) * s – Co

另外,挖到块block i还能得到奖励
FEE_FRACTION_C1 * fee[i]
其中参数
RewardFractionDiff(i) = REWARD_DIFF_FRACTION_C3 * ( 1 – i – 1) / (k – 1)。

根据代码, FEE_FRACTION_C1为1 / 100, REWARD_DIFF_FRACTION_C3为1/100。
具体代码可以自己分析:

猜你喜欢

转载自blog.csdn.net/happyfromtbq/article/details/80585155
今日推荐