zcash难度调整算法

zcash的难度调整算法在zcash的协议文档(Protocol Specification)p37,6.4.3 Dif culty adjustment中有详细描述,在源码中的实现位于
https://github.com/zcash/zcash/blob/master/src/pow.cpp 的CalculateNextWorkRequired中,由于源码中的实现分散于各个相关文件,现使用C语言集中实现与解释如下

常量定义

static int64_t pow_averaging_window = 17;
static int64_t pow_max_adjust_down = 32;
static int64_t pow_max_adjust_up = 16;
static int64_t pow_target_spacing = 150;
static int pow_median_blockspan = 11;
staic double pow_limit = 0.0;
    if(testnet)
        pow_limit = pow(2, 251) - 1;
    else
        pow_limit = pow(2, 243) - 1;

实现及解释

int64_t get_actual_timespan(uint32_t height)
{
    uint64_t timestamps[11] = {0};
    uint64_t timestamps2[11] = {0};
   //获取前当前块的前11个块及height - pow_averaging_window前11块的中位数(注意是降序排列)时间之差
    get_block_times(height, timestamps);
    get_block_times(height - pow_averaging_window, timestamps2);
    return get_median_time(timestamps) - get_median_time(timestamps2);
}
double get_nextblock_target(bool testnet, uint32_t height)
{
     double mean_target = 0.0;
    if (height <= pow_averaging_window) {
        mean_target = pow_limit;
    } else {
        sds nbits[17];
        //当前块的前17块的难度
        get_block_nbits(height, nbits);
        //求得平均值
        mean_target = get_mean_target(nbits);
    }
   
    int64_t actual_timespan = get_actual_timespan(height);
    int64_t averaging_window_timespan = pow_averaging_window * pow_target_spacing;
    actual_timespan = averaging_window_timespan + (actual_timespan - averaging_window_timespan) / 4;
    int64_t min_actual_timespan = (averaging_window_timespan * (100 - pow_max_adjust_up)) / 100;
    int64_t max_actual_timespan = (averaging_window_timespan * (100 + pow_max_adjust_down)) / 100;
    if (actual_timespan < min_actual_timespan) {
        actual_timespan = min_actual_timespan;
    }
    if (actual_timespan > max_actual_timespan) {
        actual_timespan = max_actual_timespan;
    }

    printf("averaging_window_timespan:%ld, mean_target * actual_timespan:%lf\n", averaging_window_timespan, mean_target * actual_timespan);
    double target  = mean_target * actual_timespan / averaging_window_timespan;
    if (target > pow_limit)
        target = pow_limit;
    printf("target:%lf\n", target);
    return floor(target);
}

数据压缩(会省略后几位非零数字),得到nbit,此时得到的数据才会跟链上的数据相等

至于怎么得到nbits,请查阅
http://www.jianshu.com/p/169458321386

你可能感兴趣的:(zcash难度调整算法)