zcash難易度調整アルゴリズム

2505 ワード

zcashの難易度調整アルゴリズムはzcashのプロトコル文書(Protocol Specification)p 37,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
", 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
", target); return floor(target); }

データ圧縮(後数桁のゼロ以外の数字を省略)してnbitを得ると、チェーン上のデータと等しくなります.
nbitsの入手方法については、http://www.jianshu.com/p/169458321386