Skip to content

Commit

Permalink
Merge pull request #1 from vinarmani/2021fix
Browse files Browse the repository at this point in the history
Sync to current blocks + index UTXOs (coins) by address
  • Loading branch information
vinarmani authored Mar 27, 2021
2 parents 81b74a8 + 5405f39 commit 27f2a81
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 168 deletions.
126 changes: 77 additions & 49 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,6 @@ class Chain extends AsyncEmitter {
}
}

// Non-contextual checks.
if (flags & common.flags.VERIFY_BODY) {
const [valid, reason, score] = block.checkBody();

if (!valid)
throw new VerifyError(block, 'invalid', reason, score, true);
}

// Ensure the POW is what we expect.
const bits = await this.getTarget(block.time, prev);

Expand Down Expand Up @@ -425,6 +417,15 @@ class Chain extends AsyncEmitter {
// Get the new deployment state.
const state = await this.getDeployments(block.time, prev);

// Non-contextual checks.
if (flags & common.flags.VERIFY_BODY) {
const [valid, reason, score] = block.checkBody(state.hasPhonon());

if (!valid) {
throw new VerifyError(block, 'invalid', reason, score, true);
}
}

// Get timestamp for tx.isFinal().
const time = state.hasMTP() ? mtp : block.time;

Expand Down Expand Up @@ -755,7 +756,7 @@ class Chain extends AsyncEmitter {

sigops += txSigops;

if (sigops > consensus.maxBlockSigops(block.getSize())) {
if (!state.hasPhonon() && sigops > consensus.maxBlockSigops(block.getSize())) {
throw new VerifyError(block,
'invalid',
'bad-blk-sigops',
Expand Down Expand Up @@ -1919,6 +1920,16 @@ class Chain extends AsyncEmitter {
return this.db.getCoin(hash, index);
}

/**
* Get coins by address (unspents only).
* @param {Address} addr
* @returns {Promise} - Returns {@link Coin}[].
*/

getCoinsByAddress(addr) {
return this.db.getCoinsByAddress(addr);
}

/**
* Retrieve a block from the database (not filled with coins).
* @param {Hash} hash
Expand Down Expand Up @@ -2336,18 +2347,19 @@ class Chain extends AsyncEmitter {
if (pow.noRetargeting)
return prev.bits;

// Asert retargeting activation set to activate on MTP instead of
// Deployment State
const state = await this.getDeployments(time, prev);
if (state.hasAsert()) {
return this.getASERTTarget(time, prev);
}

// Deployment state is not set at this time, so cannot use state.daa just
// yet. Rely on height instead.
if (prev.height >= this.network.block.daaHeight) {
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 @@ -2392,7 +2404,7 @@ class Chain extends AsyncEmitter {
* (target is in compact/mantissa form).
*/

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

if (pow.targetReset) {
Expand All @@ -2404,71 +2416,87 @@ class Chain extends AsyncEmitter {
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);
return this.calculateASERT(prev);
}

/**
* Calculate the next target using the ASERTi3-2d
* algorithm for targeting block intervals.
* @param {ChainEntry} first - First chain entry.
* ***** MAINNET ASERT *****
* asertReferenceBlockBits = 0x1804dafe (402971390)
* asertReferenceBlockHeight = 661647
* asertReferenceBlockAncestorTime = 1605447844
* ***** MAINNET ASERT *****
* ***** TESTNET3 ASERT *****
* asertReferenceBlockBits = 0x1d00ffff
* asertReferenceBlockHeight = 1421481
* asertReferenceBlockAncestorTime = 1605445400
* ***** TESTNET3 ASERT *****
* ***** TESTNET4 ASERT *****
* asertReferenceBlockBits = 0x1d00ffff
* asertReferenceBlockHeight = 16844
* asertReferenceBlockAncestorTime = 1605451779
* ***** TESTNET4 ASERT *****
*
* @param {ChainEntry} last - Last chain entry.
* @returns {Target} - target is in mantissa/compact form.
*/


calculateASERT(first, last) {
assert(last.height >= first.height);
calculateASERT(last) {
const refBlockHeight = 661647;
const refBlockBits = 402971390;
assert(last.height >= refBlockHeight);

const pow = this.network.pow;

const target = consensus.fromCompact(last.bits);
const evalBlockHeight = new BN(last.height);
const evalBlockTime = new BN(last.time);
const ancestorTime = new BN(1605447844);
const timeDiff = evalBlockTime.sub(ancestorTime);

let actualTimespan = last.time - first.time;

let exponent;
let factor;
let shifts;
let target = consensus.fromCompact(refBlockBits);

// Constant variables
const tau = this.network.pow.halfLife;
const halfLife = new BN(172800);
const window = 600;

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

const heightDiff = evalBlockHeight.subn(refBlockHeight);
const heightDiffWithOffset = heightDiff.addn(1);
const targetHeightOffsetMultiple = new BN(window).mul(heightDiffWithOffset);

exponent = new BN(actualTimespan).subn(pow.targetSpacing);
let exponent = new BN(timeDiff).sub(targetHeightOffsetMultiple);
exponent = exponent.shln(16);
exponent = exponent.quo(halfLife);

exponent = exponent.mul(radix).muln(height);
exponent = exponent.quon(tau);
let shifts = exponent.shrn(16);

shifts = exponent.ushrn(16);
exponent = exponent.sub(shifts.shln(16));

exponent = exponent.sub(shifts.mul(radix));
let factor = new BN(195766423245049).mul(exponent);
const stepOne = new BN(971821376).mul(exponent.pown(2));
factor = factor.add(stepOne);
const stepTwo = new BN(5127).mul(exponent.pown(3));
factor = factor.add(stepTwo);
const stepThree = new BN(2).pown(47);
factor = factor.add(stepThree);

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 = factor.shrn(48);

factor = factor.ushrn(48);
factor = factor.add(radix);

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

if (shifts.cmp(EMPTY) < 0) {
target = target.ushrn(shifts.negative);
target = target.shr(shifts.muln(-1));
} else {
target = target.ushl(shifts);
target = target.shl(shifts);
}

target.ushrn(16);
target = target.shrn(16);

// If the target is empty
if (target.cmp(EMPTY) === 0)
Expand Down
37 changes: 37 additions & 0 deletions lib/blockchain/chaindb.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ class ChainDB {
assert(height >= 0);
assert(height <= entry.height);

let isMainchain = await this.isMainChain(entry);
if (await this.isMainChain(entry))
return this.getEntryByHeight(height);

Expand Down Expand Up @@ -903,6 +904,37 @@ class ChainDB {
return coin.toCoin(prevout);
}

/**
* Get coins (unspent only) for an address
* @param {Address} addr
* @returns {Promise} - Returns {@link Coin}[].
*/

async getCoinsByAddress(addr) {

const addrHash = addr.getHash();
const prefix = addr.getPrefix(this.network);

const opts = {
gte: layout.C.min(addrHash),
lte: layout.C.max(addrHash),
parse: (key) => {
const [, hash, index] = layout.C.decode(key);
return [hash, index];
}
};

const prevouts = await this.db.keys(opts);
const coins = [];

for (const [hash, index] of prevouts) {
const coin = await this.getCoin(hash, index);
coins.push(coin);
}

return coins;
}

/**
* Check whether coins are still unspent. Necessary for bip30.
* @see https://bitcointalk.org/index.php?topic=67738.0
Expand Down Expand Up @@ -1481,14 +1513,19 @@ class ChainDB {
saveView(view) {
for (const [hash, coins] of view.map) {
for (const [index, coin] of coins.outputs) {
const addr = coin.output.getAddress();
if (coin.spent) {
this.del(layout.c.encode(hash, index));
if (addr)
this.del(layout.C.encode(addr.getHash(), hash, index));
continue;
}

const raw = coin.toRaw();

this.put(layout.c.encode(hash, index), raw);
if (addr)
this.put(layout.C.encode(addr.getHash(), hash, index), raw);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/mempool/mempool.js
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ class Mempool extends EventEmitter {
*/

getTXByAddress(addr, options) {
return this.addrindex.get(addr, options);
return this.getMetaByAddress(addr, options);
}

/**
Expand Down
Loading

0 comments on commit 27f2a81

Please sign in to comment.