EDA与DAA
众所周知,BCH刚从BTC硬分叉出来时,为了能够在较少算力的支持下顺利存活,使用了一个特别的难度调整算法,称为紧急难度调整规则(EDA),关于EDA算法的详细介绍可参见这篇文章《什么是比特现金(BCC)的算力暴击(紧急难度调整)?》,在此不再赘述
EDA出色的完成了其最重要的任务,使bch顺利存活,但随着bch的价值逐渐被大部分人接受,价格随之攀升,与此同时EDA算法的弊端也渐渐被放大:
(1)出块速度极不稳定
(2)算力波动剧烈
(3)bch超发
在得到几大矿池的稳定算力支持后,bch开发团队为了解决以上几个问题,决定使用新的DAA(difficulty adjustment algorithm),这是新算法的官方文档
DAA的原理与实现
下面将对新算法作出解释并给出c语言的实现
(1)新算法将在高度504031开始生效
(2)假设需要得到target_height的目标难度
(3)取(target_height - 1)至 (target - 1 - 2 )这三块的ntime,排序,取ntime在中间的那块为block_last
(4)取(target - 1 - 144)至 (target - 1 - 144 - 2)这三块的ntime,排序,取ntime在中间的那块为block_first
备注:bch的目标是10分钟产生一块,一天产生144块
(5)区块上会纪录一个当前累计工作量(chain_work),通过:
(block_last->chain_work - block_first->chain_work) / (block_last->ntime - block_first->ntime) * 10 * 60 可以得出当前10分钟的算力值work
(6)再通过算力值得出目标难度,该过程详见文章挖矿难度表示
官方源码的实现见GetNextWorkRequired方法, 使用C语言实现如下
double compute_target(struct block_info *block_first, struct block_info *block_last)
{
if (block_last->height <= block_first->height) {
return -__LINE__;
}
uint64_t actual_timespan = (uint64_t)block_last->ntime - (uint64_t)block_first->ntime;
uint32_t pow_target_spacing = 10 * 60
printf("time span:%ld\n", actual_timespan);
if (actual_timespan > 288 * pow_target_spacing) {
actual_timespan = 288 * pow_target_spacing;
} else if (actual_timespan < 72 * pow_target_spacing){
actual_timespan = 72 * pow_target_spacing;
}
double work = block_last->chain_work - block_first->chain_work;
work /= actual_timespan;
work *= pow_target_spacing;
uint8_t target_bin[32] = {0};
get_bin_from_double(work, target_bin);
sds target = bin2hex(target_bin, 32);
printf("work: %s\n", target);
double bigest_num = pow(2, 256);
return bigest_num / work - 1;
}
double get_nextblock_target(bool testnet, uint32_t height)
{
if (height < daa_height) {
return -__LINE__;
}
uint32_t height_prev = height - 1;
if (height_prev < diff_adjustment_inerval) {
return -__LINE__;
}
struct block_info *block_last = get_suitable_block_tail(height_prev);
uint32_t height_first = height_prev - 144;
struct block_info *block_first = get_suitable_block_head(height_first);
double target = compute_target(block_first, block_last);
return target;
}
网友评论