diff --git a/lib/covenants/rules.js b/lib/covenants/rules.js index dbb763d9..f7e535bb 100644 --- a/lib/covenants/rules.js +++ b/lib/covenants/rules.js @@ -396,8 +396,10 @@ rules.isReserved = function isReserved(nameHash, height, network) { assert((height >>> 0) === height); assert(network && network.names); - if (network.names.noReserved) + // Lethean: second-level TLD, no ICANN collision protection needed + if (network.names.noReserved) { return false; + } if (height >= network.names.claimPeriod) return false; diff --git a/lib/protocol/genesis-lethean.js b/lib/protocol/genesis-lethean.js new file mode 100644 index 00000000..f7aa61ff --- /dev/null +++ b/lib/protocol/genesis-lethean.js @@ -0,0 +1,41 @@ +/*! + * genesis-lethean.js - ITNS sidechain genesis block + * + * The genesis block contains: + * - No premine (trust is earned, not granted) + * - No airdrop claims (identity via main chain aliases) + * - Timestamp set to Lethean CIC incorporation date + * + * To generate the actual genesis block, run: + * node scripts/gen-genesis.js --network=lethean + */ + +'use strict'; + +const genesis = {}; + +// Lethean CIC incorporation as the genesis timestamp +// This anchors the sidechain to the legal entity +genesis.GENESIS_TIME = 1577836800; // 2020-01-01 00:00:00 UTC (placeholder — use actual CIC date) + +// Genesis reward: 0 ITNS +// No premine. Every ITNS is earned by running infrastructure. +genesis.GENESIS_REWARD = 0; + +// Genesis message — encoded in the coinbase +genesis.GENESIS_MSG = 'Lethean ITNS sidechain — trust is earned, not granted'; + +// Network magic bytes (unique to ITNS sidechain) +genesis.main = { + magic: 0x4c544e53, // "LTNS" in hex (L=4c T=54 N=4e S=53) +}; + +genesis.testnet = { + magic: 0x544e5354, // "TNST" +}; + +genesis.regtest = { + magic: 0x52475354, // "RGST" +}; + +module.exports = genesis; diff --git a/lib/protocol/lethean.js b/lib/protocol/lethean.js new file mode 100644 index 00000000..2cd2238b --- /dev/null +++ b/lib/protocol/lethean.js @@ -0,0 +1,101 @@ +/*! + * lethean.js - ITNS sidechain parameter overrides for Lethean network + * + * Token: ITNS (IntenseCoin) — named after Lethean's original identity + * + * Economics: + * - Tiny block rewards (atomic scale) + * - Round numbers exchangeable 1:1 with LTHN + * - Dust = trust earned from serving the network + * + * Performance Tiers (by accumulated dust): + * Valiant (1M+) — Datacenter/regional peering (named for Lethean's original lead dev) + * Intense (100K+) — Dedicated server operator (named for IntenseCoin) + * Pioneer (10K+) — Home server / VPS operator + * Relay (1K+) — Lightweight relay node + * Seed (1+) — New gateway + */ + +'use strict'; + +const consensus = require('./consensus'); + +/** + * ITNS sidechain overrides + * Apply these to consensus exports to create the Lethean network parameters + */ + +const lethean = { + // Match LTHN's 12 decimal places for dust precision + EXP: 12, + COIN: Math.pow(10, 12), + + // Tiny block reward — forces long-term commitment + // 0.000001 ITNS per block = need ~348 days solo to earn 1 exchangeable ITNS + // A datacenter region (100 nodes) earns 1 ITNS every ~3.5 days + BASE_REWARD: 1000000, // 0.000001 * 10^12 + + // Faster blocks for more trust accrual events + // 30 second blocks = ~2880 blocks/day + // Solo: 0.00288 ITNS/day (exchangeable) + work-based dust (trust) + POW_TARGET_SPACING: 30, + + // Work proofs: dust accrues from actual network service + // DNS queries served, VPN sessions handled, bandwidth relayed + // 1 query = 1 atomic dust unit + // A busy gateway: ~1000 queries/block * 2880 blocks = 2.88M dust/day + // Pioneer in ~4 days, Intense in ~35 days, Valiant in ~1 year + + // No airdrop, no premine — trust is earned + MAX_AIRDROP: 0, + MAX_INITIAL: 0, + + // Max supply determined by halving schedule + // With 0.001 per block, halving every 170000 blocks (~59 days) + // Total supply converges to ~340 ITNS (exchangeable to 340 LTHN) + // Plus unlimited dust (trust) in atomic units + + // Naming costs — registering .lthn subnames + // Free for alias holders (validated against main chain) + MIN_NAME_FEE: 0, + + // Performance tier thresholds (dust units) + TIER_SEED: 1, + TIER_RELAY: 1000, + TIER_PIONEER: 10000, + TIER_INTENSE: 100000, + TIER_VALIANT: 1000000, + + /** + * Get tier name from dust amount + * @param {Number} dust - atomic units of trust + * @returns {String} tier name + */ + getTier(dust) { + if (dust >= lethean.TIER_VALIANT) return 'Valiant'; + if (dust >= lethean.TIER_INTENSE) return 'Intense'; + if (dust >= lethean.TIER_PIONEER) return 'Pioneer'; + if (dust >= lethean.TIER_RELAY) return 'Relay'; + if (dust >= lethean.TIER_SEED) return 'Seed'; + return 'None'; + }, + + /** + * Split balance into exchangeable value and trust dust + * @param {Number} balance - total balance in atomic units + * @returns {Object} { exchangeable, dust, tier } + */ + splitBalance(balance) { + const coin = lethean.COIN; + const exchangeable = Math.floor(balance / coin); + const dust = balance % coin; + return { + exchangeable, // whole ITNS, exchangeable to LTHN + dust, // atomic remainder, trust score + tier: lethean.getTier(dust), + display: `${exchangeable}.${String(dust).padStart(12, '0')} ITNS`, + }; + }, +}; + +module.exports = lethean; diff --git a/lib/protocol/networks-lethean.js b/lib/protocol/networks-lethean.js new file mode 100644 index 00000000..735d2732 --- /dev/null +++ b/lib/protocol/networks-lethean.js @@ -0,0 +1,120 @@ +/*! + * networks-lethean.js - ITNS sidechain network parameters + * + * Lethean fork of Handshake — manages the .lthn TLD + * Token: ITNS (IntenseCoin) + * + * Changes from upstream HSD: + * - Seeds point to Lethean infrastructure + * - Ports use Lethean range (12037-12040) + * - Block reward reduced to atomic scale (0.000001 ITNS) + * - Block time 30 seconds (faster trust accrual) + * - No airdrop (identity via main chain aliases) + * - EXP=12 (matches LTHN decimal places) + */ + +'use strict'; + +/** + * Lethean ITNS sidechain network overrides. + * Apply these on top of the base HSD network config. + */ + +const lethean = {}; + +// === Mainnet === + +lethean.main = { + type: 'main', + + seeds: [ + 'seed.lthn.io', // Primary (ClouDNS anycast) + 'ns5.lthn.io', // snider-linux (DE) + 'ns6.lthn.io', // darbs (AU) + ], + + // Lethean HSD ports (avoid collision with main chain 36941-36943) + port: 12037, + brontidePort: 44807, + nsPort: 12038, + rsPort: 12039, + walletPort: 12040, + + // Block time: 30 seconds (vs HSD's 10 minutes) + // More blocks = more trust accrual events + pow: { + targetSpacing: 30, + }, + + // Names — .lthn TLD management + names: { + // No reserved names — this is a second-level TLD, ICANN collision doesn't apply + noReserved: true, + // Registration is free for main-chain alias holders + // Validated via alias-DNS bridge + auctionStart: 0, + rolloutInterval: 1, + // Renewal every ~1 year (1,051,200 blocks at 30s) + renewalWindow: 1051200, + renewalPeriod: 525600, + renewalMaturity: 2880, // ~1 day + }, +}; + +// === Testnet === + +lethean.testnet = { + type: 'testnet', + + seeds: [ + 'seed-testnet.lthn.io', + ], + + port: 13037, + brontidePort: 45807, + nsPort: 13038, + rsPort: 13039, + walletPort: 13040, + + pow: { + targetSpacing: 30, + }, + + names: { + noReserved: true, + auctionStart: 0, + rolloutInterval: 1, + renewalWindow: 10080, + renewalPeriod: 5040, + renewalMaturity: 288, + }, +}; + +// === Regtest (local development) === + +lethean.regtest = { + type: 'regtest', + + seeds: [], + + port: 14037, + brontidePort: 46807, + nsPort: 14038, + rsPort: 14039, + walletPort: 14040, + + pow: { + targetSpacing: 1, // 1 second blocks for testing + }, + + names: { + noReserved: true, + auctionStart: 0, + rolloutInterval: 1, + renewalWindow: 100, + renewalPeriod: 50, + renewalMaturity: 2, + }, +}; + +module.exports = lethean; diff --git a/lib/protocol/networks.js b/lib/protocol/networks.js index cd209ab0..02dda3c2 100644 --- a/lib/protocol/networks.js +++ b/lib/protocol/networks.js @@ -872,7 +872,7 @@ regtest.names = { transferLockup: 10, auctionMaturity: 5 + 10 + 50, noRollout: false, - noReserved: false + noReserved: true }; regtest.block = { diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index af9e5c60..8cb7468d 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -1734,8 +1734,10 @@ class Wallet extends EventEmitter { const {icannlockup} = this.wdb.options; // TODO: Handle expired behavior. - if (rules.isReserved(nameHash, height, network)) + // Lethean: skip reserved check for second-level TLD names + if (rules.isReserved(nameHash, height, network)) { throw new Error(`Name is reserved: ${name}.`); + } if (icannlockup && rules.isLockedUp(nameHash, height, network)) throw new Error(`Name is locked up: ${name}.`);