Page MenuHomePhabricator

Implement weighted-time difficulty adjustment algorithm
AbandonedPublic

Authored by deadalnix on Oct 22 2017, 15:20.

Details

Reviewers
kyuupichan
dgenr8
Group Reviewers
Restricted Owners Package(Owns No Changed Paths)
Restricted Project
Summary

This weighted-time DAA uses a 144-block sliding window and applies two weights to the individual inter-block times before retargeting.

Difficulty weight
To correct for the difficulty at which the block was mined, its time is multiplied by the ratio of its target to the final block's target.

Recency weight
Each blocktime is weighted by its sequence within the window, starting at 1 with the oldest block.

Test Plan

make check
A testnet effort is planned.
Extensive simulations have been done and continue. The simulation's python implementation temporarily remains as comments to aid review.

Diff Detail

Repository
rABC Bitcoin ABC
Branch
wt-144
Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 1029
Build 1029: arc lint + arc unit

Event Timeline

dgenr8 created this revision.Oct 22 2017, 15:20
Owners added a reviewer: Restricted Owners Package.Oct 22 2017, 15:20
Herald added a reviewer: Restricted Project. · View Herald TranscriptOct 22 2017, 15:20
dgenr8 retitled this revision from Imlplement weighted-time difficulty adjustment algorithm to Implement weighted-time difficulty adjustment algorithm.Oct 22 2017, 16:08
dgenr8 edited the test plan for this revision. (Show Details)
dgenr8 edited the summary of this revision. (Show Details)Oct 22 2017, 16:19
dgenr8 edited the test plan for this revision. (Show Details)
dgenr8 edited the test plan for this revision. (Show Details)
kyuupichan requested changes to this revision.Oct 22 2017, 21:51
kyuupichan added a subscriber: kyuupichan.
kyuupichan added inline comments.
src/pow.cpp
200 ↗(On Diff #1600)

I don't think the division is good here - as it's integer division it doesn't have sufficient granularity. Do we not want ((time_i * target_i) / last_target).GetLow64() - that matches the Python.

The rest looks good to me.

This revision now requires changes to proceed.Oct 22 2017, 21:51
kyuupichan added inline comments.Oct 22 2017, 22:11
src/pow.cpp
200 ↗(On Diff #1600)

On regtest there is only 1 bit of room in the targets. So how about:

const uint32 DIFF_WEIGHT_PRECISION = 1000000;
last_target /= DIFF_WEIGHT_PRECISION; // outside the loop

uint32_t adj_time_i = time_i * ((target_i / DIFF_WEIGHT_PRECISION) / last_target).GetLow64();

dgenr8 added inline comments.Oct 22 2017, 22:13
src/pow.cpp
200 ↗(On Diff #1600)

Looks good except we need a temporary rather than updating last_target. Will do.

kyuupichan added inline comments.Oct 22 2017, 22:14
src/pow.cpp
200 ↗(On Diff #1600)

Sorry

uint32_t adj_time_i = ((time_i * (target_i / DIFF_WEIGHT_PRECISION)) / last_target).GetLow64();

dgenr8 updated this revision to Diff 1601.Oct 22 2017, 22:53
dgenr8 edited edge metadata.

Use 6-digit precision for 256-bit ratio

dgenr8 updated this revision to Diff 1602.Oct 23 2017, 05:19

Add unit test

dgenr8 edited the test plan for this revision. (Show Details)Oct 23 2017, 15:31
dgenr8 edited the summary of this revision. (Show Details)
Mengerian added inline comments.
src/pow.cpp
203 ↗(On Diff #1602)

I notice that it divides by last_target inside the loop, then multiplies the result by last_target outside the loop.

Seems like the calculations could be done more efficiently removing the division inside the loop (and the subsequent multiplication outside)

dgenr8 added inline comments.Oct 28 2017, 01:00
src/pow.cpp
203 ↗(On Diff #1602)

Great catch. This will also remove the need for fixed precision, we'll just need to accumulate in a 256-bit var.

dgenr8 updated this revision to Diff 1609.Oct 28 2017, 02:01
dgenr8 updated this revision to Diff 1611.Oct 29 2017, 00:52
deadalnix commandeered this revision.Jan 21 2018, 13:16
deadalnix abandoned this revision.
deadalnix added a reviewer: dgenr8.