Skip to content

Commit

Permalink
Merge pull request #13 from rojii/aserti3-2d
Browse files Browse the repository at this point in the history
ASERTi3-2D November 15th Hardfork update
  • Loading branch information
jonajosejg authored Nov 10, 2020
2 parents b5508f3 + 5d38345 commit c9b4d58
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 4 deletions.
125 changes: 123 additions & 2 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*!
* chain.js - blockchain management for bcoin
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License)
* Copyright (c) 2019-2020, Jonathan Gonzalez (MIT License).
* https://github.com/cash-org/cashnode
*/

'use strict';
Expand Down Expand Up @@ -498,6 +499,7 @@ class Chain extends AsyncEmitter {
const deployments = this.network.deployments;
const height = prev.height + 1;
const state = new DeploymentState();
const mtp = await this.getMedianTime(prev);

// For some reason bitcoind has p2sh in the
// mandatory flags by default, when in reality
Expand Down Expand Up @@ -570,6 +572,10 @@ class Chain extends AsyncEmitter {
state.flags |= Script.flags.REPORT_SIGCHECKS;
}

if (mtp >= this.network.block.asertActivationTime) {
state.asert = true;
}

return state;
}

Expand Down Expand Up @@ -617,6 +623,10 @@ class Chain extends AsyncEmitter {
if (!this.state.hasPhonon() && state.hasPhonon())
this.logger.warning('Phonon has been activated.');

if (!this.state.hasAsert() && state.hasAsert())
this.logger.warning('Asert has been activated.');


this.state = state;
}

Expand Down Expand Up @@ -2332,6 +2342,12 @@ class Chain extends AsyncEmitter {
return this.getCashTarget(time, prev);
}

// Asert retargeting activation set to activate on MTP instead of
// Deployment State.
if (prev.time >= this.network.block.asertActivationTime) {
return this.getASERTTarget(time, prev);
}

return this.getEDATarget(time, prev);
};

Expand Down Expand Up @@ -2368,6 +2384,102 @@ class Chain extends AsyncEmitter {
return consensus.toCompact(target);
}

/**
* Calculate the next target using the ASERT algorithm
* @param {Number} time - Next block timestamp.
* @param {ChainEntry} prev - Previous entry.
* @returns {Promise} - returns Number
* (target is in compact/mantissa form).
*/

getASERTTarget(time, prev) {
const pow = this.network.pow;

if (pow.targetReset) {
if (time > prev.time + (pow.targetSpacing * 2))
return pow.bits;
}

// Special behaviour for simnet
if (prev.height < pow.retargetInterval)
return prev.bits;

const height = prev.height + 1;

const first = this.getAncestor(prev, height);
const last = prev;

return this.calculateASERT(first, last);
}

/**
* Calculate the next target using the ASERTi3-2d
* algorithm for targeting block intervals.
* @param {ChainEntry} first - First chain entry.
* @param {ChainEntry} last - Last chain entry.
* @returns {Target} - target is in mantissa/compact form.
*/


calculateASERT(first, last) {
assert(last.height >= first.height);

const pow = this.network.pow;

const target = consensus.fromCompact(last.bits);

let actualTimespan = last.time - first.time;

let exponent;
let factor;
let shifts;

// Constant variables
const tau = this.network.pow.halfLife;
const window = 600;

const height = last.height + 1;
const radix = new BN(65536);
const EMPTY = new BN(0);

exponent = new BN(actualTimespan).subn(pow.targetSpacing);

exponent = exponent.mul(radix).muln(height);
exponent = exponent.quon(tau);

shifts = exponent.ushrn(16);

exponent = exponent.sub(shifts.mul(radix));

factor = new BN(195766423245049).mul(exponent);
factor = factor.add(new BN(971821376));
factor = factor.mul(exponent.sqr());
factor = factor.add(new BN(5127))
factor = factor.mul(exponent.sqr()).mul(exponent);
factor = factor.add(new BN(140737488355328));

factor.ushrn(48);

target.mul(factor).add(radix);

if (shifts.cmp(EMPTY) < 0) {
target = target.ushrn(shifts.negative);
} else {
target = target.ushl(shifts);
}

target.ushrn(16);

// If the target is empty
if (target.cmp(EMPTY) === 0)
return consensus.fromCompact(1);

if (target.cmp(pow.limit) > 0)
return pow.limit;

return consensus.toCompact(target);
}

/**
* Retarget. This is called when the chain height
* hits a retarget diff interval.
Expand Down Expand Up @@ -2873,6 +2985,7 @@ class DeploymentState {
this.greatWallActivation = false;
this.graviton = false;
this.phonon = false;
this.asert = false;
}

/**
Expand Down Expand Up @@ -2983,6 +3096,14 @@ class DeploymentState {
return this.phonon;
}

/**
* Test whether asert update is active.
* @returns {Boolean}
*/

hasAsert() {
return this.asert;
}

/**
* Get max block size
Expand Down
25 changes: 23 additions & 2 deletions lib/protocol/networks.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* network.js - bitcoin networks for bcoin
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
* Copyright (c) 2019-2020, Jonathan Gonzalez (MIT License).
* https://github.com/cash-org/cashnode
*/

'use strict';
Expand Down Expand Up @@ -206,6 +207,15 @@ main.pow = {

bits: 486604799,

/**
* Half Life value used in DAA.
* Represents the value of two days in seconds
* @const {Number}
* @default
*/

halfLife: 172800,

/**
* Minimum chainwork for best chain.
* @const {BN}
Expand Down Expand Up @@ -406,6 +416,12 @@ main.block = {
phononHash:
b('f73075b2c598f49b3a19558c070b52d5a5d6c21fefdf33000000000000000000'),

/**
* Time at which Asert3d-2i was activated.
* November 15, 2020 12:00:00 UTC
*/

asertActivationTime: 1605441600,

/**
* Safe height to start pruning.
Expand Down Expand Up @@ -708,6 +724,7 @@ testnet.pow = {
'00000000000000000000000000000000000000000000006956e7298fb096a1cc',
'hex'
),
halfLife: 172800,
targetTimespan: 14 * 24 * 60 * 60,
targetSpacing: 10 * 60,
retargetInterval: 2016,
Expand Down Expand Up @@ -749,6 +766,7 @@ testnet.block = {
b('5ba3af2992073940ed9e5a9d9eef9194bbfba905d92b202eea44fcff00000000'),

phononActivationTime: 1589544000,
asertActivationTime: 1605441600,
pruneAfterHeight: 1000,
keepBlocks: 10000,
maxTipAge: 24 * 60 * 60,
Expand Down Expand Up @@ -875,6 +893,7 @@ regtest.pow = {
'0000000000000000000000000000000000000000000000000000000000000002',
'hex'
),
halfLife: 172800,
targetTimespan: 14 * 24 * 60 * 60,
targetSpacing: 10 * 60,
retargetInterval: 2016,
Expand All @@ -899,7 +918,8 @@ regtest.block = {
gwaHash: null,
gravitonHeight: 0,
gravitonHash: null,
phononActivationTime: 1589544000,
phononActivationTime: 0,
asertActivationTime: 0,
pruneAfterHeight: 1000,
keepBlocks: 10000,
maxTipAge: 0xffffffff,
Expand Down Expand Up @@ -1029,6 +1049,7 @@ simnet.pow = {
'0000000000000000000000000000000000000000000000000000000000000002',
'hex'
),
halfLife: 172800,
targetTimespan: 14 * 24 * 60 * 60,
targetSpacing: 10 * 60,
retargetInterval: 2016,
Expand Down
10 changes: 10 additions & 0 deletions test/pow-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ describe('Difficulty', function() {
assert.strictEqual(chain.retarget(prev, first), 0x1d00ffff);
});

it('should get an ASERT target', async () => {
const prev = new ChainEntry();
prev.time = 1602486147;
prev.bits = 0x1d00ffff;
prev.height = 1;
const first = new ChainEntry();
first.time = 1602486750;
assert.strictEqual(chain.getASERTTarget(first, prev), 0x1d00ffff);
});

it('should get next work lower limit actual', async () => {
const prev = new ChainEntry();
prev.time = 1279297671;
Expand Down

0 comments on commit c9b4d58

Please sign in to comment.