Skip to content

Commit

Permalink
Merge PR #819 from 'nodech/icann-lockup'
Browse files Browse the repository at this point in the history
  • Loading branch information
nodech committed Jun 21, 2023
2 parents aefc311 + d951f72 commit 90cdf84
Show file tree
Hide file tree
Showing 30 changed files with 1,319 additions and 71 deletions.
51 changes: 37 additions & 14 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ const {CriticalError} = require('../errors');
const thresholdStates = common.thresholdStates;
const {states} = NameState;

const {
VERIFY_COVENANTS_HARDENED,
VERIFY_COVENANTS_LOCKUP
} = rules.nameFlags;

/**
* Blockchain
* @alias module:blockchain.Chain
Expand Down Expand Up @@ -201,10 +206,9 @@ class Chain extends AsyncEmitter {
assert(state);

const view = new CoinView();
const hardened = state.hasHardening();

for (const tx of block.txs)
await this.verifyCovenants(tx, view, height, hardened);
await this.verifyCovenants(tx, view, height, state.nameFlags);

// If the chain replay crosses a tree interval, it will commit
// and write to disk in saveNames(), resetting the `txn` like usual.
Expand Down Expand Up @@ -699,7 +703,11 @@ class Chain extends AsyncEmitter {

// Disable RSA-1024.
if (await this.isActive(prev, deployments.hardening))
state.hardening = true;
state.nameFlags |= rules.nameFlags.VERIFY_COVENANTS_HARDENED;

// Disable ICANN, TOP100 and CUSTOM TLDs from getting auctioned.
if (await this.isActive(prev, deployments.icannlockup))
state.nameFlags |= rules.nameFlags.VERIFY_COVENANTS_LOCKUP;

return state;
}
Expand All @@ -721,6 +729,9 @@ class Chain extends AsyncEmitter {
if (this.height === this.network.deflationHeight)
this.logger.warning('Name claim deflation has been activated.');

if (!this.state.hasICANNLockup() && state.hasICANNLockup())
this.logger.warning('ICANN lockup has been activated.');

this.state = state;
}

Expand All @@ -733,7 +744,6 @@ class Chain extends AsyncEmitter {
*/

async updateInputs(block, prev, state) {
const hardened = state.hasHardening();
const view = new CoinView();
const height = prev.height + 1;

Expand All @@ -749,7 +759,7 @@ class Chain extends AsyncEmitter {
'BUG: Spent inputs in historical data!');
}

await this.verifyCovenants(tx, view, height, hardened);
await this.verifyCovenants(tx, view, height, state.nameFlags);

view.addTX(tx, height);
}
Expand Down Expand Up @@ -777,7 +787,6 @@ class Chain extends AsyncEmitter {

async verifyInputs(block, prev, state) {
const network = this.network;
const hardened = state.hasHardening();
const view = new CoinView();
const height = prev.height + 1;
const interval = network.halvingInterval;
Expand Down Expand Up @@ -854,7 +863,7 @@ class Chain extends AsyncEmitter {
}

// Verify covenants.
await this.verifyCovenants(tx, view, height, hardened);
await this.verifyCovenants(tx, view, height, state.nameFlags);

// Add new coins.
view.addTX(tx, height);
Expand Down Expand Up @@ -961,14 +970,14 @@ class Chain extends AsyncEmitter {
* @param {TX} tx
* @param {CoinView} view
* @param {Number} height
* @param {Boolean} hardened
* @param {NameFlags} nameFlags
*/

async verifyCovenants(tx, view, height, hardened) {
async verifyCovenants(tx, view, height, nameFlags) {
assert(tx);
assert(view instanceof CoinView);
assert((height >>> 0) === height);
assert(typeof hardened === 'boolean');
assert(typeof nameFlags === 'number');

const {types} = rules;
const network = this.network;
Expand Down Expand Up @@ -1055,7 +1064,7 @@ class Chain extends AsyncEmitter {
// any weak algorithms (i.e. RSA-1024).
// Any future emergency soft-forks should
// also be included below this check.
if (hardened && weak) {
if ((nameFlags & VERIFY_COVENANTS_HARDENED) && weak) {
throw new VerifyError(tx,
'invalid',
'bad-claim-algorithm',
Expand Down Expand Up @@ -1160,6 +1169,16 @@ class Chain extends AsyncEmitter {
100);
}

// Make sure locked up names are not opened if ICANN LOCKUP has
// activated.
const isLockUpActive = nameFlags & VERIFY_COVENANTS_LOCKUP;
if (isLockUpActive && rules.isLockedUp(nameHash, height, network)) {
throw new VerifyError(tx,
'invalid',
'bad-open-lockedup',
100);
}

// On mainnet, names are released on a
// weekly basis for the first year.
if (!rules.hasRollout(nameHash, height, network)) {
Expand Down Expand Up @@ -1307,7 +1326,7 @@ class Chain extends AsyncEmitter {
// registrar's keys are compromised.
if (ns.isClaimable(height, network)) {
// Soft-fork #1 (RSA hardening).
if (hardened && ns.weak) {
if ((nameFlags & VERIFY_COVENANTS_HARDENED) && ns.weak) {
throw new VerifyError(tx,
'invalid',
'bad-register-state',
Expand Down Expand Up @@ -3942,11 +3961,15 @@ class DeploymentState {
this.tip = tip;
this.flags = Script.flags.MANDATORY_VERIFY_FLAGS;
this.lockFlags = common.lockFlags.MANDATORY_LOCKTIME_FLAGS;
this.hardening = false;
this.nameFlags = rules.nameFlags.MANDATORY_VERIFY_COVENANT_FLAGS;
}

hasHardening() {
return this.hardening;
return (this.nameFlags & VERIFY_COVENANTS_HARDENED) !== 0;
}

hasICANNLockup() {
return (this.nameFlags & VERIFY_COVENANTS_LOCKUP) !== 0;
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/blockchain/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ exports.lockFlags = {};
* @default
*/

exports.lockFlags.MANDATORY_LOCKTIME_FLAGS = 0;;
exports.lockFlags.MANDATORY_LOCKTIME_FLAGS = 0;

/**
* Standard locktime flags (used for mempool validation).
Expand Down
10 changes: 6 additions & 4 deletions lib/covenants/ownership.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,6 @@ class Ownership extends BNSOwnership {
}
}

Ownership.Proof = Proof;
Ownership.OwnershipProof = Proof;

/**
* ProofData
*/
Expand Down Expand Up @@ -291,4 +288,9 @@ ownership = new Ownership();
* Expose
*/

module.exports = ownership;
module.exports = Ownership;

Ownership.Proof = Proof;
Ownership.OwnershipProof = Proof;
Ownership.ProofData = ProofData;
Ownership.ownership = ownership;
5 changes: 4 additions & 1 deletion lib/covenants/reserved-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ class Reserved {
hash,
target,
value,
root
root,
top100,
custom,
zero
};
}

Expand Down
5 changes: 4 additions & 1 deletion lib/covenants/reserved.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,10 @@ class Reserved {
hash,
target,
value,
root
root,
top100,
custom,
zero
};
}

Expand Down
53 changes: 53 additions & 0 deletions lib/covenants/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,28 @@ rules.MAX_NAME_SIZE = 63;

rules.MAX_RESOURCE_SIZE = 512;

/**
* Consensus name verification flags (used for block validation).
* @enum {Number}
* @default
*/

rules.nameFlags = {
VERIFY_COVENANTS_NONE: 0,
// Activated when hardening soft fork activates.
VERIFY_COVENANTS_HARDENED: 1 << 0,
// Activated when ICANN lockup soft fork activates.
VERIFY_COVENANTS_LOCKUP: 1 << 1
};

/**
* Standard verify flags for covenants.
* @const {NameFlags}
* @default
*/

rules.nameFlags.MANDATORY_VERIFY_COVENANT_FLAGS = 0;

/**
* Maximum covenant size.
* @const {Number}
Expand Down Expand Up @@ -374,6 +396,37 @@ rules.isReserved = function isReserved(nameHash, height, network) {
return reserved.has(nameHash);
};

/**
* Test whether a name is locked up.
* ICANNLOCKUP soft fork.
* @param {Buffer} nameHash
* @param {Number} height
* @param {Network} network
* @returns {Boolean}
*/

rules.isLockedUp = function isLockedUp(nameHash, height, network) {
assert(Buffer.isBuffer(nameHash));
assert((height >>> 0) === height);
assert(network && network.names);

if (network.names.noReserved)
return false;

if (height < network.names.claimPeriod)
return false;

const item = reserved.get(nameHash);

if (!item)
return false;

if (item.root || item.top100 || item.custom)
return true;

return false;
};

/**
* Create a blind bid hash from a value and nonce.
* @param {Amount} value
Expand Down
7 changes: 7 additions & 0 deletions lib/mempool/contractstate.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,13 @@ class ContractState {
return this.toSet(this.reveals, nameHash, items);
}

/**
* Invalidate transactions in the mempool.
* @param {Number} height
* @param {Boolean} hardened
* @returns {BufferSet<Hash>} - list of invalidated tx hashes.
*/

invalidate(height, hardened) {
const nextHeight = height + 1;
const network = this.network;
Expand Down
Loading

0 comments on commit 90cdf84

Please sign in to comment.